为什么这个两行更改会破坏这个 minizinc set-cover 程序?
Why does this two-line change break this minizinc set-cover program?
下面的程序(改编自 http://www.hakank.org/minizinc/set_covering4b.mzn )是集合覆盖问题的解决方案(问题末尾提供的示例数据)。这运行正确。
int: num_alternatives;
int: num_objects;
par set of int: ALTERNATIVES = 1..num_alternatives;
% costs for the alternatives
array[ALTERNATIVES] of int: costs;
% objects covered by the alternatives
array[ALTERNATIVES] of var set of 1..num_objects: a;
% decision variable: which alternative to choose
array[ALTERNATIVES] of var bool: x;
% the objective to minimize
var int: z = sum(i in 1..num_alternatives) (x[i]*costs[i]);
solve minimize z;
constraint
forall(j in 1..num_objects) (
sum(i in 1..num_alternatives) (x[i] * bool2int(j in a[i])) >= 1
)
;
output
[
"x: " ++ show(x) ++ "\n" ++
"a: " ++ show(a) ++ "\n"
];
但是,如果我替换上面的 a
定义:
array[ALTERNATIVES] of var set of 1..num_objects: a;
这两行在我看来是等价的:
var set of int: OBJECTS = 1..num_objects;
array[ALTERNATIVES] of OBJECTS: a;
...突然出现以下错误:
MiniZinc: type error: type-inst must be par set but is `var set of
int'
这让我很困惑。我什至改变了什么?在每种情况下,a
都是一个整数集数组。类型实例在每种情况下都是 var set of int
,但是第二个会抛出错误而第一个不会因为某种原因抛出错误?
这里有一些数据可以放在 .mzn 代码文件的底部,以生成一个独立的、可运行的示例:
% data
num_alternatives = 10;
costs = [ 19, 16, 18, 13, 15, 19, 15, 17, 16, 15];
num_objects = 8;
% the alternatives and the objects they contain
a = [
{1,6},
{2,6,8},
{1,4,7},
{2,3,5},
{2,5},
{2,3},
{2,3,4},
{4,5,8},
{3,6,8},
{1,6,7}
];
你可以这样写:
int: num_alternatives;
int: num_objects;
set of int: ALTERNATIVES = 1..num_alternatives;
set of int: OBJECTS = 1..num_objects;
% costs for the alternatives
array[ALTERNATIVES] of int: costs;
% objects covered by the alternatives
array[ALTERNATIVES] of var set of OBJECTS: a;
% decision variable: which alternative to choose
array[ALTERNATIVES] of var bool: x;
% the objective to minimize
var int: z = sum(i in ALTERNATIVES) (x[i]*costs[i]);
solve minimize z;
constraint
forall(j in OBJECTS) (
sum(i in ALTERNATIVES) (x[i] * (j in a[i])) >= 1
)
;
output
[
"x: " ++ show(x) ++ "\n" ++
"a: " ++ show(a) ++ "\n"
];
在你的实验中
var set of int: OBJECTS = 1..num_objects;
array[ALTERNATIVES] of OBJECTS: a;
a
是 array
范围内的整数 1..num_objects
。
但是您想要 array
个该范围内的整数集。
下面的程序(改编自 http://www.hakank.org/minizinc/set_covering4b.mzn )是集合覆盖问题的解决方案(问题末尾提供的示例数据)。这运行正确。
int: num_alternatives;
int: num_objects;
par set of int: ALTERNATIVES = 1..num_alternatives;
% costs for the alternatives
array[ALTERNATIVES] of int: costs;
% objects covered by the alternatives
array[ALTERNATIVES] of var set of 1..num_objects: a;
% decision variable: which alternative to choose
array[ALTERNATIVES] of var bool: x;
% the objective to minimize
var int: z = sum(i in 1..num_alternatives) (x[i]*costs[i]);
solve minimize z;
constraint
forall(j in 1..num_objects) (
sum(i in 1..num_alternatives) (x[i] * bool2int(j in a[i])) >= 1
)
;
output
[
"x: " ++ show(x) ++ "\n" ++
"a: " ++ show(a) ++ "\n"
];
但是,如果我替换上面的 a
定义:
array[ALTERNATIVES] of var set of 1..num_objects: a;
这两行在我看来是等价的:
var set of int: OBJECTS = 1..num_objects;
array[ALTERNATIVES] of OBJECTS: a;
...突然出现以下错误:
MiniZinc: type error: type-inst must be par set but is `var set of int'
这让我很困惑。我什至改变了什么?在每种情况下,a
都是一个整数集数组。类型实例在每种情况下都是 var set of int
,但是第二个会抛出错误而第一个不会因为某种原因抛出错误?
这里有一些数据可以放在 .mzn 代码文件的底部,以生成一个独立的、可运行的示例:
% data
num_alternatives = 10;
costs = [ 19, 16, 18, 13, 15, 19, 15, 17, 16, 15];
num_objects = 8;
% the alternatives and the objects they contain
a = [
{1,6},
{2,6,8},
{1,4,7},
{2,3,5},
{2,5},
{2,3},
{2,3,4},
{4,5,8},
{3,6,8},
{1,6,7}
];
你可以这样写:
int: num_alternatives;
int: num_objects;
set of int: ALTERNATIVES = 1..num_alternatives;
set of int: OBJECTS = 1..num_objects;
% costs for the alternatives
array[ALTERNATIVES] of int: costs;
% objects covered by the alternatives
array[ALTERNATIVES] of var set of OBJECTS: a;
% decision variable: which alternative to choose
array[ALTERNATIVES] of var bool: x;
% the objective to minimize
var int: z = sum(i in ALTERNATIVES) (x[i]*costs[i]);
solve minimize z;
constraint
forall(j in OBJECTS) (
sum(i in ALTERNATIVES) (x[i] * (j in a[i])) >= 1
)
;
output
[
"x: " ++ show(x) ++ "\n" ++
"a: " ++ show(a) ++ "\n"
];
在你的实验中
var set of int: OBJECTS = 1..num_objects;
array[ALTERNATIVES] of OBJECTS: a;
a
是 array
范围内的整数 1..num_objects
。
但是您想要 array
个该范围内的整数集。