为什么我的数组是 var int 类型而不是 var set of int?

问题描述

我有以下问题:我想调用全局约束at_most,但出现与签名相关的错误

constraint forall(i in 0..w-1)(at_most(l_max,[board[i,j] | j in 0..l_max-1],0..n));

第二个参数不匹配,因为结果是 var int 而不是 var set of int 但我之前已经以这种方式定义了 board:

set of int: VALUES = 0..n;
array[0..w-1,0..l_max-1] of var VALUES: board;

解决方法

就像一般信息:at_most 是已弃用的约束列表之一:https://www.minizinc.org/doc-2.5.5/en/lib-globals.html#deprecated-constraints。 相反,您应该使用 count 约束。这些约束更灵活,求解器可以更好地支持。

在这种情况下,似乎对 at_most 的作用存在误解。最多只限制单个值出现的次数。你是。然而,给它一套完整的值。

如果您要计算所有不同的值,则可以改用 global_cardinality_low_up。 (您可能还想查看封闭版本)。 我认为您打算编写以下约束。

constraint forall(i in 0..w-1)(
  global_cardinality_low_up([board[i,j] | j in 0..l_max-1],0..n,[0 | i in 0..n],[l_max | i in 0..n])
);

此约束确保对于推导式,0..n 中的值仅出现 l_max 次。

请注意,如果您使用推导式选择整行,则最好使用切片表示法:board[i,..]