我在MIP问题中遇到IloBoolVarArray
。解算器完成后,我将这些变量解析为double
,但有时我得到的值非常小,为1.3E-008而不是0.我的问题是:为什么?它只是一个解析问题吗?在内部,求解器使用了这个值,所以结果不值得信赖吗?
非常感谢。
答案 0 :(得分:1)
CPLEX在内部使用双精度浮点数据。它具有公差参数EpInt。如果变量x
具有值
0 <= x <= EpInt, or
1-EpInt <= x <= 1
然后CPLEX将该值视为二进制。 EpInt的默认值为10 ^ -6,因此您看到的解决方案值10 ^ -8与CPLEX的默认行为一致。除非您确实需要精确的整数值,否则在从CPLEX中提取解决方案时应该考虑到这一点。你可以在C ++中做的一件特别糟糕的事情是
IloBoolVar x(env);
// ...
cplex.solve();
int bad_value = cplex.getValue(x); // BAD
int ok_value = cplex.getValue(x) + 0.5; // OK
这里,即使CPLEX解决方案的有效值为1,bad_value也可以设置为0.这是因为CPLEX的值可以为0.999999,它将被截断为0.第二个赋值将可靠地存储解决方案。
在最新版本的CPLEX中,您可以将EpInt设置为0,这将使CPLEX仅将0.0和1.0视为二进制。如果确实需要精确值0或1,那么您应该记住CPLEX旨在工作的域。例如,如果您尝试使用它来解决cryptology problems,即使是小型实例,也可能无法获得良好的结果。