【问题标题】:Converting Excel Solver Solution to Python Pulp将 Excel Solver 解决方案转换为 Python Pulp
【发布时间】:2017-08-21 16:04:29
【问题描述】:

我发现很难将 Excel Solver 模型转换为 python 纸浆语法。 在我的模型中,我正在优化每个部门的 HC 和 OT 变量,目标是最小化 OT 变量的总和。约束要求 HC 变量的总和不超过 92,并且总产量(下面的电子表格中的=E2*C2*D2 + F2*C2)满足每个部门的要求(下面的 excel 电子表格的“输入”列)。下面显示的 Excel 求解器公式完美运行。

问题

  1. 如何在纸浆中编写我的目标函数(在 Excel F7 =SUM(F2:F6))?
  2. 约束 E7
  3. 约束G2:G6 >= B2:B6
  4. 我有两个决策变量 HCOT。在下面的 python 代码中,我只创建了一个变量。

之前

求解器之后

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)

【问题讨论】:

    标签: python math mathematical-optimization linear-programming pulp


    【解决方案1】:

    您发布的 Pulp 代码存在一些问题。

    您只声明了一组变量 x,但您的 Excel 公式中有两组变量 HC 和 OT。您应该声明两组不同的变量,并适当地命名它们:

    HC = pulp.LpVariable.dicts("HC", df.index, lowBound=0)
    OT = pulp.LpVariable.dicts("OT", df.index, lowBound=0)
    

    当您将目标添加为mod += sum(df['OT']) 时,您试图将数据框的一列添加到模型中,这会导致错误。相反,您想添加 OT 变量的总和,这可以通过以下方式实现:

    mod += sum([OT[idx] for idx in df.index])
    

    当您添加约束 x[idx] &lt;= df['Input'][idx] 时,您要求您的 x 变量是输入数据的上限。然而,实际上你有一个更复杂的约束——请注意,在 excel 代码中,你的输入列下界 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]
    

    将所有这些放在一起会产生所需的输出:

    import pulp
    import pandas as pd
    
    # Problem data
    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([11346, 13011, 2715, 13682, 14194], index=idx)}
    df = pd.DataFrame(d)
    
    # Create variables and model                                                                                                 
    HC = pulp.LpVariable.dicts("HC", df.index, lowBound=0)
    OT = pulp.LpVariable.dicts("OT", df.index, lowBound=0)
    mod = pulp.LpProblem("OTReduction", pulp.LpMinimize)
    
    # Objective function                                                                                                         
    mod += sum([OT[idx] for idx in df.index])
    
    # Lower and upper bounds:                                                                                                    
    for idx in df.index:
        mod += df['Target'][idx] * df['Hrs/day'][idx] * HC[idx] + df['Target'][idx] * OT[idx] >= df['Prod'][idx]
    
    # Total HC value should be less than or equal to 92                                                                          
    mod += sum([HC[idx] for idx in df.index]) <= 92
    
    # Solve model                                                                                                                
    mod.solve()
    
    # Output solution                                                                                                            
    for idx in df.index:
        print(idx, HC[idx].value(), OT[idx].value())
    # 0 24.0 0.0
    # 1 13.241236 35.795316
    # 2 10.947581 0.0
    # 3 28.022529 0.0
    # 4 15.788654 0.0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多