检查 MiniZinc 数组中的项目
Checking for items in a MiniZinc array
我想在 MiniZinc 中用相同的项目创建两个数组,不一定要按相同的顺序。在这里,A0
中的每个项目也应该在 A1
:
中
array[1..3] of var int:A0;
array[1..3] of var int:A1;
constraint forall(A2 in A0)(
(A2 in A1) /\ A2 < 5
);
但是这里好像有类型错误:
MiniZinc: type error: type error in operator application for `'in''. No matching operator found with left-hand side type `var int' and right-hand side type `array[int] of var int'
如何检查一个数组是否包含另一个数组中的相同项目?
编辑:文件builtins.mzn
中有一个array2set
,但在https://www.minizinc.org/doc-2.4.2/中没有记录。
以下模型适用于大多数 FlatZinc 求解器,例如 Gecode、Google-OR-tools、Choco、PicatSAT 和 JaCoP,但不适用于 Chuffed(见下文)。请注意 "nosets.mzn" 的包含,以便不支持设置变量的求解器可以 运行 模型。另外,我添加了一个较小的 A0
和 A1
域以便于测试。
include "nosets.mzn"; % Support for set variables for all solvers
array[1..3] of var 0..10: A0;
array[1..3] of var 0..10: A1;
constraint
forall(A2 in A0)(
A2 in array2set(A1) /\ A2 < 5
)
/\
forall(A2 in A1)(
A2 in array2set(A0) /\ A2 < 5
);
solve satisfy;
output [ "A0: \(A0) A1: \(A1)\n" ];
但是,有些求解器不喜欢这样:
- Chuffed:投掷 "Error: Registry: Constraint bool_lin_eq not found in line no. 101"
甚至稍后注意:如果域是 var int
(而不是我的 var 0..10
),那么 MiniZinc 会出现一个奇怪的(而且很长)错误:
...
in array comprehension expression
comprehension iterates over an infinite set
所以array2set
似乎要求变量域必须有界。
这是第一个回答
这是一种似乎有效的方法,即使用 exists
并检查元素是否相等:
constraint forall(A2 in A0)(
exists(i in 1..3) ( A2 = A1[i] /\ A2 < 5)
);
注意:该约束只保证A0中的元素在A1中。因此,A1 中可能存在不在 A0 中的元素。例如
A0: [1,1,4]
A1: [1,4,3]
我猜您还想要相反的情况,即 A1 中的所有元素也都在 A0 中:
constraint forall(A2 in A1) (
exists(i in 1..3) ( A2 = A0[i] /\ A2 < 5)
);
注意:以下 不 有效,但如果有就更好了。两者都会产生错误 MiniZinc: internal error: var set comprehensions not supported yet
.
% idea 1
constraint forall(A2 in A0)(
A2 in {A1[i] | i in 1..3} /\ A2 < 5
);
% idea 2
constraint forall(A2 in A0) (
A2 in {a | a in A1} /\ A2 < 5
);
我想在 MiniZinc 中用相同的项目创建两个数组,不一定要按相同的顺序。在这里,A0
中的每个项目也应该在 A1
:
array[1..3] of var int:A0;
array[1..3] of var int:A1;
constraint forall(A2 in A0)(
(A2 in A1) /\ A2 < 5
);
但是这里好像有类型错误:
MiniZinc: type error: type error in operator application for `'in''. No matching operator found with left-hand side type `var int' and right-hand side type `array[int] of var int'
如何检查一个数组是否包含另一个数组中的相同项目?
编辑:文件builtins.mzn
中有一个array2set
,但在https://www.minizinc.org/doc-2.4.2/中没有记录。
以下模型适用于大多数 FlatZinc 求解器,例如 Gecode、Google-OR-tools、Choco、PicatSAT 和 JaCoP,但不适用于 Chuffed(见下文)。请注意 "nosets.mzn" 的包含,以便不支持设置变量的求解器可以 运行 模型。另外,我添加了一个较小的 A0
和 A1
域以便于测试。
include "nosets.mzn"; % Support for set variables for all solvers
array[1..3] of var 0..10: A0;
array[1..3] of var 0..10: A1;
constraint
forall(A2 in A0)(
A2 in array2set(A1) /\ A2 < 5
)
/\
forall(A2 in A1)(
A2 in array2set(A0) /\ A2 < 5
);
solve satisfy;
output [ "A0: \(A0) A1: \(A1)\n" ];
但是,有些求解器不喜欢这样:
- Chuffed:投掷 "Error: Registry: Constraint bool_lin_eq not found in line no. 101"
甚至稍后注意:如果域是 var int
(而不是我的 var 0..10
),那么 MiniZinc 会出现一个奇怪的(而且很长)错误:
...
in array comprehension expression
comprehension iterates over an infinite set
所以array2set
似乎要求变量域必须有界。
这是第一个回答
这是一种似乎有效的方法,即使用 exists
并检查元素是否相等:
constraint forall(A2 in A0)(
exists(i in 1..3) ( A2 = A1[i] /\ A2 < 5)
);
注意:该约束只保证A0中的元素在A1中。因此,A1 中可能存在不在 A0 中的元素。例如
A0: [1,1,4]
A1: [1,4,3]
我猜您还想要相反的情况,即 A1 中的所有元素也都在 A0 中:
constraint forall(A2 in A1) (
exists(i in 1..3) ( A2 = A0[i] /\ A2 < 5)
);
注意:以下 不 有效,但如果有就更好了。两者都会产生错误 MiniZinc: internal error: var set comprehensions not supported yet
.
% idea 1
constraint forall(A2 in A0)(
A2 in {A1[i] | i in 1..3} /\ A2 < 5
);
% idea 2
constraint forall(A2 in A0) (
A2 in {a | a in A1} /\ A2 < 5
);