在CPLEX中从IloBoolVarArray解析到Bool的问题

时间:2016-03-09 23:46:29

标签: c++ floating-point double mathematical-optimization cplex

我在MIP问题中遇到IloBoolVarArray。解算器完成后,我将这些变量解析为double,但有时我得到的值非常小,为1.3E-008而不是0.我的问题是:为什么?它只是一个解析问题吗?在内部,求解器使用了这个值,所以结果不值得信赖吗?

非常感谢。

1 个答案:

答案 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,即使是小型实例,也可能无法获得良好的结果。