使用列表在 python pulp 中加载数据

Load data in python pulp using lists

我有以下python纸浆代码:

import pulp

# Create a LP Minimization problem
Lp_prob = pulp.LpProblem('Problem', pulp.LpMaximize)

# Create problem Variables
a01 = pulp.LpVariable("a01", 0, 1, cat="Integer")  # Create a variable x >= 0
x31 = pulp.LpVariable("x31", 0, 1, cat="Integer")  # Create a variable x >= 0
c97 = pulp.LpVariable("c97", 0, 1, cat="Integer")  # Create a variable x >= 0
ab12 = pulp.LpVariable("ab12", 0, 1, cat="Integer")  # Create a variable x >= 0
eaz = pulp.LpVariable("eaz", 0, 1, cat="Integer")  # Create a variable x >= 0
f12 = pulp.LpVariable("f12", 0, 1, cat="Integer")  # Create a variable x >= 0

# Objective Function
Lp_prob += 100*a01 + 110*x31 + 150*c97 + 90*ab12 + 50*eaz + 60*f12

# Constraints:
Lp_prob += 3*a01 + 10*x31 + 10*c97 + 2*ab12 + 4*eaz + 6*f12 <= 25
Lp_prob += 4*a01 + 9*x31 + 3*c97 + 9*ab12 + 1*eaz + 4*f12 <= 21
Lp_prob += 6*a01 + 2*x31 + 9*c97 + 4*ab12 + 5*eaz + 5*f12 <= 22
Lp_prob += 10*a01 + 4*x31 + 10*c97 + 8*ab12 + 8*eaz + 9*f12 <= 34

# Display the problem
print(Lp_prob)

status = Lp_prob.solve()  # Solver
print(pulp.LpStatus[status])  # The solution status

# Printing the final solution
print(pulp.value(a01), pulp.value(x31), pulp.value(c97), pulp.value(ab12),
      pulp.value(eaz), pulp.value(f12), pulp.value(Lp_prob.objective))

我想做的是:

1-) 在列表中加载 a01、x31、c97、ab12、eaz、f12,然后将它们加载到 pulp 中。原因是此列表将包含大约 20,000 个项目。它会将 #Create 问题变量减少到一两行代码。

2-) 加载列表中的所有约束编号,并将它们加载到 pulp 中。原因是此列表将包含大约 1,000 个项目。它会将#Constraint 减少到一两行代码。

3-) 也将纸浆溶液列入列表。

原矩阵为:

                    p   q   r   s   Revenue
                a   3   4   6   10  100 
                b   10  9   2   4   110 
                c   10  3   9   10  150 
                d   2   9   4   8   90 
                e   4   1   5   8   50 
                f   6   4   5   9   60 
Quantity available  25  21  22  34   

您可以使用 for 循环和 pulp.lpSum 方法的组合来完成您想要的:

import pulp
import pandas as pd 

# List of tuples
names = ['a01', 'x31', 'c97', 'ab12', 'eaz', 'f12']

data = [(3,  4,  6,  10, 100),
        (10, 9,  2,  4,  110),
        (10, 3,  9,  10, 150),
        (2,  9,  4,  8,  90),
        (4,  1,  5,  8,  50),
        (6,  4,  5,  9,  60)]

qty = [25, 21, 22, 34]

# Create DataFrame object from list of tuples
data_frame = pd.DataFrame(data,
                          columns=['p' , 'q', 'r' , 's', 'rev'],
                          index=names)

# Create a LP Minimization problem
Lp_prob = pulp.LpProblem('Problem', pulp.LpMaximize)

# Create problem Variables
list_of_vars = [pulp.LpVariable(name, 0, 1, cat="Integer") for name in names]

# Objective Function
Lp_prob += pulp.lpSum([data_frame.rev[i]*list_of_vars[i] for i in range(len(data_frame))])

# Constraints:
for i in range(len(qty)):
    Lp_prob += pulp.lpSum([data_frame.iloc[j,i] * list_of_vars[j]
                            for j in range(len(list_of_vars))]) <= qty[i]

# Display the problem
print(Lp_prob)

status = Lp_prob.solve()        # Solver
print(pulp.LpStatus[status])    # The solution status

# Printing all the vars:
for v in Lp_prob.variables ():
    print (v.name, "=", v.varValue)

如果您的数据发生变化并允许您添加新的物料清单、项目、比例等,此方法将起作用。您只需将您的 csv 映射到 boms 列表:

编辑:添加了 csv 加载,我的 csv 看起来像这样,但您可以更改列 headers 或交换您的实际数据,它们只需要匹配 available_parts 键。

csv 格式:

import csv
import pulp

def open_csv(path):
    '''return a list of dictionaries
    '''
    with open(path, 'r') as file:
        reader = csv.DictReader(file)
        return [dict(row) for row in reader]

# load the bom item data
boms = open_csv('./boms.csv')

# define the available parts, these will be matched with columns from the csv so they must match
available_parts = {'p': 25, 'q': 21, 'r': 22, 's': 34}

# {LpVariable: item} dictionary for easy referencing later
variables = {pulp.LpVariable(i['name'], 0, 1, cat='Integer'): i
             for i in boms}

prob = pulp.LpProblem('Problem', pulp.LpMaximize)

# add variable*revenue for each variable (dict we creted earlier makes this easier)
prob += pulp.lpSum([variable * float(item['revenue'])
                    for variable, item in variables.items()])


for part, amount in available_parts.items():
    # lp_sum of the boms each part in the available parts list
    maximum = pulp.lpSum([float(bom[part]) * prob.variablesDict()[bom['name']]
                          for bom in boms])
    # add the part
    prob += maximum <= amount, f'max_{part}'

# Display the problem
print(prob)

status = prob.solve()  # Solver
print(pulp.LpStatus[status])  # The solution status

# Printing the final solution


output = {v.name: v.varValue for v in prob.variables()}
print(output)

输出:

Problem:
MAXIMIZE
100*a01 + 90*ab12 + 150*c97 + 50*eaz + 60*f12 + 110*x31 + 0
SUBJECT TO
max_p: 3 a01 + 2 ab12 + 10 c97 + 4 eaz + 6 f12 + 10 x31 <= 25

max_q: 4 a01 + 9 ab12 + 3 c97 + eaz + 4 f12 + 9 x31 <= 21

max_r: 6 a01 + 4 ab12 + 9 c97 + 5 eaz + 5 f12 + 2 x31 <= 22

max_s: 10 a01 + 8 ab12 + 10 c97 + 8 eaz + 9 f12 + 4 x31 <= 34

VARIABLES
0 <= a01 <= 1 Integer
0 <= ab12 <= 1 Integer
0 <= c97 <= 1 Integer
0 <= eaz <= 1 Integer
0 <= f12 <= 1 Integer
0 <= x31 <= 1 Integer

Optimal
{'a01': 1.0, 'ab12': 0.0, 'c97': 1.0, 'eaz': 0.0, 'f12': 0.0, 'x31': 1.0}
360.0