线性编程(Simplex LP)PuLP?

发布于 2021-01-29 16:13:43

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

问题数据设置

    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或任何其他求解器方法转换此熊猫数据框求解器线性问题?最终结果将是您在下图中看到的结果。

所需结果

关注者
0
被浏览
46
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    通常,您将创建一个变量字典(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
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看