将Excel解算器解决方案转换为Python纸浆

时间:2017-08-21 16:04:30

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

我发现很难将Excel Solver模型转换为python pulp语法。 在我的模型中,我正在优化每个部门的HC和OT变量,目标是最小化OT变量的总和。约束条件要求HC变量总和不超过92,并且总生产量(下面的电子表格中=E2*C2*D2 + F2*C2)符合每个部门的要求(excel电子表格的"输入"列)下面)。下面显示的Excel求解器公式非常有效。

问题

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

    enter image description here

    解决之后

    enter image description here

    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)
    

1 个答案:

答案 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]