MATLAB compared to Python and Gurobi

advertisement
Comparing MATLAB’s Optimization Toobox with Gurobi’s Python Interface
Brian Pochinski
UW-Milwaukee
The Optimization Toolbox put out by MATLAB is able to solve a number of optimization
problems including linear programming, quadratic programming, non-linear programming, constrained
optimization and unconstrained optimization (“mathworks optimization”, 2014
http://www.mathworks.com/help/optim/functionlist.html). However, there are alternatives to the
Optimization Toolbox. One such option is using the Gurobi Optimizer. Gurobi can interface with Python,
C, C++, Java, R, and even MATLAB (Gurobi Optimizer Reference Manual, 2013). The present report will
compare the use of the Optimization Toolbox with the Gurobi Python interface. Three examples will be
presented. The first example is a linear programming problem, the second example is a binary integer
programming problem, and the third will be a quadratic programming problem.
Linear Programming
MATLAB is able to solve linear programming problems with linprog which is part of the
Optimization Toolbox. Mathworks offers information on linprog at “mathworks optimization” (2014)
http://www.mathworks.com/help/optim/ug/linprog.html where the following example can be found.
Find x that minimizes
f(x) = –5x1 – 4x2 –6x3,
subject to
x1 – x2 + x3 ≤ 20
3x1 + 2x2 + 4x3 ≤ 42
3x1 + 2x2 ≤ 30
0 ≤ x1, 0 ≤ x2, 0 ≤ x3.
f = [-5; -4; -6];
A = [1 -1 1
3 2 4
3 2 0];
b = [20; 42; 30];
lb = zeros(3,1);
[x,fval,exitflag,output,lambda] = linprog(f,A,b,[],[],lb)
As can be seen in the example, the f vector is the objective function we are trying to minimize.
The A matrix is for the left side of the inequality contstraints and the b vector is for the right side
inequality constraints. Had there been equality constraints, they would be represented by an Aeq matrix
and a beq vector. The lb vector represents the lower bounds and if there were upper bounds they would
be represented by a ub vector. Running this script will return the following output which shows the
minimum value is -78 when X1 is 0, X2 is 15, and X3 is 3.
>> lp
Optimization terminated.
x=
0.0000
15.0000
3.0000
fval =
-78.0000
exitflag =
1
output =
iterations: 6
algorithm: 'large-scale: interior point'
cgiterations: 0
message: 'Optimization terminated.'
constrviolation: 0
firstorderopt: 5.8705e-10
lambda =
ineqlin: [3x1 double]
eqlin: [0x1 double]
upper: [3x1 double]
lower: [3x1 double]
You could do the same problem using the Gurobi Python interface. The Gurobi Optimizer Quick
Start Guide (2013) offers an example and detailed description on how you could formulate an
optimization problem. Adjusting the script allows you to solve the linear programming problems that
can be solved with linprog. The following script solves the same linprog example from above:
from gurobipy import *
try:
m = Model("mip1")
x = m.addVar(vtype=GRB.CONTINUOUS, name="x")
y = m.addVar(vtype=GRB.CONTINUOUS, name="y")
z = m.addVar(vtype=GRB.CONTINUOUS, name="z")
m.update()
m.setObjective(-5 * x - 4 * y - 6 * z, GRB.MINIMIZE)
m.addConstr(x - y + z <= 20, "c0")
m.addConstr(3 * x + 2 * y + 4 * z <= 42, "c1")
m.addConstr(3 * x + 2 * y <= 30, "c2")
m.addConstr(x >= 0, "c3")
m.addConstr(y >= 0, "c4")
m.addConstr(z >= 0, "c5")
m.optimize()
for v in m.getVars():
print('%s %g' % (v.varName, v.x))
print('Obj: %g' % m.objVal)
except GurobiError:
print('Error reported')
Gurobi Python scripts must begin with from gurobipy import * so that python can import Gurobi
functions and classes. Creating the model m = Model("mip1") allows the user to do linear programming,
integer programming, or binary integer programming. Variables are created using the syntax x =
m.addVar(vtype=GRB.CONTINUOUS, name="x"). This simply specifies the variables that will be in our
object function and constraints. Integer programming could be done by replacing CONTINUOUS WITH
INTEGER and binary integer programming could be done by replacing CONTINUOUS with BINARY. Using
m.update() in your script is only required if you will be doing modification later on, but it is not very
important for our purposes. The objective function is called using m.setObjective(-5 * x - 4 * y - 6 * z,
GRB.MINIMIZE). This is analogous to the f matrix in MATLAB. It is possible to do maximization problems
by replacing MINIMIZE with MAXIMIZE. Constraints are added using m.addConstr(x - y + z <= 20, "c0").
The Gurobi Python interface can use =, <=, or >=. The constraints are analogous to the A and Aeq
matrices and the b and beq vectors in MATLAB. Adding a name such as “c0” is optional and is simply for
the user’s convenience. Finally, using m.optimize() tells the Gurobi Python interface we want to optimize
the minimization or maximization problem.
Running the script yields the following output:
Optimize a model with 6 rows, 3 columns and 11 nonzeros
Presolve removed 3 rows and 0 columns
Presolve time: 0.00s
Presolved: 3 rows, 3 columns, 8 nonzeros
Iteration Objective
Primal Inf. Dual Inf.
Time
0 -1.7318800e+02 2.254400e+01 0.000000e+00
0s
3 -7.8000000e+01 0.000000e+00 0.000000e+00
0s
Solved in 3 iterations and 0.01 seconds
Optimal objective -7.800000000e+01
x0
y 15
z3
Obj: -78
This is the same solution found with linprog. The minimum value is -78 when X1 is 0, X2 is 15, and X3 is
3. One slight advantage offered by the Gurobi Python interface is that it can perform minimization or
maximization problems avoiding any potential errors that could occur when changing a minimization
problem to a maximization problem or vice-versa.
Binary Integer Programming
MATLAB’s Optimization Toolbox can also solve binary integer programming problems with
bintprog. MATLAB offers information regarding bintprog and the following example at “mathworks
optimization”, (2014) http://www.mathworks.com/help/optim/ug/bintprog.html.
To minimize the function
f(x) = –9x1 – 5x2 – 6x3 – 4x4,
subject to the constraints
where x1, x2, x3, and x4 are binary integers, enter the following commands
f = [-9; -5; -6; -4];
A = [6 3 5 2; 0 0 1 1; -1 0 1 0; 0 -1 0 1];
b = [9; 1; 0; 0];
[x,fval] = bintprog(f,A,b)
This is very similar to the linprog example already discussed. The only real difference is you are
calling bintprog instead of linprog. You once again could add equality constraints with Aeq and beq and
you could also add lower and upper bounds with lb and ub, respectively. Running the script reveals the
following output which shows that the minimum value is -14 when X1 and X2 are equal to 1 and X3 and
X4 are equal to 0.
>> bp
Optimization terminated.
x=
1
1
0
0
fval =
-14
As discussed earlier, The Gurobi Optimizer Quick Start Guide (2013) offers an example and
detailed description on how you could formulate an optimization problem. Not only can the example be
easily modified for linear programming, but it can also easily be adjusted for binary integer
programming. The following script shows how to solve the previous bintprog example with the Gurobi
Python interface:
from gurobipy import *
try:
m = Model("mip1")
w = m.addVar(vtype=GRB.BINARY, name="w")
x = m.addVar(vtype=GRB.BINARY, name="x")
y = m.addVar(vtype=GRB.BINARY, name="y")
z = m.addVar(vtype=GRB.BINARY, name="z")
m.update()
m.setObjective(-9 * w - 5 * x - 6 * y - 4 * z, GRB.MINIMIZE)
m.addConstr(6 * w + 3 * x + 5 * y + 2 * z <= 9, "c0")
m.addConstr(y + z <= 1, "c1")
m.addConstr(-1 * w + y <= 0)
m.addConstr(-1 * x + z <= 0)
m.optimize()
for v in m.getVars():
print('%s %g' % (v.varName, v.x))
print('Obj: %g' % m.objVal)
except GurobiError:
print('Error reported')
The only difference between this script and the first Gurobi Python script is that the objective functions
and the constraints have changed and we have changed CONTINUOUS to BINARY in our variables.
Conveniently, the Gurobi Python interface allows a combination of continuous, binary or even integer
values for the variables in on a single script.
Quadratic Programming
Because not all optimization problems linear, MATLAB also offers the quadratic programming
with the call quadprog. The major difference between linprog and quadprog is that quadprog uses an
additional H matrix to represent the quadratic in the equation. More information regarding quadprog
can be found at“mathworks optimization” (2014)
http://www.mathworks.com/help/optim/ug/quadprog.html. In math 314 we discussed an example of
the following quadratic programming problem (Wade, 2014):
Minimize
5X(1)^2 – 2X(1)*X(2) + 5X(2)^2
Subject to
X(1) + X(2) = 1
X(1) >= 0
X(2) >= 0
This is the MATLAB script and subsequent output for this quadratic programming problem:
%EX3
f = [0 0]';
H = [10 -2;
-2 10];
A = [];
b = [];
Aeq = [1 1];
beq = [1];
lb = [0 0];
ub = [];
[x,fval] = quadprog(H,f,A,b,Aeq,beq,lb,ub)
>> qpEX3
Optimization terminated.
x=
0.5000
0.5000
fval =
2.0000
The f vector contains 0s because we have no linear part in our objective function. The 10s in the
H matix come from our 5X(1)^2 and 5X(2)^2 and -2s come from -2X(1)*X(2). Everything else is the same
as in linprog and bintprog.
The Gurobi Python interface can also handle quadratic programming problems. The Gurobi
Optimizer Example Tour (2013) offers an example script that can solve quadratic programming
problems. Making slight adjustments allows you to solve a number of differnt quadratic programming
problems. To solve a quadratic problem you must call the model “qp”. Lower bounds and upper bounds
can be specified in your variables using lb and ub, respectively. Alternatively, you could include the
upper and lower bounds inthe constraints. The quadratic programming problem discussed in class and
solved above with quadprog can also be solved with the following Gurobi Python interface script:
from gurobipy import *
m = Model("qp")
x = m.addVar(lb=0, name="x")
y = m.addVar(lb=0, name="y")
m.update()
obj = 5*x*x - 2*x*y + 5*y*y
m.setObjective(obj)
m.addConstr(x + y <= 1, "c0")
m.addConstr(x + y >= 1, "c1")
m.optimize()
for v in m.getVars():
print('%s %g' % (v.varName, v.x))
print('Obj: %g' % obj.getValue())
x.vType = GRB.CONTINUOUS
y.vType = GRB.CONTINUOUS
m.optimize()
for v in m.getVars():
print('%s %g' % (v.varName, v.x))
print('Obj: %g' % obj.getValue())
Running this script gets the same answer as quadprog and the following output:
Optimize a model with 2 rows, 2 columns and 4 nonzeros
Model has 3 quadratic objective terms
Presolve removed 1 rows and 0 columns
Presolve time: 0.01s
Presolved: 1 rows, 2 columns, 2 nonzeros
Presolved model has 3 quadratic objective terms
Ordering time: 0.00s
Barrier statistics:
Free vars : 1
AA' NZ
: 1.000e+00
Factor NZ : 3.000e+00
Factor Ops : 5.000e+00 (less than 1 second per iteration)
Threads : 1
Objective
Iter
Primal
Dual
Residual
Primal Dual
Compl
Time
0 3.02003332e+05 -3.02003332e+05 1.25e+03 1.71e-06 1.00e+06
0s
1 3.47945551e+04 -3.64480440e+04 6.13e+01 8.41e-08 7.53e+04
0s
2 5.52349085e+00 -2.52066306e+03 5.12e-01 7.02e-10 1.91e+03
0s
3 4.44502731e+00 -3.13406218e+02 5.12e-07 8.88e-16 1.59e+02
0s
4 4.39306098e+00 -6.72971833e+00 1.71e-08 4.44e-16 5.56e+00
0s
5 2.90008045e+00 -1.15036959e+01 1.73e-14 1.11e-16 7.20e+00
0s
6 2.10426620e+00 7.60772624e-01 1.11e-16 2.22e-16 6.72e-01
0s
7 2.00010512e+00 1.93973288e+00 2.22e-15 1.53e-16 3.02e-02
0s
8 2.00000000e+00 1.99993957e+00 2.22e-16 2.22e-16 3.02e-05
0s
9 2.00000000e+00 1.99999994e+00 2.22e-16 2.22e-16 3.02e-08
0s
10 2.00000000e+00 2.00000000e+00 5.55e-17 1.96e-16 3.03e-11
0s
Barrier solved model in 10 iterations and 0.07 seconds
Optimal objective 2.00000000e+00
x 0.5
y 0.5
Obj: 2
While the Optimization Toolbox offers much convenience, there are alternative ways to go
about optimization. Not only can you interface Gurobi with Python, but also with other languages such
as C, C++, Java, R, and even MATLAB (Gurobi Optimizer Reference Manual, 2013). Gurobi can handle a
number of optimization problems including linear programming, binary integer programming, integer
programming, and quadratic programming.
References
Gurobi Optimizer Example Tour. (2013). Version 5.6. Retrieved from
http://www.gurobi.com/documentation/5.6/example-tour/examples.pdf.
Gurobi Optimizer Quick Start Guide. (2013). Version 5.6. Retrieved from
http://www.gurobi.com/documentation/5.6/quick-start-guide/quickstart.pdf.
Gurobi Optimizer Reference Manual. ( 2013). Version 5.6. Retrieved from
http://www.gurobi.com/documentation/5.6/reference-manual/refman.pdf.
“Mathworks Optimization” (2014). Functionlist. Retrieved from
http://www.mathworks.com/help/optim/functionlist.html.
“Mathworks Optimization” (2014). Bintprog. Retrieved from
http://www.mathworks.com/help/optim/ug/bintprog.html.
“Mathworks Optimization” (2014). Linprog. Retrieved from
http://www.mathworks.com/help/optim/ug/linprog.html.
Wade, B. (2014). Math 314. Mathametical Programming and Optimization. Lecture conducted at UWMilwaukee. Milwaukee, WI.
Download