Introduction to gurobipy
#
Note
This material is mostly adapted from the following resources:
Gurobi Optimizer is a mathematical optimization software library for solving mixed-integer linear, quadratic, and linear optimization problems.
Gurobipy is a package to write problems to be solved with Gurobi.
Gurobi software is not open but it allows you to get an Academic license
Note
If you have not yet set up Python on your computer, you can execute this tutorial in your browser via Google Colab. Click on the rocket in the top right corner and launch “Colab”. If that doesn’t work download the .ipynb
file and import it in Google Colab.
Then install the following packages by executing the following command in a Jupyter cell at the top of the notebook.
!pip install gurobipy
We import gurobipy with prefix
gp.
The specific module
GRB
is commonly imported separately, as it is used frequently.
import gurobipy as gp
from gurobipy import GRB
Example: Simple linear optimization problem#
Let’s use the following problem as an example:
We initialize a model object in which we’ll store the problem.
model = gp.Model("My_LP_problem")
Restricted license - for non-production use only - expires 2026-11-23
Now, we can add variables to the model with the method
model.addVar(lb=0.0, ub=float('inf'), vtype=GRB.CONTINUOUS, name="")
.We can specify lower and upper bounds as well as domain using the arguments
lb
,ub
, andvtype
, respectively.Note that the default lower bound is 0!
# Note that these two variables have the same bounds and domain
x_1 = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="x_1")
x_2 = model.addVar(name="x_2")
Generally, we add constraints with the
model.addConstr(constr, name="")
method.In this case, the constraints are linear and here, we should use the
model.addLConstr(constr, name="")
method.Here, it’s important to store the constraints in a meaningful way so you can easily access specific dual variables after solving.
Note, that in the
GRB
module, you can find the three signsGRB.GREATER_EQUAL
,GRB.EQUAL
, andGRB.LESS_EQUAL
.
constraint_1 = model.addLConstr(0.6*x_1 + 0.2*x_2, GRB.GREATER_EQUAL, 60, name='constraint_1')
constraint_2 = model.addLConstr(0.4*x_1 + 0.8*x_2, GRB.GREATER_EQUAL, 100, name='constraint_2')
We define the objective function with the method
model.setObjective(expr, sense=None)
.Remember to set the
sense
argument!
model.setObjective(30*x_1 + 20*x_2, GRB.MINIMIZE)
Now, we can solve the optimization problem with the method
model.optimize
.
model.optimize()
Gurobi Optimizer version 12.0.2 build v12.0.2rc0 (linux64 - "Ubuntu 24.04.2 LTS")
CPU model: AMD EPYC 7763 64-Core Processor, instruction set [SSE2|AVX|AVX2]
Thread count: 2 physical cores, 4 logical processors, using up to 4 threads
Optimize a model with 2 rows, 2 columns and 4 nonzeros
Model fingerprint: 0x20d42a0c
Coefficient statistics:
Matrix range [2e-01, 8e-01]
Objective range [2e+01, 3e+01]
Bounds range [0e+00, 0e+00]
RHS range [6e+01, 1e+02]
Presolve time: 0.00s
Presolved: 2 rows, 2 columns, 4 nonzeros
Iteration Objective Primal Inf. Dual Inf. Time
0 0.0000000e+00 1.600000e+02 0.000000e+00 0s
2 3.9000000e+03 0.000000e+00 0.000000e+00 0s
Solved in 2 iterations and 0.01 seconds (0.00 work units)
Optimal objective 3.900000000e+03
We can check whether the problem was solved to optimality with
model.status
.If so, we retrieve optimal objective function with
model.ObjVal
and optimal primal and dual variable values with
var.x
andconstr.Pi
, respectively.
if model.status == GRB.OPTIMAL:
optimal_objective = model.ObjVal
optimal_x_1 = x_1.x
optimal_x_2 = x_2.x
optimal_dual_1 = constraint_1.Pi
optimal_dual_2 = constraint_2.Pi
print(f"optimal objective: {optimal_objective}")
print(f"optimal value of {x_1.VarName}: {optimal_x_1}")
print(f"optimal value of {x_2.VarName}: {optimal_x_2}")
print(f"optimal value of dual for {constraint_1.constrName}: {optimal_dual_1}")
print(f"optimal value of dual for {constraint_2.constrName}: {optimal_dual_2}")
else:
print(f"optimization of {model.ModelName} was not successful")
optimal objective: 3900.0
optimal value of x_1: 70.0
optimal value of x_2: 90.0
optimal value of dual for constraint_1: 40.0
optimal value of dual for constraint_2: 15.0
Example: Adding quadratic constraints and absolute values for variables#
If we want to add quadratic constraints, we should use the model.addQConstr(constr, name="")
method.
You can also check this short video on setting quadratically constrained problems in gurobipy
If we want to use the absolute value of a variable we can define it as follows
m = model.addVar(vtype=GRB.CONTINUOUS, lb=0, name="m")
abs_m = model.addVar(vtype=GRB.CONTINUOUS, lb=0, name="abs_m")
from gurobipy import abs_
model.addConstr(abs_m == abs_(m), name='abs_m')
<gurobi.GenConstr *Awaiting Model Update*>