Progtwigción lineal (Simplex LP) PuLP?

Solo en Python, y usando datos de un dataframe de Pandas, ¿cómo puedo usar PuLP para resolver problemas de progtwigción lineal de la misma manera que puedo hacerlo en Excel? ¿Cuánto presupuesto debe asignarse a cada canal en la columna Nuevo presupuesto para que maximicemos el número total de éxitos estimados? Realmente estoy buscando un ejemplo concreto utilizando datos de un dataframe y no consejos de alto nivel.

Configuración de datos del problema

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 

Este es un problema de maximización .

La función objective es:

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

Las restricciones son:

  1. La sum de df['New Budget'] debe ser igual a 5000
  2. El New Budget para un canal determinado no puede ir más bajo que el Cost Min
  3. El New Budget para un canal determinado no puede ir más alto que el Cost Max

¿Alguna idea de cómo traducir este problema lineal del solucionador de datos de pandas usando PuLP o cualquier otro enfoque de solucionador? El resultado final sería lo que ves en la imagen de abajo.

Resultado deseado

En general, crea un diccionario de variables ( x en este caso) y una variable de modelo ( mod en este caso). Para crear el objective, use la sum sobre las variables multiplicadas por algunos escalares, agregando ese resultado a mod . Usted construye restricciones calculando nuevamente las combinaciones lineales de variables, usando >= , <= , o == , y agregando esa restricción a mod . Finalmente usas mod.solve() para obtener las soluciones.

 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 

Datos:

 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