MiniZinc:类型错误:int'的预期`array [int],var opt int的实际`array [int]

时间:2016-02-17 16:15:57

标签: minizinc

我正在尝试编写一个与circuit执行相同操作的谓词,但忽略数组中的零,并且我不断收到以下错误:

MiniZinc: type error: initialisation value for 'x_without_0' has invalid type-inst: expected 'array[int] of int', actual 'array[int] of var opt int'

代码中的

% [0,5,2,0,7,0,3,0] -> true
% [0,5,2,0,4,0,3,0] -> false (no circuit)
% [0,5,2,0,3,0,8,7] -> false (two circuits)
predicate circuit_ignoring_0(array[int] of var int: x) =
  let { 
        array[int] of int: x_without_0 = [x[i] | i in 1..length(x) where x[i] != 0],
        int: lbx = min(x_without_0),
        int: ubx = max(x_without_0),
        int: len = length(x_without_0),
        array[1..len] of var lbx..ubx: order
  } in
  alldifferent(x_without_0) /\
  alldifferent(order) /\

  order[1] = x_without_0[1] /\ 
  forall(i in 2..len) (
     order[i] = x_without_0[order[i-1]]
  )
  /\  % last value is the minimum (symmetry breaking)
  order[ubx] = lbx
;

我正在使用MiniZinc v2.0.11

修改

Per Kobbe建议使用可变长度数组是一个问题,我使用"the usual workaround"保持order数组与原始数组x的大小相同,并使用参数nnonzeros来跟踪我关心的数组部分:

set of int: S = index_set(x),
int: u = max(S),
var int: nnonzeros = among(x, S),
array[S] of var 0..u: order

1 个答案:

答案 0 :(得分:1)

这样可以回答你的问题:

您遇到的问题是您的数组大小取决于var。这意味着MiniZinc无法真正知道应该创建的数组大小并使用opt类型。如果您不知道如何处理它,我建议您远离opt类型。

通常,解决方案是在一些解决方法中,您的数组不依赖于var的大小。我的解决方案通常是填充数组,即[2,0,5,0,8] -> [2,2,5,5,8],如果应用程序允许,或

var int : a;
[i * bool2int(i == a) in 1..5]

如果你的回答中的零可以(我想在这种情况下不是这样)。

此外,alldifferent_except_0可能对你有用,或者至少你可以看看alldifferent_except_0如何在答案中用零解决问题。

predicate alldifferent_except_0(array [int] of var int: vs) =
forall ( i, j in index_set(vs) where i < j ) ( 
    vs[i]!=0 /\ vs[j]!=0 -> vs[i]!=vs[j] 
)

来自http://www.asp.net/mvc/overview/older-versions-1/security/authenticating-users-with-windows-authentication-cs