首页 > 解决方案 > Minizinc“无法确定浮动的下限”

问题描述

我有一个 minizinc 模型,其中有一个距离矩阵:

array[1..n, 1..n] of var float: dist;

这将输出错误Error: Gecode: Float::linear: Number out of limits。例如,如果我尝试最小化矩阵solve minimize sum(i,j in 1..n)(dist[i,j]);(实际上代码更复杂)。下限对我来说很清楚。距离矩阵中的任何值都不能小于零。然而,用下限制定约束将不起作用:

constraint forall(i,j in 1..n)(dist[i,j] >= 0.0);

使域更小将起作用。但是我不能提前说域的上限是多少(对于下面的代码,我只取了一个很大的数字,在某些情况下可能太小了):

array[1..n, 1..n] of var 0.0..1000000.0: dist;

是否有可能只定义下限?

我使用 Minizinc 2.2.1 和地理编码 6.0.1。

标签: floating-pointminizinc

解决方案


您得到了Error: Gecode: Float::linear: Number out of limits因为 Gecode(和任何其他 CP 求解器)将需要每个变量的上限和下限。在您的目标中,您正在对每个范围从0.0..1000000.0. 在内部,MiniZinc 为这个 sum 表达式创建了一个变量,这个变量的域超出了 Gecode 的内部界限。

所以我看到了解决这个问题的两种解决方案:

1)自己创建目标变量并为其设置上限。以下模型适用于 MiniZinc 2.2.1 和 Gecode 6.0.1:

int: n = 3;
array[1..n, 1..n] of var 0.0..100000.0: dist; 
% a new variable for the objective term with a lower and upper bound
var 0.0..1000000.0: total_distance;  

constraint forall(i,j in 1..n)(dist[i,j] >= 0.0);

constraint    % set the objective term
   total_distance = sum(i,j in 1..n)(dist[i,j]);

solve minimize total_distance;

2)不要使用CP求解器,而是使用MIP(混合整数规划)求解器。他们可以处理具有无限边界的变量。MiniZinc 带有 MIP 求解器 CBC,它可以毫无问题地求解以下 MiniZinc 模型:

int: n = 3;
array[1..n, 1..n] of var float: dist;

constraint forall(i,j in 1..n)(dist[i,j] >= 0.0);

solve minimize sum(i,j in 1..n)(dist[i,j]);

推荐阅读