as presented at the NZPUG meeting in Auckland, December 2008 - http://nzpug.org/MeetingsAuckland/Dec2008
1 of 26
Download to read offline
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
More Related Content
Stuart Mitchell - Pulp Optimisation
1. The
Optimisation
University
of Auckland
Dr. Stuart Mitchell
Department of Engineering Science
University of Auckland
New Zealand
s.mitchell@auckland.ac.nz
December 2008 meeting of NZPUG
3. What is Mathematical
programing
• A simple mathematically precise way of
stating optimisation problems.
• Use mathematically rigorous ways to find a
solution
• Examples of Optimisation Problems that
can be solved with MP:
– Shortest Path Problem
– Scheduling Problems (Set partitioning)
– Knapsack problems
– Blending Problems
4. The Whiskas blending problem
• Taken from
http://130.216.209.237/engsci392/pulp/ABlendingProblem
• Whiskas cat food want to produce their cat
food products as cheaply as possible while
ensuring they meet the stated nutritional
analysis requirements shown on the cans.
• Thus they want to vary the quantities of
each ingredient used (the main ingredients
being chicken, beef, mutton, rice, wheat
and gel) while still meeting their nutritional
standards.
6. Whiskas blending problem
• We wish to identify decision variables
• Assume we only have chicken and beef
• Let
– xc = the percentage of chicken meat
– xb = the percentage of beef used
• Then we wish to
minimise $13xc + $8xb
7. Whiskas Blending Problem
• What about the nutritional requirements
• Subject to
xc+ xb= 100
0.100xc + 0.200xb >= 8.0
0.080xc + 0.100xb >= 6.0
0.001xc + 0.005xb <= 2.0
0.002xc + 0.005xb <= 0.4
• xc>=0, xb>=0
8. MP Model
Let : I ∈{c , b , m , w , g}the set of ingredients
x i be the percentage of ingredient i in the cat food i∈ I
C i be the cost of ingredient i i ∈I
Pi be the protien content of ingredient i i ∈I
F i be the fat content of ingredient i i ∈I
Fbi be the fibre content of ingredient i i ∈ I
Si be the salt content of ingredient i i ∈ I
min ∑ i∈ I C i x i
s.t.
∑i∈ I x i=100
∑ i∈ I F i x i≥8
∑i∈ I Fb i xi ≤2
∑i∈ I Si xi≤0.4
x i≥0 ∀ i ∈ I
9. Ok where is the python
• On google code you can find pulp-or
http://code.google.com/p/pulp-or/
• This is a python module that allows the
easy statement and solution of linear
programing problems.
• Pulp leverages features of python and the
open source optimisation libraries Coin-or
10. Whiskas model in python
quot;quot;quot;
The Full Whiskas Model Python Formulation for the PuLP Modeller
Authors: Antony Phillips, Dr Stuart Mitchell 2007
quot;quot;quot;
# Import PuLP modeler functions
from pulp import *
# Creates a list of the Ingredients
Ingredients = ['CHICKEN', 'BEEF', 'MUTTON', 'RICE', 'WHEAT', 'GEL']
# A dictionary of the costs of each of the Ingredients is created
costs = {'CHICKEN': 0.013,
'BEEF': 0.008,
'MUTTON': 0.010,
'RICE': 0.002,
'WHEAT': 0.005,
'GEL': 0.001}
# A dictionary of the protein percent in each of the Ingredients is created
proteinPercent = {'CHICKEN': 0.100,
'BEEF': 0.200,
'MUTTON': 0.150,
'RICE': 0.000,
'WHEAT': 0.040,
'GEL': 0.000}
# A dictionary of the fat percent in each of the Ingredients is created
fatPercent = {'CHICKEN': 0.080,
'BEEF': 0.100,
'MUTTON': 0.110,
'RICE': 0.010,
'WHEAT': 0.010,
'GEL': 0.000}
# A dictionary of the fibre percent in each of the Ingredients is created
fibrePercent = {'CHICKEN': 0.001,
'BEEF': 0.005,
'MUTTON': 0.003,
'RICE': 0.100,
'WHEAT': 0.150,
11. # Create the 'prob' variable to contain the problem data
prob = LpProblem(quot;The Whiskas Problemquot;, LpMinimize)
# A dictionary called 'Vars' is created to contain the referenced Variables
vars = LpVariable.dicts(quot;Ingrquot;,Ingredients,0)
# The objective function is added to 'prob' first
prob += lpSum([costs[i]*vars[i] for i in Ingredients]), quot;Total Cost of Ingredients per canquot;
# The five constraints are added to 'prob'
prob += lpSum([vars[i] for i in Ingredients]) == 100, quot;PercentagesSumquot;
prob += lpSum([proteinPercent[i] * vars[i] for i in Ingredients]) >= 8.0, quot;ProteinRequirementquot;
prob += lpSum([fatPercent[i] * vars[i] for i in Ingredients]) >= 6.0, quot;FatRequirementquot;
prob += lpSum([fibrePercent[i] * vars[i] for i in Ingredients]) <= 2.0, quot;FibreRequirementquot;
prob += lpSum([saltPercent[i] * vars[i] for i in Ingredients]) <= 0.4, quot;SaltRequirementquot;
# The problem data is written to an .lp file
prob.writeLP(quot;WhiskasModel2.lpquot;)
# The problem is solved using PuLP's choice of Solver
prob.solve()
# The status of the solution is printed to the screen
print quot;Status:quot;, LpStatus[prob.status]
# Each of the variables is printed with it's resolved optimum value
for v in prob.variables():
print v.name, quot;=quot;, v.varValue
# The optimised objective function value is printed to the screen
print quot;Total Cost of Ingredients per can = quot;, value(prob.objective)
12. The open source future for OR
• Presently the Computational OR tools
used, taught within this department, are
closed source.
– Excel /Storm
– AMPL, GAMS
– CPLEX, EXPRESS, ZIP
• Students can not afford commercial
licences of this software
• Students cannot see how this software
works.
13. The open source future for OR
• Outcomes for students
– Ability to access free (no cost) software to
implement their own solutions once they
graduate
– Ability to access free (open) source code to
see how the algorithms are implemented.
• Imagine the difference to 391??
– The ability to improve the software they use.
14. PuLP
• PuLP is a python module that allows the
easy expression of Mathematical Programs
• PuLP is built to interface with separate
solvers
• PuLP is similar in style to:
– AMPL
– GAMS
– OPL
– LINGO
– FLOPC++ etc.
15. PuLP
• Why Python?
– Core Python syntax leads to the concise
statement of MP's
– Python is a scripting language so no
compilation is needed and the code is platform
independent
– Python interfaces easily with external solvers
that do the heavy lifting
– Python comes with 'batteries included'
• The Python standard library is huge
16. PuLP
• Written initially by J. S. Roy
• Now maintained by S. A. Mitchell
• It is available at
http://pulp-or.google-code.com
• Now available for Windows and Linux
17. Generating a Yield Frontier
Total Volume
of Pulp logs
40m3
Lines joining
extreme points
represent the
Yield Frontier
Total Volume
20m3 of Saw logs
18. Generating a Yield Frontier
• Using pulp we formulate the bucking
problem (with a single objective) as a set
packing problem by log section.
19. lp = LpProblem(quot;Bucking Modelquot;, LpMaximize)
#set up the logvolume variables
logvol=LpVariable.dicts(quot;LogVolume(quot;%squot;)quot;,logtypes,0)
#objective
lp+=lpSum([l.price * logvol[l] for l in logtypes]), quot;Revenue“
#setup the arc variables
x=LpVariable.dict(quot;x(%s)quot;,f_logs,0,1,LpInteger)
#set up a section set partitioning problem
count = 0
for s in stems:
slogs = fs_logs[s]
for i,sec in enumerate(s.sections):
lp +=( lpSum((x[log] for log in slogs
if log.startl <= sec.start
if log.endl > sec.start)) <= 1
, quot;Stem_Section(quot;%squot;,%i)quot; % (str(s),i))
count += 1
#add the constraints that link the log volumes
for lt in logtypes:
lp +=( lpSum((log.volume*x[log]
for log in fl_logs[lt])) - logvol[lt] == 0
, quot;Logtype_volume(quot;%squot;)quot; % str(lt))
20. Generating a Yield Frontier Using Pulp
• We then iteratively solve the problem to find all
extreme supported solutions on the Yield
Frontier
• Equivalent to projecting the problem into the log
volume space
• I added a module to PuLP that implements
projection using Iterative Hull Methods (Lassez,
Lassez 1992)
>>> pprob, ppoints = polytope.project(lp, totalvars)
21. Find Yield Frontier for the Dataset
(176, 649)
(0, 650) (235, 611)
(737,145)
(823, 35)
(0, 0)
(838, 0)
22. Find Yield Frontier for a Single Stem
* Total projected *
Minimize
OBJ: __dummy
Subject To
_C1: DomSaw + 1.11154598826 ex <= 2669.27592955
_C2: DomSaw + 1.34653465347 ex <= 3118.57425743
_C3: 1.00863930886 DomSaw + ex <= 2522.60691145
Bounds
__dummy = 0
End
23. Travelling tournament problem with PuLP
• This problem models the allocation of
teams to Home and Away games in a
tournament
• A full problem description and datasets are
found at Michael Trick's page
• http://mat.tepper.cmu.edu/TOURN/
24. Travelling tournament problem with PuLP
• At IFORS 2008 M. Trick presented an
approach to finding lower bounds to this
problem using combinatorial benders cuts
• That evening I implemented his algorithm
using PuLP
• Along the way I also added Powerset,
Combination and Permutation operators to
PuLP
25. • lp = LpProblem(quot;Travelling tournement Masterquot;, LpMinimize)
#create variables
triplist = [Trip(t1,p) for t1 in teams
for p in
allpermutations([t for t in
teams if t !=t1] ,k)
if p[0] <= p[-1]]
tripvars = LpVariable.dict(quot;mastervar quot;,triplist,0,1,LpInteger)
#objective
lp += lpSum([t.cost()*tripvars[t]
for t in triplist])
#construct constraints to ensure that all teams visit each other
for t1 in teams:
for t2 in teams:
if t1 != t2:
lp += lpSum([tripvars[t] for t in triplist
if t.team == t1
if t2 in a.awayteams]) == 1,
quot;Team_%s_Visits_%squot;%(t1,t2)
26. Further examples
• The 392 course has been converted from
AMPL to PuLP
http://130.216.209.237/engsci392/pulp/OptimisationWithPuLP
• There you can see a number of different
ways to construct problems
• Note that new language features can be
added very easily only needing approval
from the BDFL