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

Problems to parse from IloBoolVarArray to Bool in CPLEX

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

非常感谢。

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,即使是小实例,您也可能不会得到好的结果。