【问题标题】:Pulp constraints when probelm is Infeasible问题不可行时的纸浆约束
【发布时间】:2020-07-06 10:25:23
【问题描述】:

我正在尝试在 Python 中使用 Pulp 解决线性优化问题。

代码如下:

import pandas as pd
import pulp

D_XB = 20
D_XP = 0
D_XC = 0

Available_Time = 1440 #in minutes

test = [['A1', 'A2', 'A3', 'A4', 'A5'], [1,2,1,0,3], [16,32,0,16,32], [10,10,10,10,10], [120,210,180,180,350]]

Cycles = pd.DataFrame(test, index=['Cycles', 'QTA1', 'QTA2', 'QTA3', 'T_TOT']).T

A1 = pulp.LpVariable("Cycle_A1", lowBound=0, cat='Integer')
A2 = pulp.LpVariable("Cycle_A2", lowBound=0, cat='Integer')
A3 = pulp.LpVariable("Cycle_A3", lowBound=0, cat='Integer')
A4 = pulp.LpVariable("Cycle_A4", lowBound=0, cat='Integer')
A5 = pulp.LpVariable("Cycle_A5", lowBound=0, cat='Integer')
    
# Defining the problem as a minimization problem (Minimize Storage)
problem_5 = pulp.LpProblem("Storage_Minimization_3", pulp.LpMinimize)

S_XB = pulp.lpSum((Cycles.iloc[0]["QTA1"])*A1 + (Cycles.iloc[1]["QTA1"])*A2 + (Cycles.iloc[2]["QTA1"])*A3 + (Cycles.iloc[3]["QTA1"])*A4 + (Cycles.iloc[4]["QTA1"])*A5)
S_XP = pulp.lpSum((Cycles.iloc[0]["QTA2"])*A1 + (Cycles.iloc[1]["QTA2"])*A2 + (Cycles.iloc[2]["QTA2"])*A3 + (Cycles.iloc[3]["QTA2"])*A4 + (Cycles.iloc[4]["QTA2"])*A5)
S_XC = pulp.lpSum((Cycles.iloc[0]["QTA3"])*A1 + (Cycles.iloc[1]["QTA3"])*A2 + (Cycles.iloc[2]["QTA3"])*A3 + (Cycles.iloc[3]["QTA3"])*A4 + (Cycles.iloc[4]["QTA3"])*A5)

Tot_Time = pulp.lpSum((Cycles.iloc[0]["T_TOT"])*A1 + (Cycles.iloc[1]["T_TOT"])*A2 + (Cycles.iloc[2]["T_TOT"])*A3 + (Cycles.iloc[3]["T_TOT"])*A4 + (Cycles.iloc[4]["T_TOT"])*A5)

Stock_XB = (S_XB - D_XB)
Stock_XP = (S_XP - D_XP)
Stock_XC = (S_XC - D_XC)

problem_5 += Stock_XB + Stock_XP + Stock_XC
    
# Constraints: Time constraint present
problem_5 += S_XB >= D_XB
problem_5 += S_XP >= D_XP
problem_5 += S_XC >= D_XC
problem_5 += A1 >= 0
problem_5 += A2 >= 0
problem_5 += A3 >= 0
problem_5 += A4 >= 0
problem_5 += A5 >= 0
problem_5 += Tot_Time <= Available_Time
    
# Solving the probelm
status = problem_5.solve()

result = pd.DataFrame({'A1':[pulp.value(A1)], 'A2':[pulp.value(A2)], 'A3':[pulp.value(A3)], 'A4':[pulp.value(A4)], 'A5':[pulp.value(A5)], 
                       'Demand XB':[D_XB], 'Demand XP':[D_XP], 'Demand XC':[D_XC],  'Minimum storage':[pulp.value(problem_5.objective)], 
                       'Stock_XB':[pulp.value(Stock_XB)], 'Stock_XP':[pulp.value(Stock_XP)], 'Stock_XC':[pulp.value(Stock_XC)], 
                       'Total Time needed':[pulp.value(Tot_Time)]})

术语: S_* 是某个项目的生产, D_* 是该项目的需求。 这些是在定义problelm之前定义的。

这个问题并不总是可行的,因为有时生产会超过可用时间。在这种情况下,我希望遵守对周期的限制,并且应该打破按时的限制以解决问题。

我怎样才能做到这一点?

谢谢, 卡洛塔。

【问题讨论】:

  • 示例不完整。 S_* 和 D_* 是参数还是纸浆变量?如果它们是参数,那么这并不是真正的约束,因为它不涉及任何纸浆变量。如果它们是纸浆表达,那么您就错过了它们的定义。最简单的方法是您提供一个包含所有所需数据的完整示例。
  • @pchtsp 我在S_* 和D_* 的定义上添加了部分。基本上D_* 是我从客户提供的数据集中得到的需求。然后使用问题的结果计算供应量。目标是找出哪些周期让我尽可能少地生产需要存储的物品。
  • 正如我在编辑中所说,您应该编辑代码以获得 mwe (stackoverflow.com/help/minimal-reproducible-example),其中包含一些显示您的问题的发明数据,以便我们可以在我们的电脑中运行代码并更好地帮助 ypu .
  • @pchtsp 我编辑了代码,现在你可以在你的电脑上运行代码了。正如您将在此示例中看到的那样,应该 >= 0 的循环 A2 是 -8.8,并且 hte 循环也应该是整数,但它们在给定的解决方案中是浮动的。所需的时间是 1440,但我希望它比遵守周期限制的更多。

标签: python optimization constraints pulp minimization


【解决方案1】:

我会这样做的方法是将松弛变量添加到时间限制约束中,如下所示:

首先你添加一个新变量:

#(...)
slack_time = pulp.LpVariable("slack_time", lowBound=0, cat=pulp.LpContinuous)
#(...)

然后你在目标函数中惩罚它:

#(...)
big_enough_number = 10000
problem_5 += Stock_XB + Stock_XP + Stock_XC + slack_time*big_enough_number
#(...)

最后你将它添加到你的时间限制约束中:

#(...)
problem_5 += Tot_Time - slack_time <= Available_Time
#(...)

然后,您将获得一个违反时间限制的解决方案,最不可能。如果你选择了足够好的big_enough_number,模型只会在没有其他选择的情况下违反时间约束。

【讨论】:

  • 您对如何选择big_enough_number 有什么建议吗?这样模型在没有其他选择的情况下才会违反时间约束?
  • 这将取决于您的目标函数中的其他权重以及您赋予所有变量的范围。您不想给予很大的权重(因为它会导致数字问题),但您希望确保它足够,以至于即使将Tot_time 延迟一个单位也会比拥有巨大的Stock_XP 更昂贵。
  • 非常感谢@pchtsp 我会听从您的建议并相应地选择big_enough_number
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-01
相关资源
最近更新 更多