【问题标题】:Error disallowing the optimal solution using Python Pulp错误不允许使用 Python Pulp 的最佳解决方案
【发布时间】:2018-05-11 11:01:41
【问题描述】:

我有以下优化问题:

以为准

其中 = {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() 中有一个虚拟变量。我应该使用另一个约束还是我做错了什么?

【问题讨论】:

    标签: mathematical-optimization linear-programming pulp


    【解决方案1】:

    当您运行prob += lpSum([x1, x3]) &lt; 2 时,您会收到以下错误:

    Traceback(最近一次调用最后一次):文件“xyz.py”,第 13 行,在 prob += lpSum([x1, x3])

    这是纸浆包,告诉您不能添加严格的不等式,这是优化求解器的标准要求。由于所有变量都是二进制值,&lt;2&lt;=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
    

    【讨论】:

    • 要获得所有解决方案,您需要更改在 True 时添加的约束:prob += lpSum([x for x in [x1, x2, x3, x4] if x.value() > = 0.99]) = opt - 1e-6: print(x1.value(), x2.value(), x3.value(), x4。 value()) else: break # 没有最优解
    • @StuartMitchell 这两种方法是相同的,只是代表相同约束的不同 python 代码(嗯,你的更通用,因为你不假设它们总和为 2,因此约束需要有 @ 987654327@,但在这个模型中,我们知道它们的总和为 2)。
    • @josliber 不是真的,因为您的解决方案也可能存在浮点运算问题,因为纸浆通常返回 1 的 0.9999 和 0 的 0.00001
    • @StuartMitchell 很公平——我继续在 RHS 中添加了 1e-6,这应该可以解决这些问题。
    【解决方案2】:

    要找到所有解决方案,您需要进行以下修改

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-12
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 2014-09-18
      相关资源
      最近更新 更多