Tutorial#

We will consider the following problem taken from [Knight and Palmer, 2022].

Problem

“£50 of profit can be made on each tonne of paint A produced, and £60 profit on each tonne of paint B produced. A tonne of paint A needs 4 tonnes of component X and 5 tonnes of component Y. A tonne of paint B needs 6 tonnes of component X and 4 tonnes of component Y. Only 24 tonnes of X and 20 tonnes of Y are available per day. How much of paint A and paint B should be produced to maximise profit?”

As discussed in [Knight and Palmer, 2022] this can be written in the following form:

\[\begin{split} \begin{align} \text{Maximise: } 50 A + 60 B & \\ \text{Subject to: } & \nonumber \\ 4 A + 6 B &\leq 24 \\ 5 A + 4 B &\leq 20 \end{align} \end{split}\]

This can be represented using the following matrices and vectors:

\[\begin{split} \begin{align} \text{minimise: } c^t x& \\ \text{subject to: } & \nonumber \\ A_{\text{ub}}x&\leq b_{\text{ub}}\\ \end{align} \end{split}\]

with:

\[\begin{split} c=\begin{pmatrix}-50, -60\end{pmatrix}\qquad A_{\text{ub}}=\begin{pmatrix}4 & 6\\ 5 & 4\end{pmatrix}\qquad b_{\text{ub}}=\begin{pmatrix}24, 20\end{pmatrix} \end{split}\]

and \(x=(A, B)\)

Problems in this format can be solved using scipy. First let us create the matrices and vectors as Numpy arrays:

import numpy as np

c = np.array((-50, -60))
A_ub = np.array(((4, 6), (5, 4)))
b_ub = np.array((24, 20))

Now we can solve the linear program:

import scipy.optimize

result = scipy.optimize.linprog(c=c, A_ub=A_ub, b_ub=b_ub)
result
        message: Optimization terminated successfully. (HiGHS Status 7: Optimal)
        success: True
         status: 0
            fun: -257.14285714285717
              x: [ 1.714e+00  2.857e+00]
            nit: 2
          lower:  residual: [ 1.714e+00  2.857e+00]
                 marginals: [ 0.000e+00  0.000e+00]
          upper:  residual: [       inf        inf]
                 marginals: [ 0.000e+00  0.000e+00]
          eqlin:  residual: []
                 marginals: []
        ineqlin:  residual: [ 0.000e+00  0.000e+00]
                 marginals: [-7.143e+00 -4.286e+00]
 mip_node_count: 0
 mip_dual_bound: 0.0
        mip_gap: 0.0

The specific solution can be accessed directly:

result.x
array([1.71428571, 2.85714286])

Indeed, it can be shown theoretically that the optimal result if \(A=\frac{12}{7}\approx 1.714\) and \(B=\frac{20}{7}\approx 2.857\).

Important

In this chapter we have:

  • Plotted a scatter plot.

  • Add a plot of a line to our scatter plot.