我有以下优化问题:
受
约束其中 = {0,1}(二进制变量)。
当我在Pulp中实现它时:
from pulp import *
x1 = pulp.LpVariable('x1', cat=LpBinary)
x2 = pulp.LpVariable('x2', cat=LpBinary)
x3 = pulp.LpVariable('x3', cat=LpBinary)
x4 = pulp.LpVariable('x4', cat=LpBinary)
prob = pulp.LpProblem('x1+x2+2*x3+x4', pulp.LpMaximize)
prob += lpSum([x1, x2, 2*x3, x4])
prob += lpSum([x1, x2, x3, x4]) == 2
prob.solve()
我得到了,,和的解决方案。但是,我想不允许这个解决方案,在Pulp中添加另一个约束为:
prob += lpSum([x1, x3]) < 2
但是由于我在prob.solve()中有一个虚拟变量,所以我得不到一个好的解决方案。我应该使用其他约束还是我做错了什么?
答案 0 :(得分:2)
运行prob += lpSum([x1, x3]) < 2
时,会出现以下错误:
回溯(最近一次呼叫最后一次):文件&#34; xyz.py&#34;,第13行, prob + = lpSum([x1,x3])&lt; 2 TypeError:&#39;&lt;&#39; LpAffineExpression&#39;的实例之间不支持和&#39; int&#39;
这是纸浆包装告诉您不能添加严格的不等式,这是优化求解器的标准要求。由于您的所有变量都是二进制值,<2
与<=1
相同,并且进行此更改将使求解器满意:
prob += lpSum([x1, x3]) <= 1
prob.solve()
print(x1.value(), x2.value(), x3.value(), x4.value())
# 0.0 1.0 1.0 0.0
所以现在你得到一个不同的解决方案,其目标值为3(x2 = 1且x3 = 1)。
如果您想输出所有可能的解决方案,您可以使用循环来继续添加约束,从而不允许最佳解决方案,直到最佳目标值发生变化:
from pulp import *
x1 = pulp.LpVariable('x1', cat=LpBinary)
x2 = pulp.LpVariable('x2', cat=LpBinary)
x3 = pulp.LpVariable('x3', cat=LpBinary)
x4 = pulp.LpVariable('x4', cat=LpBinary)
prob = pulp.LpProblem('x1+x2+2*x3+x4', pulp.LpMaximize)
prob += lpSum([x1, x2, 2*x3, x4])
prob += lpSum([x1, x2, x3, x4]) == 2
prob.solve()
print(x1.value(), x2.value(), x3.value(), x4.value())
opt = prob.objective.value()
while True:
prob += lpSum([x.value() * x for x in [x1, x2, x3, x4]]) <= 1 + 1e-6
prob.solve()
if prob.objective.value() >= opt - 1e-6:
print(x1.value(), x2.value(), x3.value(), x4.value())
else:
break # No more optimal solutions
这产生了预期的输出:
# 1.0 0.0 1.0 0.0
# 0.0 1.0 1.0 0.0
# 0.0 0.0 1.0 1.0
答案 1 :(得分:1)
要查找所有解决方案,您需要进行以下修改
while True:
prob += lpSum([x for x in [x1, x2, x3, x4] if x.value() >= 0.99]) <= sum([x.value() for x in [x1, x2, x3, x4]]) -1
prob.solve()
if prob.objective.value() >= opt - 1e-6:
print(x1.value(), x2.value(), x3.value(), x4.value())
else:
break # No more optimal solutions