二进制变量输出不是二进制-pyomo(ipopt求解器)

时间:2020-02-11 04:01:24

标签: optimization pyomo

我正在使用Pyomo(使用iPopt求解器)来优化模型,并且我试图建立一个约束,以将模型的特定变量保持在一定范围(0,500)之外,即该变量可以是零或大于500。

由于我无法为变量指定多个域,因此我使用二进制变量为每个变量添加了约束。

约束的工作原理如下:

model.variable <= 1 + (large_upper_bound-1)*model.binary_variable
model.variable >= 500*model.binary_variable

这是我的代码:

model.x2 = Var(binary_vars, within=Binary)

for route in binary_vars:
        model.cons.add(model.x[route[0], route[1], route[2], route[3]] <= (1 + (100000-1)*model.x2[route[0], route[1], route[2], route[3]]))
        model.cons.add(model.x[route[0], route[1], route[2], route[3]] >= (500*model.x2[route[0], route[1], route[2], route[3]]))
model_result = SolverFactory('ipopt').solve(model, tee=True)

代码运行良好,但是二进制变量的解决方案不是二进制(不是0或1),而是零或随机分数:

dict_values([0.0, 0.0, 0.0, 0.0, 0.0, 0.69771460622592687, 
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
0.0, 0.0, 0.0, 0.0, 0.0,  0.0, 0.52210753137570483, 0.0, 0.0,
0.44349809775540615])

这意味着x变量的解不超出指定范围。

有人可以帮助我理解为什么二进制变量变为小数吗?

如何停止这些操作,并为这些二进制变量(例如[0,1])强加一组整数?

和/或是否还有其他方法可以解决此问题?

谢谢。

1 个答案:

答案 0 :(得分:2)

首先,Ipopt仅解决持续存在的问题。它会忽略变量的离散状态,并将其视为在其指定范围之间是连续的。

第二,即使您要使用MIP求解器(例如Gurobi,Cplex),也必须考虑这些求解器中内置的整数公差。它们可能会为二进制变量返回诸如.999999的值,具体取决于求解器使用的公差设置。在您检查解决方案时,考虑到这一点是一个好主意,也许可以通过在适当的地方将解决方案四舍五入为整数。