我发现很难将Excel Solver模型转换为python pulp语法。
在我的模型中,我正在优化每个部门的HC和OT变量,目标是最小化OT变量的总和。约束条件要求HC变量总和不超过92,并且总生产量(下面的电子表格中=E2*C2*D2 + F2*C2
)符合每个部门的要求(excel电子表格的"输入"列)下面)。下面显示的Excel求解器公式非常有效。
问题
之前
解决之后
import pulp
import numpy as np
import pandas as pd
idx = [0, 1, 2, 3, 4]
d = {'Dept': pd.Series(['Receiving', 'Picking', 'PPicking', 'QC', 'Packing'], index=idx),
'Target': pd.Series([61,94,32,63,116], index=idx),
'Hrs/day': pd.Series([7.75, 7.75, 7.75, 7.75, 7.75], index=idx),
'Prod': pd.Series([11733, 13011, 2715, 13682, 14194], index=idx),
'HC': pd.Series([24,18,6,28,16], index=idx),
'OT': pd.Series([0,0,42,0,0], index=idx)}
df = pd.DataFrame(d)
# Create variables and model
x = pulp.LpVariable.dicts("x", df.index, lowBound=0)
mod = pulp.LpProblem("OTReduction", pulp.LpMinimize)
# Objective function
mod += sum(df['OT'])
# Lower and upper bounds:
for idx in df.index:
mod += x[idx] <= df['Input'][idx]
# Total HC value should be less than or equal to 92
mod += sum([x[idx] for idx in df.index]) <= 92
# Solve model
mod.solve()
# Output solution
for idx in df.index:
print idx, x[idx].value()
# Expected answer
# HC, OT
# 19, 35.795
# 18, 0
# 11, 0
# 28, 0
# ----------------
# 92, 35.795 -> **note:** SUM(HC), SUM(OT)
答案 0 :(得分:5)
您发布的纸浆代码存在一些问题。
您只声明一组变量.claro .dojoxGridRowTable tr {
background-image : url("...") !important;
background-repeat : repeat-x !important;
background-attachment :scroll !important;
background-clip:border-box !important;
background-origin:padding-box !important;
background-size:auto auto !important;
}
,但您的excel公式中有两组,即HC和OT。您应该声明两组不同的变量,并对它们进行适当的命名:
x
当您将目标添加为HC = pulp.LpVariable.dicts("HC", df.index, lowBound=0)
OT = pulp.LpVariable.dicts("OT", df.index, lowBound=0)
时,您试图将一列数据框添加到模型中,这会导致错误。相反,您想要添加OT变量的总和,这可以通过以下方式实现:
mod += sum(df['OT'])
当您添加约束mod += sum([OT[idx] for idx in df.index])
时,您要求您的x[idx] <= df['Input'][idx]
变量在输入数据的上限。但实际上你有一个更复杂的约束 - 注意在excel代码中,你是输入列的下限x
。这里的约束应该表现出相同的逻辑:
E2*C2*D2 + F2*C2
将所有这些放在一起产生所需的输出:
for idx in df.index:
mod += df['Target'][idx] * df['Hrs/day'][idx] * HC[idx] + df['Target'][idx] * OT[idx] >= df['Prod'][idx]