为什么 CPLEX 将不相关的变量设置为 1?

Why does CPLEX set unrelated variables as 1?

我一直在研究可以建模为整数线性规划的组合优化问题。我在 visual studio 2017 和 CPLEX1271 中将其实现为 c++ 项目。由于存在成倍增加的约束,我通过 IloCplex::LazyConstraintCallbackI 实现了惰性约束。在我看来,以下过程是如何产生最佳解决方案的:每次识别出整数解决方案时,LazyConstraintCallbackI 都会检查它并向模型添加一些违反的约束,直到获得最佳整数解决方案。

但是,我的实现针对不同输入给出的 objective 值并不总是正确的。经过将近一年的断断续续的调试和测试,我终于找到了原因,这是非常相关的问题,但可以通过以下小例子来解释(希望如此):一个整数线性规划涉及四个 bool 变量 x1、x2、x3 和 x4

minimize x1
subject to: 
x1  ≥  x2
x1  ≥  x3
x1  ≥  x4
x2  + x3  ≥ 1
x1, x2, x3 and x4  ∈ {0, 1}​

cplex给出的结果是:

Solution status = Optimal
Objective value = 1
x1 = 1
x2 = 1
x3 = 1
x4 = 1​

毫无疑问,objective值是正确的。奇怪的是cplex设置x4 = 1。虽然x4等于1或0对这个编程中的objective值没有影响。但是,当使用惰性约束回调时,这可能会通过添加一些不正确的约束而导致问题 整数规划通过迭代添加违反的约束来解决。我想知道:

  1. 为什么 cplex 将 "unrelated" 变量 x4 设置为 1,而不是 0?
  2. 我应该怎么做才能告诉 CPLEX 我想将 "unrelated" 变量保留为 0?

由于在最优解中没有任何因素强制 x4=0,因此不能保证 CPLEX 会设置 x4=0?为什么会这样?为什么 0 优于 1?该模型有两个最优解,一个 x4=0,一个 x4=1。两者都有 objective 值 1。CPLEX 完全可以自由选择其中之一。

正如 sascha 在他的评论中所说,在最优解中强制 x4=0 的唯一方法是将此约束添加到模型中,例如通过将 objective 系数设置为较小的正值。

但是,您的惰性约束回调会从整数可行解中生成无效约束,这似乎很奇怪。这看起来像一个错误:回调对模型做出无效假设(即在任何最优解中 x4=0)或者回调逻辑中某处存在错误。请注意,在手头的模型中,回调实际上可以切断 x4=1 的解决方案,因为这仍然会留下 x4=0 的等效最佳解决方案,而 CPLEX 最终会找到它。