线性规划(Simplex LP)PuLP?
Linear Programming (Simplex LP) PuLP?
仅在 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函数是:
objective_function = sum((df['New Budget']/(df['30-day Cost']/df['Trials']))*(df['Success']/df['Trials']))
约束是:
df['New Budget']
的总和必须等于 5000
- 给定频道的
New Budget
不能比 Cost Min
低
- 给定频道的
New Budget
不能比 Cost Max
高
关于如何使用 PuLP 或任何其他求解器方法翻译此 pandas 数据帧求解器线性问题有什么想法吗?最终结果将是您在下图中看到的。
通常,您会创建一个变量字典(在本例中为x
)和一个模型变量(在本例中为mod
)。要创建 objective,您使用 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
仅在 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函数是:
objective_function = sum((df['New Budget']/(df['30-day Cost']/df['Trials']))*(df['Success']/df['Trials']))
约束是:
df['New Budget']
的总和必须等于5000
- 给定频道的
New Budget
不能比Cost Min
低
- 给定频道的
New Budget
不能比Cost Max
高
关于如何使用 PuLP 或任何其他求解器方法翻译此 pandas 数据帧求解器线性问题有什么想法吗?最终结果将是您在下图中看到的。
通常,您会创建一个变量字典(在本例中为x
)和一个模型变量(在本例中为mod
)。要创建 objective,您使用 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