【发布时间】:2017-03-31 02:36:44
【问题描述】:
我正在对 minizinc 中的约束满足程序进行建模,其中解决方案是在 3D 网格上分配点。限制之一是只有一个点可以占据任何给定位置,因此这些点必须在至少一个坐标上成对不同。
我的点变量被建模为 N X 3 坐标数组:
array[1..N,1..3] of var -N..N: X;
而差异约束是
constraint forall(i in 1..N-1)(forall(j in i+1..N)(not X_eq(i,j))); %extremely slow
predicate X_eq(int: a, int: b)=
(X[a,1]=X[b,1]/\X[a,2]=X[b,2]/\X[a,3]=X[b,3]);
但是当我像这样制定约束时,问题的解决时间会飞涨。我还有很多其他的约束要添加,而且它已经很慢了,只能找到不同的点。
我尝试将点建模为
array[1..N] var set of -N..N
这样我就可以使用内置函数了
all_different
然后我看到了如何强制集合具有基数 3,而且使用通用大小的集合来建模三元组似乎不太自然。
我的问题是:什么是对坐标集和完全不同的约束进行建模的易处理且“正确”的方法?
我正在使用 minizinc IDE 包中的 gecode 求解器。模型如下所示。求解时间为 24 分钟。
array[1..N] of 0..1: seq=[1,1,0,0,0,0,0,1,1,0,0,0,1,0,0,0,1,0];
int: N=18;
int: H=6;
array[1..N,1..3] of var -N..N: X;
array [1..H,1..3] of 0..N:c;
%H are in core
constraint forall(i in 1..N)( if (seq[i]=1) then exists(j in 1..H)([i,1]=c[j,1] /\ X[i,2]=c[j,2] /\ X[i,3]=c[j,3] ) else true endif);
%All points different
constraint forall(i in 1..N-1)(forall(j in i+1..N)(not X_eq(i,j))); %extremely slow
predicate X_eq(int: a, int: b)=
(X[a,1]=X[b,1]/\X[a,2]=X[b,2]/\X[a,3]=X[b,3]);
solve satisfy;
output[show(X[i,j]) ++ " "|i in 1..N,j in 1..3]++["\n"];
c=[|0,0,0|
0,0,1|
0,0,2|
0,1,0|
0,1,1|
0,1,2|];
【问题讨论】:
标签: constraint-programming minizinc