Minizinc 奇怪的行为

Minizinc strange behaviour

我最近开始研究 minizinc,但我的程序中出现了这种奇怪的行为。

.dzn

n = 5;
c = 2;

.mzn

include "globals.mzn";

int: n;
int: c;

set of int: num_deliveries = 1..n-1;
int: headquarter = 1;
set of int: num_places = 1..n;
set of int: deliveries = 2..n;
set of int: couriers = 1..c;
set of int: num_max_deliveries = 1..n+2;
set of int: schedule_domain = 0..n;
int: first_place_idx = 1;
int: last_place_idx = n+2;

array[couriers,num_max_deliveries] of var schedule_domain: schedule;
array[1..2*n] of int: total = [schedule[i,j]|i,j in num_max_deliveries where i<=2 /\ j != first_place_idx /\ j!= last_place_idx];
output ["len_without_variable = \(length([ k | k in total where k != 0]))"];
var int: len_cleaned = length([ k | k in total where k != 0]);

output ["len_with_variable = \(len_cleaned)\n"];

特别是,从这些代码行我得到了不同的结果,即使它们是相等的。

output ["len_without_variable = \(length([ k | k in total where k != 0]))"];
var int: len_cleaned = length([ k | k in total where k != 0]);
output ["len_with_variable = \(len_cleaned)\n"];

为什么会这样?

这是模型的一个输出(添加了 total):

len_without_variable = 2
len_with_variable = 10
total: [3, 3, 0, 0, 0, 0, 0, 0, 0, 0]

老实说,我不确定total中非零元素个数的两次计算是否相同。也许这是 length 如何对决策变量(使用 where 条件)进行运算的错误,它应该是 2(在本例中)。在解决这个问题之前,您应该避免像这样使用 length

len_without_variable 的输出(在输出部分中定义的输出)对解的实际值和已知值进行运算。所以这可能与在 constraint/variable 定义中使用 length 不完全一样。

要计算非零值的数量,您可以使用 sum 代替:

var 0..n num_non_zeros = sum([ 1 | k in total where k != 0]);

但是,构造 ... where k != 0 会创建临时变量,这会使模型比必要的更大,因此最好使用以下内容:

var 0..n num_non_zeros = sum([ total[i] != 0 | i in 1..n]);