Minizinc - 检查元素匹配的约束

问题描述

如果我有一个二维决策变量数组和一个一维集合数组,我如何添加约束来检查决策变量中的值是否应该与一维数组匹配?

例如

array[1..3,1..2] of var 1..10: x;
array[1..3] of set of 1..10: y;

And y is = [{2,6,7,8},{1,2,3},8,1,5,1},];

我想添加约束以确保 x 仅保留 y 中包含的值。 例如,规则是 x0,x1 的值应该是 y {2,8} 的第一组值之一。 x2,x3 的值应该在 y {1,3} 的第二组值中,依此类推。

谢谢

解决方法

如果 y 被定义为参数(即没有用 var 定义),那么你可以将 y 的值提取为一个集合 (vals ) 像这样:

array[1..3] of set of 1..10: y = [{2,6,7,8},{1,2,3},8,1,5,1},];

% convert the values 
set of int: vals = { val | row in y,val in row  };
        
array[1..3,1..2] of var vals : x;

output [
  "vals:\(vals)\nx:\(x)\n"
];

更新:这是对问题更新版本的建议。这里我们将 x 中的 i'th 变量限制为仅 i'th 中的 y 行的值,即 i'th 中的 y 集。和以前一样,我假设 y 中的值是普通整数(不是决策变量):

array[1..3] of set of 1..10: y = [{2,];

array[1..3,1..2] of var int : x;

% Ensure that the i'th row in x only contains values 
% that are in the i'th row/set of y
constraint
  forall(i in 1..3) (
     forall(j in 1..2) (
        x[i,j] in y[i]
     )
  )
;

output [
"x:\(x)\n",];