PuLP:目标函数:在循环中添加多个 lpSum

Posted

技术标签:

【中文标题】PuLP:目标函数:在循环中添加多个 lpSum【英文标题】:PuLP: Objective Function: Adding multiple lpSum in a loop 【发布时间】:2018-12-28 11:58:20 【问题描述】:

我正在尝试使用 PuLp 解决与不同元素(铁、汞......)的混合问题。但是,我需要最大限度地利用我的约束,而不是最大化/最小化一些利润/成本。所以在 Excel 中我有这样的东西(在伪代码中):

max Sum (for each Element: (Sumproduct([DecisionVariables] * [Values]) / [MaximumAllowedValueForThisElement]))

我从未使用过这样的目标函数,但它似乎在 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] 存储来自每个元素及其所有浓缩物的值。

现在使用上面的代码,目标函数在每个循环中都会被覆盖。我不需要覆盖旧的目标函数,而是需要 append() 之类的东西来将每个 loops=lpSums 添加到我的 prob 变量?类?

总的来说,我对编程比较陌生,我想我的问题更多地与我缺乏 python 编程技能有关,而不是我(也缺乏 :D)PuLP 技能。但我在PuLP documentation 中找不到任何东西,至少我无法连接到它。

编辑:包括一个小表格来展示问题:

+------------------------------+-------------------------------------------+----+------------------------------+---------------+----------------------+---------------+---------------+-------------------------------+
|       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                            |
+------------------------------+-------------------------------------------+----+------------------------------+---------------+----------------------+---------------+---------------+-------------------------------+

“元素 2”和“元素 3”列存储与“元素 1”列相同的信息:各元素在浓缩物 1/2/3 中的百分比份额。

目标函数是最大化所有利用率的总和(u1+u2+u3)。所以我试图确定我应该使用多少每种浓缩物,尽可能多地利用每个元素的给定约束。回到我的 PuLp 代码,我想我可以将相当于“u1”的内容添加到我的 PuLp“LpProblem 类”中,但我不知道如何将这些 LpSum 中的多个添加到我的“LpProblem 类”中环形。

【问题讨论】:

你好 JanB。您还可以张贴一张小表格,显示可能 3 种元素和它们的一些浓缩物吗?什么是决策变量,您试图最大化哪种利用率?如果你用英语解释,人们可以尝试用 PuLP 帮助你。谢谢 嗨@Ram Narasimhan!谢谢你看我的问题!我在原始帖子中附上了一张小表格,希望这有助于澄清我想用我的 PuLp 代码实现的目标。最好的问候,简 我创建了一些虚拟数据来说明循环结合字典和 lpSum 的使用。希望它可以帮助你。有什么不清楚的就问吧。 【参考方案1】:

这里有一个版本,带有用于说明目的的虚拟数据。看看这对你有没有帮助。

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

希望能帮助你前进。

【讨论】:

嘿@Ram Narasimhan,很抱歉这么晚才回复。但你的大纲确实帮助我解决了我的问题。非常感谢! @Ram 字典 conc_vars 中的“Util”是什么意思?从哪里得到它以及为什么在编写时使用它( conc_vars = LpVariable.dicts("Util", concs, 0, 1.0) ) Utils_CONC_x 是问题的决策变量。请参阅 OP 提供的定义。我没有从任何地方得到它,我正在定义它,LP 将为所有 3 个实用程序分配值,以便最大化目标函数。它是混合物中每种 CONC 的量。

以上是关于PuLP:目标函数:在循环中添加多个 lpSum的主要内容,如果未能解决你的问题,请参考以下文章

PuLP:规范化多个决策变量并分配权重

Python数模笔记-PuLP库线性规划入门

Python数模笔记-PuLP库线性规划进阶

js的replace如何全部替换目标字符串

Day03---集合,函数,三目运算,lambda表达式,内置函数,文件操作

使用 SSIS 将数据加载到 SQL Server 中的多个表