MiniZinc: type error: expected `array[int] of int', actual `array[int] of var opt int
MiniZinc: type error: expected `array[int] of int', actual `array[int] of var opt int
我正在尝试编写一个谓词来执行与 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
编辑
根据 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
这种回答你的问题:
您遇到的问题是您的数组大小取决于 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]
)
我正在尝试编写一个谓词来执行与 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
编辑
根据 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
这种回答你的问题:
您遇到的问题是您的数组大小取决于 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]
)