PuLP: Objective 功能:在循环中添加多个 lpSum
PuLP: Objective Function: Adding multiple lpSum in a loop
我正在尝试使用 PuLp 解决不同元素(铁,Mercury..)的混合问题。但是我需要最大限度地利用约束,而不是 max/min 一些 profit/cost。所以在 Excel 我有这样的东西(伪代码):
max Sum (for each Element: (Sumproduct([DecisionVariables] * [Values]) / [MaximumAllowedValueForThisElement]))
我从未使用过这样的 objective 函数,但它似乎在 Excel 中有效。
现在我想在 PuLP 中模拟同样的问题。我想我需要的是这样的想法:
for Element in ELEMENTS:
prob += lpSum(DecisionVariable[Concentrate]*dic[Element][Concentrate]/ MaxAmount[Element] for Concentrate in CONCENTRATES)
其中 ELEMENTS 是一个包含所有元素的列表,CONCENTRATES 是一个列表
从 0 到 100 的值和 dic[Element][Concentrate] 存储每个元素及其所有浓缩物的值。
现在使用上面的代码,objective 函数在每个循环中都被覆盖。我不需要覆盖旧的 objective 函数,而是需要类似 append() 或类似的东西来将每个 loops=lpSums 添加到我的 prob 变量?class?
总的来说,我对编程还比较陌生,我想我的问题更多是因为我缺乏 python 编程技能,而不是我(也缺乏 :D)PuLP 技能。但是我在 PuLP documentation 中找不到任何东西,至少没有我可以连接到的东西。
编辑:包括一个小 table 来展示问题:
+------------------------------+-------------------------------------------+----+------------------------------+---------------+----------------------+---------------+---------------+-------------------------------+
| Utilization [%] | Sumproduct[Quantity] = [LHS] | | Constrains[Quantity] = [RHS] | Concentrate | Element 1 [%] | Element 2 [%] | Element 3 [%] | Decision Variables [Quantity] |
+------------------------------+-------------------------------------------+----+------------------------------+---------------+----------------------+---------------+---------------+-------------------------------+
| u1 = z1 / MaxAmount Element1 | z1 = Col Element1 * Col Decison Variables | <= | MaxAmount Element1 | Concentrate 1 | % Element 1 in Con 1 | | | X1 |
| u2 = z2 / MaxAmount Element2 | z2 = Col Element2 * Col Decison Variables | <= | MaxAmount Elemen2 | Concentrate 2 | % Element 1 in Con 2 | | | X2 |
| u3 = z3 / MaxAmount Element3 | z3 = Col Element3 * Col Decison Variables | <= | MaxAmount Elemen3 | Concentrate 3 | % Element 1 in Con 3 | | | X3 |
+------------------------------+-------------------------------------------+----+------------------------------+---------------+----------------------+---------------+---------------+-------------------------------+
"Element 2" 和 "Element 3" 列存储与 "Element 1" 列相同的信息:各元素在 Concentrate 1/2/3 中的百分比份额。
objective 函数是最大化所有利用率 (u1+u2+u3) 的总和。所以我试图确定我应该使用多少浓缩物,尽可能多地利用每个元素的给定限制。回到我的 PuLp 代码,我想我可以将 "u1" 的等价物添加到我的 PuLp "LpProblem Class",但我不知道如何将这些 LpSums 中的多个添加到我的 [=37] =] 在循环中。
这是一个版本,带有用于说明目的的虚拟数据。看看对你有没有帮助。
import pulp
from pulp import *
ELEMENTS = ['Iron', 'Mercury', 'Silver']
Max_Per_Elem = {'Iron': 35,
'Mercury': 17,
'Silver': 28
}
# A dictionary of the Iron percent in each of the CONCs
IronPercent = {'CONC_1': 20, 'CONC_2': 10, 'CONC_3': 25}
# A dictionary of the Hg percent in each of the CONCs
MercPercent = {'CONC_1': 15, 'CONC_2': 18, 'CONC_3': 12}
# A dictionary of the Silver percent in each of the CONCs
SilverPercent = {'CONC_1': 30, 'CONC_2': 40, 'CONC_3': 20}
CONCENTRATE_DIC = {'Iron': IronPercent,
'Mercury': MercPercent,
'Silver': SilverPercent
}
# Creates a list of Decision Variables
concs = ['CONC_1', 'CONC_2', 'CONC_3']
现在,我们可以调用 puLP
函数了。
conc_vars = LpVariable.dicts("Util", concs, 0, 1.0)
# Create the 'prob' variable to contain the problem data
prob = LpProblem("Elements Concentration Problem", LpMaximize)
# The objective function
prob += lpSum([conc_vars[i] for i in concs]), "Total Utilization is maximized"
for elem in ELEMENTS:
prob += lpSum([CONCENTRATE_DIC[elem][i]/Max_Per_Elem[elem] * conc_vars[i] for i in concs]) <= Max_Per_Elem[elem]/100, elem+"Percent"
为了验证,您可以打印 prob
以查看其外观:
Elements Concentration Problem:
MAXIMIZE
1*Util_CONC_1 + 1*Util_CONC_2 + 1*Util_CONC_3 + 0
SUBJECT TO
IronPercent: 0.571428571429 Util_CONC_1 + 0.285714285714 Util_CONC_2
+ 0.714285714286 Util_CONC_3 <= 0.35
MercuryPercent: 0.882352941176 Util_CONC_1 + 1.05882352941 Util_CONC_2
+ 0.705882352941 Util_CONC_3 <= 0.17
SilverPercent: 1.07142857143 Util_CONC_1 + 1.42857142857 Util_CONC_2
+ 0.714285714286 Util_CONC_3 <= 0.28
VARIABLES
Util_CONC_1 <= 1 Continuous
Util_CONC_2 <= 1 Continuous
Util_CONC_3 <= 1 Continuous
对公式满意后,解决问题。
prob.writeLP("ElemUtiliztionModel.lp")
prob.solve()
print("Status:", LpStatus[prob.status])
for v in prob.variables():
print(v.name, "=", v.varValue)
得到,
Status: Optimal
Util_CONC_1 = 0.0
Util_CONC_2 = 0.0
Util_CONC_3 = 0.24083333
希望能帮助您前进。
我正在尝试使用 PuLp 解决不同元素(铁,Mercury..)的混合问题。但是我需要最大限度地利用约束,而不是 max/min 一些 profit/cost。所以在 Excel 我有这样的东西(伪代码):
max Sum (for each Element: (Sumproduct([DecisionVariables] * [Values]) / [MaximumAllowedValueForThisElement]))
我从未使用过这样的 objective 函数,但它似乎在 Excel 中有效。
现在我想在 PuLP 中模拟同样的问题。我想我需要的是这样的想法:
for Element in ELEMENTS:
prob += lpSum(DecisionVariable[Concentrate]*dic[Element][Concentrate]/ MaxAmount[Element] for Concentrate in CONCENTRATES)
其中 ELEMENTS 是一个包含所有元素的列表,CONCENTRATES 是一个列表 从 0 到 100 的值和 dic[Element][Concentrate] 存储每个元素及其所有浓缩物的值。
现在使用上面的代码,objective 函数在每个循环中都被覆盖。我不需要覆盖旧的 objective 函数,而是需要类似 append() 或类似的东西来将每个 loops=lpSums 添加到我的 prob 变量?class?
总的来说,我对编程还比较陌生,我想我的问题更多是因为我缺乏 python 编程技能,而不是我(也缺乏 :D)PuLP 技能。但是我在 PuLP documentation 中找不到任何东西,至少没有我可以连接到的东西。
编辑:包括一个小 table 来展示问题:
+------------------------------+-------------------------------------------+----+------------------------------+---------------+----------------------+---------------+---------------+-------------------------------+
| Utilization [%] | Sumproduct[Quantity] = [LHS] | | Constrains[Quantity] = [RHS] | Concentrate | Element 1 [%] | Element 2 [%] | Element 3 [%] | Decision Variables [Quantity] |
+------------------------------+-------------------------------------------+----+------------------------------+---------------+----------------------+---------------+---------------+-------------------------------+
| u1 = z1 / MaxAmount Element1 | z1 = Col Element1 * Col Decison Variables | <= | MaxAmount Element1 | Concentrate 1 | % Element 1 in Con 1 | | | X1 |
| u2 = z2 / MaxAmount Element2 | z2 = Col Element2 * Col Decison Variables | <= | MaxAmount Elemen2 | Concentrate 2 | % Element 1 in Con 2 | | | X2 |
| u3 = z3 / MaxAmount Element3 | z3 = Col Element3 * Col Decison Variables | <= | MaxAmount Elemen3 | Concentrate 3 | % Element 1 in Con 3 | | | X3 |
+------------------------------+-------------------------------------------+----+------------------------------+---------------+----------------------+---------------+---------------+-------------------------------+
"Element 2" 和 "Element 3" 列存储与 "Element 1" 列相同的信息:各元素在 Concentrate 1/2/3 中的百分比份额。
objective 函数是最大化所有利用率 (u1+u2+u3) 的总和。所以我试图确定我应该使用多少浓缩物,尽可能多地利用每个元素的给定限制。回到我的 PuLp 代码,我想我可以将 "u1" 的等价物添加到我的 PuLp "LpProblem Class",但我不知道如何将这些 LpSums 中的多个添加到我的 [=37] =] 在循环中。
这是一个版本,带有用于说明目的的虚拟数据。看看对你有没有帮助。
import pulp
from pulp import *
ELEMENTS = ['Iron', 'Mercury', 'Silver']
Max_Per_Elem = {'Iron': 35,
'Mercury': 17,
'Silver': 28
}
# A dictionary of the Iron percent in each of the CONCs
IronPercent = {'CONC_1': 20, 'CONC_2': 10, 'CONC_3': 25}
# A dictionary of the Hg percent in each of the CONCs
MercPercent = {'CONC_1': 15, 'CONC_2': 18, 'CONC_3': 12}
# A dictionary of the Silver percent in each of the CONCs
SilverPercent = {'CONC_1': 30, 'CONC_2': 40, 'CONC_3': 20}
CONCENTRATE_DIC = {'Iron': IronPercent,
'Mercury': MercPercent,
'Silver': SilverPercent
}
# Creates a list of Decision Variables
concs = ['CONC_1', 'CONC_2', 'CONC_3']
现在,我们可以调用 puLP
函数了。
conc_vars = LpVariable.dicts("Util", concs, 0, 1.0)
# Create the 'prob' variable to contain the problem data
prob = LpProblem("Elements Concentration Problem", LpMaximize)
# The objective function
prob += lpSum([conc_vars[i] for i in concs]), "Total Utilization is maximized"
for elem in ELEMENTS:
prob += lpSum([CONCENTRATE_DIC[elem][i]/Max_Per_Elem[elem] * conc_vars[i] for i in concs]) <= Max_Per_Elem[elem]/100, elem+"Percent"
为了验证,您可以打印 prob
以查看其外观:
Elements Concentration Problem:
MAXIMIZE
1*Util_CONC_1 + 1*Util_CONC_2 + 1*Util_CONC_3 + 0
SUBJECT TO
IronPercent: 0.571428571429 Util_CONC_1 + 0.285714285714 Util_CONC_2
+ 0.714285714286 Util_CONC_3 <= 0.35
MercuryPercent: 0.882352941176 Util_CONC_1 + 1.05882352941 Util_CONC_2
+ 0.705882352941 Util_CONC_3 <= 0.17
SilverPercent: 1.07142857143 Util_CONC_1 + 1.42857142857 Util_CONC_2
+ 0.714285714286 Util_CONC_3 <= 0.28
VARIABLES
Util_CONC_1 <= 1 Continuous
Util_CONC_2 <= 1 Continuous
Util_CONC_3 <= 1 Continuous
对公式满意后,解决问题。
prob.writeLP("ElemUtiliztionModel.lp")
prob.solve()
print("Status:", LpStatus[prob.status])
for v in prob.variables():
print(v.name, "=", v.varValue)
得到,
Status: Optimal
Util_CONC_1 = 0.0
Util_CONC_2 = 0.0
Util_CONC_3 = 0.24083333
希望能帮助您前进。