Graph 使用Minizin检查是否存在连接图形中两个顶点的路径
我试图做一个约束来检查图中是否有从顶点a到顶点B的路径。我已经做了一个返回路径本身的约束,但是我还需要一个返回bool的函数来指示路径是否存在 我已经在这上面花了很多时间,但是我的尝试都没有成功 有人知道我能做什么吗 下面是我创建的返回路径本身的函数,其中graph是一个邻接矩阵,source和target是顶点A和B: 谢谢 以下是我的工作:Graph 使用Minizin检查是否存在连接图形中两个顶点的路径,graph,minizinc,Graph,Minizinc,我试图做一个约束来检查图中是否有从顶点a到顶点B的路径。我已经做了一个返回路径本身的约束,但是我还需要一个返回bool的函数来指示路径是否存在 我已经在这上面花了很多时间,但是我的尝试都没有成功 有人知道我能做什么吗 下面是我创建的返回路径本身的函数,其中graph是一个邻接矩阵,source和target是顶点A和B: 谢谢 以下是我的工作: include "globals.mzn"; int: N; array[1..N, 1..N] of 0..1: adj_mat; array[1..
include "globals.mzn";
int: N;
array[1..N, 1..N] of 0..1: adj_mat;
array[1..N] of var 0..N: path;
solve satisfy;
constraint exists_path(1,3);
N=4;
adj_mat = [|
0, 1, 0, 0,|
0, 0, 1, 0,|
0, 0, 0, 1,|
0, 0, 0, 0 |];
constraint alldifferent_except_0(path);
predicate exists_path_length(int: s, int: t, int: len) =
path[1]=s /\ path[len]=t /\ forall(i in len+1..N)(path[i]=0) /\
forall(i in 1..len-1)( adj_mat[path[i],path[i+1]]=1);
predicate exists_path(int: s, int: t) = exists(len in 2..N)(exists_path_length(s,t,len));
注意:(1)限制路径的域是很重要的(在我的代码中,我将其设置为0..N),否则Minizing会因为大量的决策选择而永远运行。
(2) 理想情况下,除了0之外的所有不同的全局约束都应该放在存在路径长度内,但这样做是为了避免具体化问题(有关更多信息,请查看Minizing上的Coursera课程)
predicate exists_path(array[int,int] of int: graph, int: source, int: target)::promise_total =
let {
set of int: V = index_set_1of2(graph);
int: order = card(V);
set of int: indexes = 1..order;
array[indexes] of var (V union {-1}): path_array;
constraint assert(index_set_1of2(graph) = index_set_2of2(graph), "The adjacency matrix is not square", true);
constraint assert({source, target} subset V, "Source and target must be vertexes", true);
}
in
exists(path_nodes_count in indexes) (
path_array[1] == source /\
path_array[path_nodes_count] == target /\
forall(i in 2..path_nodes_count) ( graph[ path_array[i-1], path_array[i] ] != 0 ) /\
forall(i,j in indexes, where i<j /\ j<=path_nodes_count) ( path_array[i] != path_array[j] )
);
int: N;
array[1..N, 1..N] of 0..1: adj_mat;
array[1..N] of var int: path;
% These should work:
constraint exists_path(adj_mat, 1, 3) = true;
constraint exists_path(adj_mat, 4, 1) = false;
% These should raise =====UNSATISFIABLE=====
constraint exists_path(adj_mat, 1, 3) = false;
constraint exists_path(adj_mat, 4, 1) = true;
solve satisfy;
% If you want to check the working constraint:
% constraint path = path(adj_mat, 1, 3);
% constraint path = path(adj_mat, 4, 1); <- This finds out that the model is unsatisfiable
% output[show(path)];
/* 1 -> 2 -> 3 -> 4 */
N=4;
adj_mat = [|
0, 1, 0, 0,|
0, 0, 1, 0,|
0, 0, 0, 1,|
0, 0, 0, 0 |];
%---------------------------------*/
/* Disconnected graph
1---2---6 4
\ / |
3 5 */
N=6;
adj_mat = [|
0, 1, 1, 0, 0, 0, |
1, 0, 1, 0, 0, 1, |
1, 1, 0, 0, 0, 0, |
0, 0, 0, 0, 1, 0, |
0, 0, 0, 1, 0, 0, |
0, 1, 0, 0, 0, 0 |];
%---------------------------------*/
include "globals.mzn";
int: N;
array[1..N, 1..N] of 0..1: adj_mat;
array[1..N] of var 0..N: path;
solve satisfy;
constraint exists_path(1,3);
N=4;
adj_mat = [|
0, 1, 0, 0,|
0, 0, 1, 0,|
0, 0, 0, 1,|
0, 0, 0, 0 |];
constraint alldifferent_except_0(path);
predicate exists_path_length(int: s, int: t, int: len) =
path[1]=s /\ path[len]=t /\ forall(i in len+1..N)(path[i]=0) /\
forall(i in 1..len-1)( adj_mat[path[i],path[i+1]]=1);
predicate exists_path(int: s, int: t) = exists(len in 2..N)(exists_path_length(s,t,len));