Lec 1 - 2 - Linear Programming PDF
Lec 1 - 2 - Linear Programming PDF
Lec 1 - 2 - Linear Programming PDF
Overview
Linear programming is a method to achieve the best outcome in a mathematical model whose requirements are represented by linear
relationships. More formally, linear programming is a technique for the optimization of a linear objective function, subject to linear
equality and linear inequality constraints. Its feasible region is a convex polytope, which is a set defined as the intersection of finitely
many half spaces, each of which is defined by a linear inequality. Its objective function is a real-valued affine (linear) function defined
on this polyhedron. A linear programming algorithm finds a point in the polyhedron where this function has the smallest (or largest)
value if such a point exists.
The problem of solving a system of linear inequalities dates back to at least Fourier, who in 1827 published a method for solving it.
Later on John von Neumann imporved the Simplex Method of solving them to use it on game theory. More recently, it was proven that
a system of linear inequalities can be solved in polinomial time and with the introduction in 1984 of the interior-point method there is
now efficient ways to solving linear inequalities numerically.
Linear programming has wide applications in the fields of economics, operations research, and many others. In particular many
problems in operations reserach can be expressed as linear programs.
Standard Form
We can describe a linear programming problems in three parts:
a11x1 + a12x2 ≤ b1
a21x1 + a22x2 ≤ b2
a31x1 + a32x2 ≤ b3
x1 ≥ 0
x2 ≥ 0
T
max{c x | Ax ≤ b ∧ x ≥ 0}
Where, x is a vector of variables to be solved, c and b are vectors of known coefficients, A is a known matrix of coefficients, and ()T is
the matrix transpose operator.
Installing PuLP
To install PuLP in your computer follow this instructions:
Now lets load the libraries needed for this notebook, including pulp
In [27]:
import numpy as np
import matplotlib.pyplot as plt
import pulp
A Simple Example
Let’s start using PuPL with a simple example. Lets maximize the following objective function Z :
Z = 4x + 3y
x ≥ 0
y ≥ 2
2y ≤ 25–x
4y ≥ 2x–8
y ≤ 2x − 5
Before we use PuLP to sove this Linear Program, lets first graph these contrains and the objective function to get a good idea of how
the function we are trying to optimize looks like and how the contrains limit this function.
In [28]:
# Construct lines
# x > 0
# y >= 2
# 2y <= 25 - x
y2 = (25-x)/2.0
# 4y >= 2x - 8
y3 = (2*x-8)/4.0
# y <= 2x - 5
y4 = 2 * x -5
# Make plot
plt.plot(x, y1, label=r'$y\geq2$') #for label in math text use
plt.xlabel(r'$x$')
plt.ylabel(r'$y$')
<matplotlib.legend.Legend at 0x12f1a86d0>
Out[28]:
y1 : array (length N) or scalar. The y coordinates of the nodes defining the first curve.
y2 : array (length N) or scalar, optional, default: 0. The y coordinates of the nodes defining the second curve.
In [29]:
# Make plot
plt.plot(x, y1, label=r'$y\geq2$') #for label in math text use
plt.xlabel(r'$x$')
plt.ylabel(r'$y$')
# minimum of
# y <= 2x - 5
# maximum of
# y >= 2
<matplotlib.legend.Legend at 0x12f2b7590>
Out[29]:
Plotting the feasible space plus the heat map for the objective function
In [30]:
# Make plot
plt.plot(x, y1, label=r'$y\geq2$') #for label in math text use
plt.xlabel(r'$x$')
plt.ylabel(r'$y$')
# Z=4x+3y
X, Y = np.meshgrid(x, y)
Z = f(X, Y)
plt.colorbar();
In [31]:
# Create the 'prob' variable to contain the problem data
my_lp_problem = pulp.LpProblem("My LP Problem", pulp.LpMaximize)
In [32]:
x = pulp.LpVariable('x', lowBound=0, upBound=None, cat='Continuous')
y = pulp.LpVariable('y', lowBound=2, upBound=None, cat='Continuous')
In [33]:
# Objective function, first one to input, put lable at end "Z"
my_lp_problem += 4 * x + 3 * y, "Z"
Next, we input all the constrains we may have in our optimization problem. We use += as above follow by a relationship. Usually we
use the following relationship operators: ==, , >=, <= as shown below:
In [34]:
# Constraints
#my_lp_problem += y >= 2 # no needed since enter in variable as lowBound
my_lp_problem += 2 * y <= 25 - x
my_lp_problem += 4 * y >= 2 * x - 8
my_lp_problem += y <= 2 * x - 5
In [35]:
my_lp_problem.solve()
1
Out[35]:
Of course, behind the scenes, Pulp and Python are executing numerical optimization algorithms to find a solution. PuLP choses the
solver to use. We can determine what solver PuPL should use by providing an argument: my_lp_problem.solve(CPLEX()) . We
can see what solvers are available in our installation using pulp.pulpTestAll() .
Not Solved
Infeasible
Unbounded
Undefined
Optimal
In [36]:
print("Status:", pulp.LpStatus[my_lp_problem.status])
('Status:', 'Optimal')
Now, we can print the variables and the solved optimum values as well as the optimal value for the objective function. We use
.name() .varValue() and .objective() as follows:
In [37]:
print x.name, x.varValue
print y.name, y.varValue
print pulp.value(my_lp_problem.objective)
x 14.5
y 5.25
73.75
But of course, we can not produce infinite amount of cars. The car manufacturing is restricted by factory capacity, supplier capacity,
financial resources available, etc. Furthermore, the deamand for cars is not infinite and the particular market segment this company
operates on could have several competitors. For this example, lets simply assume that the following equations represent the
manufacturing and market constraints:
3A + 4B <= 30000
5A + 6B <= 60000
2A + 3B <= 21000
In [38]:
# Instantiate our problem class
model = pulp.LpProblem("Profit maximising problem", pulp.LpMaximize)
# Input constraints
model.solve()
print pulp.LpStatus[model.status]
Optimal
Exercises
1. An operations manager is trying to determine a production plan for the next week. There are three products (say, P, Q, and Q) to
produce using four machines (say, A and B, C, and D). Each of the four machines performs a unique process. There is one machine of
each type, and each machine is available for 2400 minutes per week. The unit processing times for each machine is given in Table 1.
A 20 10 10 2400
B 20 28 16 2400
C 20 6 16 2400
D 20 15 0 2400
The unit revenues and maximum sales for the week are indicated in Table 2. Storage from one week to the next is not permitted. The
operating expenses associated with the plant are $6000 per week, regardless of how many components and products are made. The
$6000 includes all expenses except for material costs.
Maximum sales 20 15 0
P rof it = (90 − 45)p + (100 − 40)q + (70 − 20 ) r –6 000 = 45p + 60q + 50r–6000
indentifying the constrains: the amount of time a machine is available and the maximum sales posible restrict the quantities to
be manufactured. Using the unit processing times for each machine, the linear constraints can be written as:
p ≤ 100
q ≤ 40
r ≤ 60
p ≥ 0
q ≥ 0
r ≥ 0
In [39]:
# Instantiate our problem class
model2 = pulp.LpProblem("Manufacturing problem", pulp.LpMaximize)
# Input constraints
model2 += q <= 40
model2 += r <= 60
model2.solve()
print pulp.LpStatus[model2.status]
Optimal
2. A post office requires different numbers of full- time employees on different days of the week. Each full-time employee must work five
consecutive days and then receive two days off.
In the following table, the number of employees required on each day of the week is
specified.
1=Monday 17
2=Tuesday 13
3=Wednesday 15
4=Thursday 19
5=Friday 14
6=Saturday 16
7=Sunday 11