如何在Python中使用Pulp将’or’放入约束中

huangapple go评论61阅读模式
英文:

How to put 'or' into contraints in Pulp in python

问题

Here is the translated part of your text:

我有一个问题,我需要找到三个给定电机的最佳成本。

电机1的范围是100 - 300
电机2的范围是400 - 1000
电机3的范围是50 - 250

它们的目标值是600

电机1的价格是5000
电机2的价格是5500
电机3的价格是5250

方程如下:

成本 = 电机1 * 5000 + 电机2 * 5500 + 电机3 * 5250。

还有一个非常重要的部分,不是每个电机都需要运行。

我有一个Python代码,可以计算它,但我可以传递给它不需要包括每个电机的信息。
以下是代码:

```python
from pulp import LpProblem, LpVariable, LpMinimize

def find_lowest_cost():
    # 定义问题
    problem = LpProblem("电机优化", LpMinimize)

    # 定义决策变量
    x = LpVariable("电机1", lowBound=100, cat='Integer')  # 电机1的功率
    y = LpVariable("电机2", lowBound=0, cat='Integer')    # 电机2的功率
    z = LpVariable("电机3", lowBound=50, cat='Integer')   # 电机3的功率

    # 定义目标函数(成本)
    problem += x * 5000 + y * 5500 + z * 5250

    # 定义约束条件
    problem += x >= 100  # 电机1下限
    problem += x <= 300  # 电机1上限
    problem += y >= 350  # 电机2下限
    problem += y <= 1000 # 电机2上限
    problem += z >= 50   # 电机3下限
    problem += z <= 250  # 电机3上限
    problem += x + y + z == 500  # 总功率约束

    # 解决问题
    problem.solve()

    # 获取最优解
    lowest_cost = problem.objective.value()
    best_combination = (x.value(), y.value(), z.value())
    return lowest_cost, best_combination

cost, combination = find_lowest_cost()
print("最低成本:", cost)
print("电机组合:", combination)

我尝试在“定义约束条件”部分添加了'or',但没有帮助

    problem += x >= 100 or x == 0  # 电机1下限
    problem += x <= 300           # 电机1上限
    problem += y >= 350 or y == 0  # 电机2下限
    problem += y <= 1000          # 电机2上限
    problem += z >= 50 or z == 0  # 电机3下限
    problem += z <= 250           # 电机3上限
    problem += x + y + z == 500   # 总功率约束

所以我的问题是,如何将'OR'实现到我的代码中。

谢谢你提前。

英文:

I have a problem, where I have to find the optimal cost of 3 given motor.

Motor 1 has a range of 100 - 300
Motor 2 has a range of 400 - 1000
Motor 3 has a range of 50 - 250

They have a target value of 600

Motor 1 price is 5000
Motor 2 price is 5500
Motor 3 price is 5250

The equation looks like this:

Cost = Motor1 * 5000 + Motor2 * 5500 + Motor3 * 5250.

And a very important part, NOT every motor needs to run.

I have a python code, that can calculate it, but I can give it to it that not every motors needs to be inclued.
Here is the code:

from pulp import LpProblem, LpVariable, LpMinimize

def find_lowest_cost():
    # Define the problem
    problem = LpProblem(&quot;Motor Optimization&quot;, LpMinimize)

    # Define the decision variables
    x = LpVariable(&quot;Motor1&quot;, lowBound=100, cat=&#39;Integer&#39;)  # Power of motor 1
    y = LpVariable(&quot;Motor2&quot;, lowBound=0, cat=&#39;Integer&#39;)  # Power of motor 2
    z = LpVariable(&quot;Motor3&quot;, lowBound=50, cat=&#39;Integer&#39;)  # Power of motor 3

    # Define the objective function (cost)
    problem += x * 5000 + y * 5500 + z * 5250

    # Define the constraints
    problem += x &gt;= 100  # Motor 1 lower bound
    problem += x &lt;= 300   # Motor 1 upper bound
    problem += y &gt;= 350  # Motor 2 lower bound
    problem += y &lt;= 1000  # Motor 2 upper bound
    problem += z &gt;= 50  # Motor 3 lower bound
    problem += z &lt;= 250  # Motor 3 upper bound
    problem += x + y + z == 500  # Total power constraint

    # Solve the problem
    problem.solve()

    # Retrieve the optimal solution
    lowest_cost = problem.objective.value()
    best_combination = (x.value(), y.value(), z.value())
    return lowest_cost, best_combination

cost, combination = find_lowest_cost()
print(&quot;Lowest cost:&quot;, cost)
print(&quot;Motor combination:&quot;, combination)

I tried to add 'or' to the "Define the Constraints' part, but it did not help

    problem += x &gt;= 100 or x ==0 # Motor 1 lower bound
    problem += x &lt;= 300  # Motor 1 upper bound
    problem += y &gt;= 350 or y == 0 # Motor 2 lower bound
    problem += y &lt;= 1000  # Motor 2 upper bound
    problem += z &gt;= 50 or z == 0 # Motor 3 lower bound
    problem += z &lt;= 250  # Motor 3 upper bound
    problem += x + y + z == 500  # Total power constraint

So my Questions is, how to implement that 'OR' into my code.

Thank you in advance

答案1

得分: 0

我有一些假设:

  • 电机的功率是连续的,而不是积分的。
  • 观察您的变量界限中的最小值,而不是后来添加的冗余和不一致的约束。
  • 使用500作为目标,而不是600。

您需要像这样的二进制选择变量:

from pulp import LpProblem, LpVariable, LpMinimize, LpContinuous, lpDot, LpBinary, lpSum

powers = (
    LpVariable('Motor1', cat=LpContinuous, upBound=300),
    LpVariable('Motor2', cat=LpContinuous, upBound=1000),
    LpVariable('Motor3', cat=LpContinuous, upBound=250),
)
used = LpVariable.matrix(name='MotorUsed', cat=LpBinary, indices=range(len(powers)))

problem = LpProblem(name='Motor_Optimization', sense=LpMinimize)
problem.objective = lpDot(powers, (5000, 5500, 5250))

problem.addConstraint(name='target', constraint=lpSum(powers) == 500)

for power, power_min, use in zip(
    powers,
    (100, 0, 50),
    used,
):
    problem.addConstraint(power >= power_min*used)
    problem.addConstraint(power <= 1000*used)

problem.solve()
combination = 

print('Lowest cost:', problem.objective.value()) print('Motor combination:', combination)

Result - Optimal solution found

Objective value:                2550000.00000000
Enumerated nodes:               0
Total iterations:               0
Time (CPU seconds):             0.01
Time (Wallclock seconds):       0.01

Option for printingOptions changed from normal to all
Total time (CPU seconds):       0.01   (Wallclock seconds):       0.01

Lowest cost: 2550000.0
Motor combination: [300.0, 0.0, 200.0]
英文:

I make some assumptions:

  • Continuous power of motors, not integral
  • Observe the minima in your variable bounds, not the redundant and inconsistent constraints added later
  • Use 500 as a target, not 600

You need binary selection variables, like this:

from pulp import LpProblem, LpVariable, LpMinimize, LpContinuous, lpDot, LpBinary, lpSum

powers = (
    LpVariable(&#39;Motor1&#39;, cat=LpContinuous, upBound=300),
    LpVariable(&#39;Motor2&#39;, cat=LpContinuous, upBound=1000),
    LpVariable(&#39;Motor3&#39;, cat=LpContinuous, upBound=250),
)
used = LpVariable.matrix(name=&#39;MotorUsed&#39;, cat=LpBinary, indices=range(len(powers)))

problem = LpProblem(name=&#39;Motor_Optimization&#39;, sense=LpMinimize)
problem.objective = lpDot(powers, (5000, 5500, 5250))

problem.addConstraint(name=&#39;target&#39;, constraint=lpSum(powers) == 500)

for power, power_min, use in zip(
    powers,
    (100, 0, 50),
    used,
):
    problem.addConstraint(power &gt;= power_min*used)
    problem.addConstraint(power &lt;= 1000*used)

problem.solve()
combination = 

print(&#39;Lowest cost:&#39;, problem.objective.value()) print(&#39;Motor combination:&#39;, combination)

Result - Optimal solution found

Objective value:                2550000.00000000
Enumerated nodes:               0
Total iterations:               0
Time (CPU seconds):             0.01
Time (Wallclock seconds):       0.01

Option for printingOptions changed from normal to all
Total time (CPU seconds):       0.01   (Wallclock seconds):       0.01

Lowest cost: 2550000.0
Motor combination: [300.0, 0.0, 200.0]

huangapple
  • 本文由 发表于 2023年6月1日 20:12:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76381732.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定