【发布时间】:2019-07-12 19:08:22
【问题描述】:
我正在尝试使用 minizinc 为我构建一个真/假矩阵,其中每一列都满足某些条件(至少 3 个真值,并且必须有奇数个真值)。到目前为止,一切都很好 - 但是当我添加额外的约束以使每一列都不同(与所有其他列)时,我没有得到一致的结果:
使用下面注释掉的版本,在 Ubuntu-on-WSL (Windows) 上使用 minizinc 2.1.7,它几乎可以立即找到解决方案。但是,Mac 或 ArchLinux 安装上的任何版本的 minizinc(2.1.7、2.2.0、2.3.1)都不能满足这些限制(至少在几分钟内)。这一切都与 Gecode 相关。
Chuffed 可以很好地满足约束条件,同样是注释掉的代码版本,而不是下面的代码。
但是,如果我解决以最小化某些值(参见第二个 sn-p),那么 Chuffed 将不再找到任何解决方案(同样,至少在几分钟内不会)。我原以为它至少会找到与“满足”相同的解决方案。
我做错了什么?是否有更好的方法来编写更一致的“不同列”约束?我不认为这对于约束求解器来说是一个特别困难的问题,所以我怀疑这确实是我如何编写约束的问题。
我想将 H 矩阵保留为真/假的 2d 矩阵,因为具有该形状还有其他约束。
int: k = 7;
int: n = 47;
array[1..k,1..n] of var bool: H;
array[1..k] of var bool : flip_bits;
predicate all_different_int(array[int] of var int: x) =
forall(i,j in index_set(x) where i < j) ( x[i] != x[j] );
constraint forall(j in 1..n)(
sum(i in 1..k)(
if H[i,j] then 1 else 0 endif
) mod 2 > 0
);
constraint forall(j in 1..n)(
sum(i in 1..k)(
if H[i,j] then 1 else 0 endif
) >= 3
);
%array[1..n] of var int: H_t;
%constraint forall(j in 1..n)(
% H_t[j] = sum(i in 1..k)(
% if H[i,j] then pow(2,i) else 0 endif
% )
%);
%constraint all_different_int(H_t);
constraint all_different_int(
[sum(i in 1..k)(if H[i,j] then pow(2,i) else 0 endif) | j in 1..n]
);
solve satisfy;
var int: z2 = sum(i in 1..k, j in 1..n)(if H[i,j] then 1 else 0 endif);
var int: z1 = max(i in 1..k)(sum (j in 1..n)(if H[i,j] then 1 else 0 endif));
solve minimize z1*1000+z2;
【问题讨论】:
-
要强制使用奇数个布尔值,您可能需要使用
xorall()。这应该比mod 2高效得多。 -
@AxelKemper 谢谢 - 我在后来的约束中使用了 xorall() 但没有想到在那里使用它。这确实有助于用 gecode 再次解决它。不过,仍然对编写列唯一性的其他/更好的方法感到好奇。
标签: minizinc