2015-10-15 2 views
4

Только в Python и используя данные из фрейма Pandas, как я могу использовать PuLP для решения задач линейного программирования так же, как я могу в Excel? Какой бюджет должен быть выделен каждому каналу в колонке «Новый бюджет», чтобы мы максимально увеличили общее количество оценочных успехов? Я действительно ищу конкретный пример , используя данные из dataframe и не очень совет высокого уровня.Линейное программирование (Simplex LP) PuLP?

Настройка Проблема данных

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

Любые идеи, как перевести эту панд dataframe решатель линейной задачи, используя Pulp или любой другой решатель подход? Конечным результатом будет то, что вы видите на изображении ниже.

Desired result

ответ

7

В общем создании словаря переменных (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 
+0

В том же примере, что если у меня есть две переменные. Например, в настоящее время $ G $ 2: $ G $ 4 существует, если требуется что-то вроде $ G $ 2: $ H $ 6 как изменение переменной в целлюлозе. –

+0

@josliber, мне любопытно, почему вы используете '1.0' в своей целевой функции, где OP использует' df ['New Budget'] '? Это потому, что 'df ['New Budget']' являются ячейками переменных? Я пытаюсь сопоставить это с моей собственной проблемой, но не могу понять, где разместить мои переменные ячейки. Благодаря! – tmthyjames

+0

@tmthyjames Я использую '1.0/(df ['30 -day Cost '] [idx]/df [' Trials '] [idx])) * (df [' Success '] [idx]/float (df [ 'Trials'] [idx]) ', потому что это целевая функция OP из их таблицы Excel. Если у вас есть другая формула, вы должны использовать это вместо этого. – josliber

Смежные вопросы