【问题标题】:Linear Programming (Simplex LP) PuLP?线性规划(单纯形 LP) 纸浆?
【发布时间】:2016-01-14 14:29:04
【问题描述】:

仅在 Python 中,并使用来自 Pandas 数据框的数据,我如何使用PuLP 来解决线性规划问题,就像在 Excel 中一样?应该为“新预算”列下的每个渠道分配多少预算,以便我们最大化估计的成功总数?我真的在寻找一个具体的example,使用来自数据框的数据,而不是真正的高级建议。

问题数据设置

    Channel  30-day Cost  Trials  Success  Cost Min  Cost Max  New Budget
0  Channel1      1765.21    9865      812    882.61   2647.82           0
1  Channel2      2700.00   15000      900   1350.00   4050.00           0
2  Channel3      2160.00   12000      333   1080.00   3240.00           0

这是一个最大化问题。

目标函数是:

objective_function = sum((df['New Budget']/(df['30-day Cost']/df['Trials']))*(df['Success']/df['Trials']))

约束是:

  1. df['New Budget'] 之和必须等于5000
  2. 给定频道的New Budget 不能低于Cost Min
  3. 给定频道的New Budget 不能高于Cost Max

任何想法如何使用 PuLP 或任何其他求解器方法来翻译这个 pandas 数据帧求解器线性问题?最终结果将如下图所示。

【问题讨论】:

    标签: python pandas dataframe linear-programming pulp


    【解决方案1】:

    通常,您会创建一个变量字典(在本例中为x)和一个模型变量(在本例中为mod)。要创建目标,您可以在变量乘以一些标量时使用sum,然后将该结果添加到mod。您可以通过使用>=<=== 再次计算变量的线性组合来构造约束,并将该约束添加到mod。最后你使用mod.solve() 来获得解决方案。

    import pulp
    
    # Create variables and model
    x = pulp.LpVariable.dicts("x", df.index, lowBound=0)
    mod = pulp.LpProblem("Budget", pulp.LpMaximize)
    
    # Objective function
    objvals = {idx: (1.0/(df['30-day Cost'][idx]/df['Trials'][idx]))*(df['Success'][idx]/float(df['Trials'][idx])) for idx in df.index}
    mod += sum([x[idx]*objvals[idx] for idx in df.index])
    
    # Lower and upper bounds:
    for idx in df.index:
        mod += x[idx] >= df['Cost Min'][idx]
        mod += x[idx] <= df['Cost Max'][idx]
    
    # Budget sum
    mod += sum([x[idx] for idx in df.index]) == 5000.0
    
    # Solve model
    mod.solve()
    
    # Output solution
    for idx in df.index:
        print idx, x[idx].value()
    # 0 2570.0
    # 1 1350.0
    # 2 1080.0
    
    print 'Objective', pulp.value(mod.objective)
    # Objective 1798.70495012
    

    数据:

    import numpy as np
    import pandas as pd
    idx = [0, 1, 2]
    d = {'channel': pd.Series(['Channel1', 'Channel2', 'Channel3'], index=idx),
         '30-day Cost': pd.Series([1765.21, 2700., 2160.], index=idx),
         'Trials': pd.Series([9865, 1500, 1200], index=idx),
         'Success': pd.Series([812, 900, 333], index=idx),
         'Cost Min': pd.Series([882.61, 1350.00, 1080.00], index=idx),
         'Cost Max': pd.Series([2647.82, 4050.00, 3240.00], index=idx)}
    df = pd.DataFrame(d)
    df
    #    30-day Cost  Cost Max  Cost Min  Success  Trials   channel
    # 0      1765.21   2647.82    882.61      812    9865  Channel1
    # 1      2700.00   4050.00   1350.00      900    1500  Channel2
    # 2      2160.00   3240.00   1080.00      333    1200  Channel3
    

    【讨论】:

    • 在同一个例子中,如果我有两个变量怎么办。例如:目前,如果想要 $G$2:$H$6 之类的东西来更改纸浆中的变量,则可以使用 $G$2:$G$4。
    • @josliber,我很好奇,你为什么在目标函数中使用1.0 而OP 使用df['New Budget']?那是因为df['New Budget'] 是可变单元格吗​​?我试图将此映射到我自己的问题,但无法弄清楚将变量单元格放在哪里。谢谢!
    • @tmthyjames 我正在使用1.0/(df['30-day Cost'][idx]/df['Trials'][idx]))*(df['Success'][idx]/float(df['Trials'][idx]),因为这是 OP 在他们的 excel 电子表格中的目标函数。如果您有不同的公式,那么您可以使用它。
    • 嗨@josliber,我可以通过邮件与您联系吗?我有一个类似的问题想讨论。如果您能帮助我,将不胜感激。谢谢。请检查一下:stackoverflow.com/questions/49194399/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 2022-01-10
    • 2022-06-11
    • 2023-03-09
    • 1970-01-01
    • 2020-11-14
    相关资源
    最近更新 更多