Production Mix

Problem definition

Chappie Ltd. has 3 production lines (A, B, and C) to make 4 different types of metal sheets of width 0.4, 05, 0.6, and 0.7 mm. The company needs to meet the monthly demand for each kind of product (in Tons) expressed in the next table:

Sheet 0.4 mm

Sheet 0.5 mm

Sheet 0.6 mm

Sheet 0.7 mm

500

1200

1500

300

The production lines do not have the same overall efficiency for all types of sheets. Furthermore, due to design constraints, not all the lines are capable of manufacturing all types of sheets. The table below indicates the manufacturing costs in € of the different products in the different lines: a dash “-“ means that it is not possible to manufacture a product in a line:

Line

Sheet 0.4 mm

Sheet 0.5 mm

Sheet 0.6 mm

Sheet 0.7 mm

A

60

50

50

45

B

80

70

75

70

C

60

60

The different lines have the following capacities (in hours) in the planning period:

A

B

C

500

480

370

And the following table represents the manufacturing time (hours) per ton of product required for each type of metal sheet in the different lines:

Line

Sheet 0.4 mm

Sheet 0.5 mm

Sheet 0.6 mm

Sheet 0.7 mm

A

0.4

0.3

0.3

0.25

B

0.8

0.6

0.7

0.6

C

0.5

0.4

Formulate a linear programming problem to obtain the monthly production plan: quantity of metal sheet in tons of each type of metal sheet to be manufactured in each production line

indexes

i: Manufacturing lines (A,B,C)

j: Product types Sheet (0.4, 0.5, 0.6, 0.7) mm

Decision Variables

\(x_{ij}\) = Quantity of product j to produce in line i

**Objective function Minimize cost

\(\min z = \sum_i\sum_j c_{ij}*x_{ij}\)

where \(c_{ij}\) is the cost of manufacturing product j in line i as expressed in the second table.

Constraints Capacity

\(\sum_{j}a_{ij}·x_{ij} <= b_{i}, \forall i\)

Where \(a_{ij}\) represent the manufacturing time required to manufacture product j in line i as expressed in the last table and b_{i} represents the capacity of line i for the planning period

Demand

\(\sum_{i}{x_{ij}}>= d_{j}, \forall j\)

[23]:
# Let's start importing the library PuLP to solve linear programs
import pulp
# We are going to use panda to display the results as tables using Panda
import pandas as pd
#And we will use numpy to perform array operations
import numpy as np
#We will use display and Markdown to format the output of code cells as Markdown
from IPython.display import display, Markdown
[24]:
# Create an instance of the problem class using LpProblem
model = pulp.LpProblem("Chappie_example", pulp.LpMinimize)
[25]:

# Define index i (lines) line_names = ('A', 'B', 'C') # Define index j (product types ) product_types = ('4', '5', '6', '7') # Then we create a variable from a dictionary, using the variable names as keys variables = pulp.LpVariable.dicts("x", [(i,j) for i in line_names for j in product_types], lowBound=0, cat='Continuous') # Define coefficients coefficients = [[60, 50, 50, 45], [80, 70, 75, 70], [0, 60, 60, 0]] # Define objective function model += ( pulp.lpSum([ coefficients[i][j] * variables[(line_names[i],product_types[j])] for i in range(len(line_names)) for j in range(len(product_types))]) ), "Cost" # Capacity Constraints capacity=[500, 480, 370] A = [[0.4, 0.3, 0.3, 0.25], [0.8, 0.6, 0.7, 0.6], [0, 0.5, 0.4, 0]] for i in range(len(line_names)): model += pulp.lpSum([ A[i][j] * variables[(line_names[i],product_types[j])] for j in range(len(product_types))]) <= capacity[i] , line_names[i] # Demand constraints demand = [500, 1200, 1500, 300] for j in range(len(product_types)): model += pulp.lpSum([ variables[(line_names[i],product_types[j])] for i in range(len(line_names))]) >= demand[j], product_types[j]
[26]:
# Solve our problem
model.solve()
pulp.LpStatus[model.status]
[26]:
'Optimal'
[27]:
# Solution
max_z = pulp.value(model.objective)

#We use display and Markdown to show the value using markdown
display(Markdown("The value of the objective function is **%.2f**"%max_z))


# Print our decision variable values
display(Markdown("The following tables show the values obtained: "))
# First we create a dataframe from the dictionary of the solution. We want to use the variable indexes to present the results and
# place the different values provided by the solver in the data frame.
var_df = pd.DataFrame.from_dict(variables, orient="index",
                                columns = ["Variables"], dtype=object)
# First we add the solution. We apply a lambda function to get only two decimals:
var_df["Solution"] = var_df["Variables"].apply(lambda item: item.varValue)
# We do the same for the reduced cost:
var_df["Reduced cost"] = var_df["Variables"].apply(lambda item: item.dj)


# We use the display function to represent the results:
display(var_df)


# we define a dictionary with the constraints:
const_dict = dict(model.constraints)
#We create a list of records from the dictionary and exclude the Expression to have a more compact solution.
con_df = pd.DataFrame.from_records(list(const_dict.items()), exclude=["Expression"], columns=["Constraint", "Expression"])

#Now we add columns for the solution, the slack and shadow price

con_df["Right Hand Side"] = con_df["Constraint"].apply(lambda item: "{:.2f}".format(-const_dict[item].constant))
con_df["Slack"] = con_df["Constraint"].apply(lambda item: "{:.2f}".format(const_dict[item].slack))
con_df["Shadow Price"] = con_df["Constraint"].apply(lambda item: "{:.2f}".format(const_dict[item].pi))

# And we display the results
display(con_df)

The value of the objective function is 146416.67

The following tables show the values obtained:

Variables Solution Reduced cost
(A, 4) x_('A',_'4') 0.00000 86.666667
(A, 5) x_('A',_'5') 1091.66670 0.000000
(A, 6) x_('A',_'6') 575.00000 0.000000
(A, 7) x_('A',_'7') 0.00000 61.666667
(B, 4) x_('B',_'4') 0.00000 80.000000
(B, 5) x_('B',_'5') 108.33333 0.000000
(B, 6) x_('B',_'6') 0.00000 5.000000
(B, 7) x_('B',_'7') 0.00000 70.000000
(C, 4) x_('C',_'4') 500.00000 0.000000
(C, 5) x_('C',_'5') 0.00000 2.500000
(C, 6) x_('C',_'6') 925.00000 0.000000
(C, 7) x_('C',_'7') 300.00000 0.000000
Constraint Right Hand Side Slack Shadow Price
0 A 500.00 -0.00 -66.67
1 B 480.00 415.00 0.00
2 C 370.00 -0.00 -25.00
3 4 500.00 -0.00 0.00
4 5 1200.00 -0.00 70.00
5 6 1500.00 -0.00 70.00
6 7 300.00 -0.00 0.00
[ ]: