简体   繁体   English

PuLP:目标功能:在循环中添加多个lpSum

[英]PuLP: Objective Function: Adding multiple lpSum in a loop

I am trying to use PuLp for a Blending problem with different Elements (Iron, Mercury..). 我正在尝试使用PuLp解决具有不同元素(铁,水银..)的混合问题。 But instead of max/min some profit/cost I need to maximize the utilization of my constraints. 但是我需要最大化约束的利用率,而不是最大化/最小化某些利润/成本。 So in Excel I had something like this (in pseudocode): 因此,在Excel中,我有类似以下内容(使用伪代码):

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

I never used an objective function like this but it seems to work in Excel. 我从未使用过这样的目标函数,但它似乎可以在Excel中工作。

Now I want to model the same problem in PuLP. 现在,我想在PuLP中建模相同的问题。 I think what I would need is somethink like this: 我认为我需要这样的想法:

for Element in ELEMENTS:
    prob += lpSum(DecisionVariable[Concentrate]*dic[Element][Concentrate]/ MaxAmount[Element] for Concentrate in CONCENTRATES)

Where ELEMENTS is a List containing all Elements, CONCENTRATES is a List of Values from 0 to 100 and dic[Element][Concentrate] stores the values from each Element and all its concentrates. 其中ELEMENTS是包含所有Elements的列表,CONCENTRATES是从0到100的值的列表,并且dic [Element] [Concentrate]存储每个Element及其所有集中的值。

Now with the code above, the objective function is overwritten in each loop. 现在,使用上面的代码,目标函数在每个循环中都将被覆盖。 Instead of overwriting the old objective function I'd need something like append() or alike to add each of the loops=lpSums to my prob variable?class? 而不是覆盖旧的目标函数,我需要诸如append()之类的东西来将每个loops = lpSums添加到我的问题变量中?

I am rather new to programming in general and I guess my problem is more related to my lack of python programming skills than my (also lacking :D) PuLP skills. 我一般对编程都不熟悉,我想我的问题更多是由于我缺少python编程技能而不是我(也缺少:D)PuLP技能引起的。 But I could not find anything in the PuLP documentation , atleast nothing I could connect it to. 但是我在PuLP文档中找不到任何东西,至少没有我可以连接的东西。

Edit: Included a small table to showcase the problem: 编辑:包括一张小桌子来展示此问题:

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

The columns "Element 2" and "Element 3" store the same information as the column "Element 1": the % share of the respective Element in Concentrate 1/2/3. 列“元素2”和“元素3”存储与列“元素1”相同的信息:浓度1/2/3中各个元素的%份额。

The objective function is to maximize the sum over all utilizations (u1+u2+u3). 目标函数是在所有利用率(u1 + u2 + u3)上最大化总和。 So I am trying to determine how much of each concentrate I should use, to utilize as much of the given constraints for each element, as possible. 因此,我试图确定我应该使用每种浓缩物的多少,以尽可能多地利用每个元素的给定约束。 Coming back to my PuLp code, I think I am able to add the equivalent of "u1" to my PuLp "LpProblem Class", but I can't figure out how to add multiple of these LpSums to my "LpProblem Class" in a loop. 回到我的PuLp代码,我想我可以在我的PuLp“ LpProblem Class”中添加等价的“ u1”,但我不知道如何在其中将多个LpSums添加到我的“ LpProblem Class”中。环。

Here' one version, with dummy data for illustrative purposes. 这是一种版本,其中以虚拟数据为例。 See if this helps you. 看看这是否对您有帮助。

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']

Now, we are ready to call puLP functions. 现在,我们准备调用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"

To verify, you can print the prob to see what it looks like: 要进行验证,您可以打印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

Once you are happy with the formulation, solve the problem. 对配方满意后,即可解决问题。

prob.writeLP("ElemUtiliztionModel.lp")
prob.solve()
print("Status:", LpStatus[prob.status])
for v in prob.variables():
    print(v.name, "=", v.varValue)

To get, 要得到,

Status: Optimal
Util_CONC_1 = 0.0
Util_CONC_2 = 0.0
Util_CONC_3 = 0.24083333

Hope that helps you move forward. 希望能帮助您前进。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM