【发布时间】:2019-06-10 23:01:20
【问题描述】:
我需要阻止 CPLEX 这样做,但不知道该怎么做。
- 我有一个小问题,它是 MIP。
- 目标中有一个系数为零的变量x。
- 所有约束都“小于或等于”-约束。
- x 只出现在约束矩阵中的非负系数。
- CPLEX 返回一个解,其中 x 设置为正值,这很奇怪,因为它没有提高目标函数值,并且在约束矩阵中,x只会“带走容量”。
在迭代过程中多次求解模型。在每次迭代中,目标都会发生变化。因此,我检查了上一次迭代的模型和解决方案,发现 x 当时的系数为负,并设置为正值。我得出结论,此行为一定与 CPLEX 的某些热启动有关。
如何预防?
我宁愿不将具有正系数的变量添加到目标中,因为有很多。
这是一个 Java 示例:
IloCplex cplex = new IloCplex();
/* Variables */
IloNumVar x = cplex.intVar(0, Integer.MAX_VALUE, "x");
/* Objectiv */
IloLinearNumExpr objExpr = cplex.linearNumExpr();
objExpr.addTerm(1.0, x);
IloObjective objective = cplex.addMaximize();
objective.setExpr(objExpr);
/* Constraints */
IloLinearNumExpr expr = cplex.linearNumExpr();
expr.addTerm(1.0, x);
cplex.addLe(expr, 2.5);
System.out.println(cplex.getModel().toString());
cplex.solve();
System.out.println("x = " + cplex.getValue(x) + "\n"); // x = 2.0
objective.clearExpr();
IloLinearNumExpr newObjexpr = cplex.linearNumExpr();
objective.setExpr(newObjexpr);
System.out.println(cplex.getModel().toString());
cplex.solve();
System.out.println("x = " + cplex.getValue(x) + "\n"); // x = 2.0
【问题讨论】:
-
如果变量根本不在目标中,那么您实际上是在告诉 CPLEX,您对它所取的值没有偏好。因此,您可以获得任何可行且与您的(最佳)解决方案的其余部分兼容的值。
-
@TimChippingtonDerrick 当然。但是,求解器没有理由增加该变量的值,除非它使用一些初始解决方案。 (想想单纯形从一个基本可行的解决方案到下一个。)我不想在目标中包含像 x 这样的变量,以减少求解器的计算工作量。接受的答案解决了这个问题,因为它正是这样做的:热启动。
标签: cplex