Optimization in R - Production quantities to maximize profit

This article showcases solving an assumed business problem using optimization, with R as the tool to do so. Optimization problems come is various shapes and sizes and complexities. In this article the focus is on a simplified version of a problem to decide on production quantities to maximize profit. Image attribute: GYassineMrabetTalk✉, CC BY 3.0 https://creativecommons.org/licenses/by/3.0, via Wikimedia Commons

Introduction

Manufacturing units often must decide on production quantities under various constrains, to maximize margin/profit. Mathematics can help with such decisions, as shown below using a simplified example.

Problem

XYZ corp manufactures 4 products, each of which need two machines and two types of labour. The time required to manufacture each product (in each machine) and manhours required (for each type of labour) is mentioned below. In addition, the sales price is also mentioned.

Product Machine 1 Machine 2 Labour (Skilled) Labour (Unskilled) Unit price
1 11 4 8 7 300
2 7 6 5 8 260
3 6 5 5 7 220
4 5 4 6 4 180

Machine 1 is allowed to run for 700 hours and Machine 2 for 500 hours each month. Moreover, 600 hours of skilled and 650 hours of unskilled labour are available at $8 per hour and $6 per hour respectively. XYZ wants to decide on how many of each product to produce and how much labour to purchase each month to maximize the margin.

Solution

Objective function

The function of margin can be defined as

$$ \overbrace{300x_{1} + 260x_{2} + 220x_{3} + 180x_{4}}^{\text {Revenue from Sales}} - \underbrace{(8 y_{1} + 6 y_{2})}_{\text {Cost of Labour}} $$

where \(x_n\) are the number of products to produce each month and \(y_n\) are the hours of labour to purchase (1 for skilled and 2 for unskilled)

Constrains

If \(x_1\) units of product 1 are manufactured, \(x_2\) units of product 2 are manufacture and so on, the total time machine 1 will be occupied is

$$ 11x_1 + 7x_2 + 6x_3 + 5x_4 $$ Total number of hours in machine one should be within 700 hours (included).

$$ 11x_1 + 7x_2 + 6x_3 + 5x_4 \le 700 $$

Similarly for machine 2

$$ 4x_1 + 6x_2 + 5x_3 + 4x_4 \le 500 $$

Similarly, for the labours

$$ 8x_1+5x_2+5x_3+6x_4 \le y_1 $$

$$ 7x_1+8x_2+7x_3+4x_4 \le y_2 $$

Also for skilled labour

$$ y_1 \le 600 $$ and for unskilled

$$ y_2 \le 650 $$

Finally, all the variables need to be non-zero and Integer

$$ x_n \ge 0 $$

$$ y_n \ge 0 $$

We also solve this assuming that number of products need to be integer, whereas the manhours can be a decimal.

Solving the equations

1library(lpSolve)
2objective.fn <- c(300, 260, 220, 180, -8, -6)
3const.mat <- matrix(c(11, 7, 6, 5, 0, 0, 4,6,5,4,0,0, 8,5,5,6,-1,0, 7,8, 7, 4,0,-1, 0,0,0,0,1,0,0,0,0,0,0,1) , ncol=6 , byrow=TRUE)
4const.dir <- c("<=", "<=", "<=","<=","<=","<=")
5const.rhs <- c(700, 500, 0,0, 600, 650)
6
7lp.solution <- lpSolve::lp("max", objective.fn, const.mat, 
8                  const.dir, const.rhs, compute.sens=TRUE,int.vec = c(1,2,3,4))
9lp.solution$solution
1## [1]  18  51   0  29 573 650

Hence, the optimum solution to maximize margin under the given condition is to product 18 units of product 1, 51 units of product 2 and 29 units of product 4 while using 573 hours of skilled and 650 hours of unskilled labour. This will enable XYZ corp to earn a margin of 15396 dollars.

Insights

Optimum production and labour hours to maximize margin.

Variable Optimum value
Product 1 18 units
Product 2 51 units
Product 3 0 units
Product 4 29 units
Skilled Labour 573 hours
Unskilled Labour 650 hours

Solving this optimization problem is not limited to this result. The following insights are also available.

The optimum values will not change within these following ranges.

1data.frame(Variable=c("Product 1 Price","Product 2 Price", "Product 3 Price", "Product 4 Price", "Skilled Labour Cost", "Unskilled Labour Cost"),From=round(lp.solution$sens.coef.from,2), To=round(lp.solution$sens.coef.to,2))
1##                Variable       From          To
2## 1       Product 1 Price  2.290e+02  1.0000e+30
3## 2       Product 2 Price  2.530e+02  3.0400e+02
4## 3       Product 3 Price -1.000e+30  2.2700e+02
5## 4       Product 4 Price  1.580e+02  1.8667e+02
6## 5   Skilled Labour Cost -1.429e+01 -5.5000e+00
7## 6 Unskilled Labour Cost -1.100e+01  1.0000e+30

The insights are not limited to these. Sensitivity analysis also reveals that

  1. Relaxing the constrain of Machine one adds margin of $2.22 i.e. if availability of machine 1 is increased by 1 hours, the margin can be increased by $2.22.
  2. Increasing availability of unskilled labour by 1 hour can increase the margin by $24.22
1data.frame(Duals = lp.solution$duals)
 1##         Duals
 2## 1    2.222222
 3## 2    0.000000
 4## 3    8.000000
 5## 4   30.222222
 6## 5    0.000000
 7## 6   24.222222
 8## 7    0.000000
 9## 8  -37.333333
10## 9  -44.888889
11## 10   0.000000
12## 11   0.000000
13## 12   0.000000

Posts in this Series