Distribution of pharma

Try me

Open In ColabBinder

Problem Definition

The US Department of Energy conducts a series of experiments in two research facilities located in Hawkins (Atlanta) and Los Angeles. The department needs to supply these facilities with pharma products that are processed in two factories in Portland and Flint. The delivery costs are summarised in the following table:

Production plants

Research Facilities

Delivery costs

Portland

Los Angeles

€30

Portland

Hawkins

€40

Flint

Los Angeles

€60

Flint

Hawkins

€50

The supply and demand data is provided in the table below:

Supply

Available units

Demand

Required units

Portland

200

Los Angeles

300

Flint

600

Hawkins

400

Implement an MILP that determines how to supply the two research facilities at minimum cost.

Problem Model

\(X_{11}\) = Units delivered from Portland to Los Angeles.

\(X_{12}\) = Units delivered from Portland to Hawkins.

\(X_{21}\) = Units delivered from Flint to Los Angeles.

\(X_{22}\) = Units delivered from Flint to Hawkins. Objective function:

Minimize \(z = 30X_{11} + 40X_{12} + 60X_{21} + 50X_{22}\)

Constraints:

\(X_{11} + X_{12} \leq 200\) Supply from Portland

\(X_{21} + X_{22} \leq 600\) Supply from Flint

\(X_{11} + X_{21} \geq 300\) Demand in Los Angeles

\(X_{12} + X_{22} \geq 400\) Demand in Hawkins

All variables are Integer and greater or equal than zero.

Solution in Python

The following scripts implement the problem model and solve it using Python.

Requirements

Install the following requirements first

[ ]:
!pip install pandas
!pip install pulp
!pip install IPython
[7]:
import pandas as pd
import pulp
import numpy as np
from IPython.display import display, Markdown
[14]:
# Instantiate our problem class
model = pulp.LpProblem("Cost minimising problem", pulp.LpMinimize)
[15]:
# Construct our decision variable lists
supply = ['Portland', 'Flint']
demand = ['Los Angeles', 'Hawkins']


variables = pulp.LpVariable.dicts("units ",
                                     ((i, j) for i in supply for j in demand),
                                     lowBound=0,
                                     cat='Integer')

#coefficients
coefficients = {}
coefficients['Portland', 'Los Angeles'] = 30
coefficients['Portland', 'Hawkins'] = 40
coefficients['Flint', 'Los Angeles'] = 60
coefficients['Flint', 'Hawkins'] = 50

# Objective Function
model += (
    pulp.lpSum([
        coefficients[(i,j)] * variables[(i, j)]
        for i in supply for j in demand])
)

#Constraints
model += pulp.lpSum([variables['Portland', j] for j in demand]) <= 200, "Supply From Portland"
model += pulp.lpSum([variables['Flint', j] for j in demand]) <= 600, "Supply From Flint"

model += pulp.lpSum([variables[i, 'Los Angeles'] for i in supply]) >= 300, "Demand in Los Angeles"
model += pulp.lpSum([variables[i, 'Hawkins'] for i in supply]) >= 400, "Demand in Hawkins"

[16]:
# Solve our problem
model.solve()
pulp.LpStatus[model.status]
[16]:
'Optimal'
[17]:
total_cost = pulp.value(model.objective)
display(Markdown("Total cost is %0.2f €"%total_cost))

display(Markdown("The following table shows the decision variables: "))
var_df = pd.DataFrame.from_dict(variables, orient="index",
                                columns = ["Variables"], dtype=object)

var_df["Solution"] = var_df["Variables"].apply(lambda item: item.varValue)
display(var_df)

Total cost is 32000.00 €

The following table shows the decision variables:

Variables Solution (GRB) Reduced cost (GRB) Objective Coefficient (GRB) Objective Lower bound (GRB) Objective Upper bound (GRB)
(Portland, Los Angeles) units__('Portland',_'Los_Angeles') 200.00 0.00 30.00 -Inf 50.00
(Portland, Hawkins) units__('Portland',_'Hawkins') 0.00 20.00 40.00 20.00 Inf
(Flint, Los Angeles) units__('Flint',_'Los_Angeles') 100.00 0.00 60.00 40.00 Inf
(Flint, Hawkins) units__('Flint',_'Hawkins') 400.00 0.00 50.00 0.00 70.00

The following table shows the constraints:

Constraint Right Hand Side Shadow Price Slack Min RHS Max RHS
0 Supply_From_Portland 200.00 -30.00 0.00 100.00 300.00
1 Supply_From_Flint 600.00 0.00 100.00 500.00 Inf
2 Demand_in_Los_Angeles 300.00 60.00 0.00 200.00 400.00
3 Demand_in_Hawkins 400.00 50.00 0.00 -0.00 500.00
[ ]: