【问题标题】:How to use a variable as a divisor in PuLP如何在纸浆中使用变量作为除数
【发布时间】:2016-02-29 00:01:48
【问题描述】:

我试图通过将变量 A 除以变量 B 来计算约束来解决 LP 问题。

问题的简单版本如下:

  1. 产品由两种材料(A和B)制成

  2. A 的百分比应大于 50%

  3. B 的百分比应小于 40%

  4. A和B的总量是100

目标:A的最小数量是多少?

代码如下:

from pulp import *

prob = LpProblem('Simple problem', LpMinimize)
x = LpVariable('x', 0, None, 'Integer')
y = LpVariable('y', 0, None, 'Integer')
prob += x
prob += x / (x + y) > 0.5  # <== Where the error happens
prob += y / (x + y) < 0.4
prob += x + y == 100
prob.solve()

print 'Result: %s' % LpStatus[prob.status]
print 'Amount of A: %s' % value(prob.objective)

但是我收到一条错误消息:

TypeError: 表达式不能被非常量表达式除

看起来 PuLP 不支持变量作为除数。 https://github.com/coin-or/pulp/blob/master/src/pulp/pulp.py#L800

有什么想法吗?如果 PuLP 不是合适的库,我很乐意切换到任何适合的库。

2015 年 11 月 27 日更新

由于某种原因,上面的示例没有意义(未按预期工作)。我是这个图书馆的新手。也许这根本不是解决我问题的合适人选。因此,如果有人对其他库有建议,我们将不胜感激。

顺便说一句,下面 Koen Peters 的建议很棒。接受他的建议后,错误消失了。谢谢。

【问题讨论】:

    标签: python pulp


    【解决方案1】:

    线性规划不理解除法,因此错误:) 您必须重新制定它,以便线性地制定除法。 在这种情况下:

    prob += x / (x + y) > 0.5  
    prob += y / (x + y) < 0.4
    

    相当于:

    prob += x > 0.5 * (x + y)
    prob += y < 0.4 * (x + y)
    

    哪些是线性约束。 祝你好运!

    【讨论】:

    • 感谢您的解决方案。它正在工作。如果目标是一个部门怎么办?有什么办法可以解决吗?
    • 优化非线性物镜更具挑战性。如果可以的话,尽量避免它或解决它!如果无法避免,请查看 Charles-Cooper 的方法 (en.wikipedia.org/wiki/Linear-fractional_programming)
    【解决方案2】:

    我觉得我的解决方案中不应该允许零 - 我包含了一个变量,它是 xy 的总和(认为您将其称为 A)。

    from pulp import LpProblem, LpStatus, LpVariable
    from pulp import LpMinimize, LpMaximize, lpSum, value
    
    # I feel like zero shouldn't be allowed for lower bound...
    x = LpVariable("x", lowBound=1, cat="Integer")
    y = LpVariable("y", lowBound=1, cat="Integer")
    z = LpVariable("z", lowBound=1, cat="Integer")
    
    model = LpProblem("Divison problem", LpMinimize)
    
    model += x
    model += z == x + y
    model += z == 100
    
    # Rather than division, we can use multiplication
    model += x >= z * 0.5
    model += y <= z * 0.4
    
    model.solve()
    
    print(LpStatus[model.status])
    
    print(f"""
    x = {int(x.varValue):>3}  #  60
    y = {int(y.varValue):>3}  #  40
    z = {int(z.varValue):>3}  # 100
    """)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-08
      • 2023-03-14
      • 2020-09-16
      • 2022-01-10
      • 1970-01-01
      • 2020-08-06
      相关资源
      最近更新 更多