来自var float

时间:2017-12-21 22:58:27

标签: minizinc

我正处于学习MiniZinc的初级阶段,我想完成MiniZinc教程中提供的laplace.mzn示例,而不需要查看代码。我在下面的代码块1中显示的原始尝试提供了正确的答案。我想尝试通过在show_float()函数中将硬编码值设为6来概括输出语句,该函数指定输出中的每个浮点数应右对齐6位数,动态(即找到t中的最大值和将输出宽度基于此。

我的第一次尝试是在代码块2中添加语句,但是我收到以下错误: MiniZinc:评估错误:
laplace.mzn:28:
在'm'的变量声明中   在电话'最大'中   /home/str/MiniZinc/share/minizinc/std/builtins.mzn:278:
  在表达中   /home/str/MiniZinc/share/minizinc/std/builtins.mzn:281:
  在电话'max_t'中   /home/str/MiniZinc/share/minizinc/std/builtins.mzn:2020:
  在if-then-else表达中   /home/str/MiniZinc/share/minizinc/std/builtins.mzn:2023:
  在表达中   /home/str/MiniZinc/share/minizinc/std/builtins.mzn:2025:
  在调用'array_float_maximum'中   /home/str/MiniZinc/share/minizinc/linear/redefinitions-2.0.mzn:16:
  在if-then-else表达中   /home/str/MiniZinc/share/minizinc/linear/redefinitions-2.0.mzn:19:
  在调用'array_float_minimum_I'中   /home/str/MiniZinc/share/minizinc/linear/redefinitions.mzn:108:
  在表达中   /home/str/MiniZinc/share/minizinc/linear/redefinitions.mzn:110:
    i = 1   在电话'ub'中   无法确定界限

然后,虽然我对它的外观并不满意,但我尝试了Code Block 3,导致以下错误:
MiniZinc:评估错误:
  /home/str/MiniZinc/share/minizinc/linear/redefs_lin_reifs.mzn:319:
  在if-then-else表达中   /home/str/MiniZinc/share/minizinc/linear/redefs_lin_reifs.mzn:321:
  在电话'ub'中   无法确定界限

有关如何在满足约束问题后从't'获取最大值的任何建议?提前谢谢。

代码块1:

int: w = 5;
int: h = 5;

array[1..h,1..w] of var float: t;
float: top = 100.0;
float: bottom = 0.0;
float: left = 0.0;
float: right = 0.0;
float: corners = 0.0;

% Top row all the same except corners
constraint forall(c in 2..w-1)(t[1,c] = top);

% Bottom row all the same except corners
constraint forall(c in 2..w-1)(t[h,c] = bottom);

% First column all the same except corners
constraint forall(r in 2..h-1)(t[r,1] = left);

% Last column all the same except corners
constraint forall(r in 2..h-1)(t[r,w] = right);

% The four corners must be the same value
constraint t[1,1] = corners /\ t[1,1] = t[1,w] /\ t[1,w] = t[h,w] /\ t[h,w] = t[h,1];

constraint forall( r in 2..h-1, c in 2..w-1)( 4*t[r,c] = t[r-1,c] + t[r+1,c] + t[r,c-1] + t[r,c+1]);

solve satisfy;

output[ show_float(6,2,t[r,c]) ++
        if c = h then "\n" else " " endif
        | r in 1..h, c in 1..w ];

代码块2:

var float: m = max(r in 1..h, c in 1..w)(t[r,c]);

代码区块3:

% Width of temperature grid
int: w = 5;

% Height of temperature grid
int: h = 5;

array[1..h,1..w] of var float: t;

% Temperature in the top row, bottom row, left row, right row, and corners
float: top = 100.0;
float: bottom = 0.0;
float: left = 0.0;
float: right = 0.0;
float: corners = 0.0;

% Top row all the same except corners
constraint forall(c in 2..w-1)(t[1,c] = top);

% Bottom row all the same except corners
constraint forall(c in 2..w-1)(t[h,c] = bottom);

% First column all the same except corners
constraint forall(r in 2..h-1)(t[r,1] = left);

% Last column all the same except corners
constraint forall(r in 2..h-1)(t[r,w] = right);

% The four corners must be the same value
constraint t[1,1] = corners /\ t[1,1] = t[1,w] /\ t[1,w] = t[h,w] /\ t[h,w] = t[h,1];

constraint forall( r in 2..h-1, c in 2..w-1)( 4*t[r,c] = t[r-1,c] + t[r+1,c] + t[r,c-1] + t[r,c+1]);

% Get the maximum value in t
var float: m;
constraint forall(r in 1..h, c in 1..w)(m >= t[r,c]);
constraint exists(r in 1..h, c in 1..w)(m = t[r,c]);

solve maximize m;

% Wish to replace the value six in the next line with m + 3, where the 3 represents
% character for the 2 digits to the right of a decimal point and 1 character for the
% decimal point
output[ show_float(6,2,t[r,c]) ++
        if c = h then "\n" else " " endif
        | r in 1..h, c in 1..w ];

1 个答案:

答案 0 :(得分:2)

我可以看到cannot determine bounds错误来自MIP求解器。这是由模型中tm定义为var float引起的。它可以通过一些修复 - 而且相当小 - 用于这些决策变量的域来修复。 E.g。

var 0.0..100.0: m;
array[1..h,1..w] of var 0.0..100.0: t;

如果使用可以将浮点数作为决策变量(例如Gecode或JaCoP)处理的FlatZinc解算器运行,则不会抛出此错误。但是,Gecode很慢,因为两个决策变量tm被定义为var float,它们是巨大的域。如果您设置了一个特定的 - 相当小的 - 域名,例如0.0..100.0然后Gecode快速解决这个问题。或者至少指出tm应该大于或等于0(由于域远大于0..100而不是那么快)。请注意,JaCoP解算器没有此问题;使用var float时速度不是很慢。