Gurobi Optimization

Seminars in Operations Research, ULisboa

Mario Ruthmair
Optimization Engineer

Agenda

  1. What is Gurobi?
  2. Customer Case Studies
  3. Modeling Example: Facility Location

What is Gurobi?

  • Founded in 2008 by Bob Bixby, Zonghao Gu, Ed Rothberg
  • Solver for mathematical optimization problems
  • Additional products around the solver:
    • Gurobi Compute Server + Cluster Manager
    • Gurobi Cloud
    • Several model building and analysis tools

Gurobi is the Engine

  • Gurobi is a generic math optimization solver
  • No application-specific interfaces, no GUI !
  • Partner companies or customers build the car around it

Which models can be solved by Gurobi?

  • Linear Programs (LPs): \[ \begin{align*} \min~ c' x & \\ A x & = b \end{align*} \]

  • Mixed-Integer Linear Programs (MILPs): \[ \begin{align*} \min~ c' x + d' y & \\ A x + D y & = b\\ y & \quad \mathrm{integer} \end{align*} \]

  • Mixed-Integer Quadratically-Constrained Quadratic Programs (MIQCQPs), convex or non-convex: \[ \begin{align*} \min~ c' x + d' y + x' Q x + y' P y & \\ A x + Dy + x' R x + y' T y & = b\\ y & \quad \mathrm{integer} \end{align*} \]

  • Mixed-Integer Non-Linear Non-Convex Programs (MINLPs): \[ \begin{align*} \min~ f(x) + d(y) & \\ g(x) + h(y) & = 0\\ y & \quad \mathrm{integer} \end{align*} \]

How to use Gurobi?

  • Programming language APIs for Python, C, C++, Java, C#, R, Matlab
  • Additional Python packages:
  • Links to standard modeling languages: AIMMS, AMPL, GAMS, MPL
  • Third-party frameworks (not officially supported by Gurobi): Pyomo, PuLP, JuMP (Julia), Google OR-Tools, etc.

What do you need to use Gurobi efficiently?

  • Understanding of business problem to solve
  • Advanced modeling skills
  • Intermediate programming skills

Warning

You need to be an OR + Math + IT expert :)

Experts Team

We help commercial customers with:

  • Installation, licensing
  • Usage, programming APIs
  • Modeling hints and guidelines
  • Numerical issues
  • Model tuning (tweak solver parameters)
  • IT support for Compute Server, Cloud

Who are our customers?

  • Used by 2,500+ companies in 40+ industries
  • 60+ customer case studies on our website

National Football League (NFL)

  • Create game schedule for the whole season
  • From boards to computers
  • Many complicated constraints:
    • broadcast time slots and rights
    • free-agents
    • away-game limitations
  • Decomposition and parallelization approach

Air France

  • Tail assignment problem:
    • assigning sequence of flights to each individual aircraft
    • while respecting operational constraints
    • multiple objectives: fleet utilization, on-time performance, fuel consumption, operational costs, perferential assignments
  • Schedules are re-built every day (disruptions, etc.)
  • Short-haul and medium-haul fleets are more difficult to schedule than long-haul fleet

Verge

  • Optimizing seasonal farm field operations
  • Path Planner to find route covering the whole field
  • Minimize time, distance, fuel consumption
  • Avoid overlaps and obstacles
  • Headland management: boundaries, turnrow

Supply Chain Optimization

Challenges and Optimization Problems

  • Network Design:
    • Location of production facilities and distribution centers
    • Transportation networks and routes
    • Minimize transportation costs but ensure customer service levels
  • Inventory Management:
    • Inventory levels and replenishment policies
    • Minimize inventory holding costs but ensure products are available when needed
  • Production planning:
    • Production schedules and workforce allocation
    • Maximize production efficiency and minimize costs

Supply Chain Optimization

Challenges and Optimization Problems

  • Supplier selection:
    • Supplier selection and contracting decisions
    • Minimize costs but ensure quality and delivery performance
  • Demand forecasting:
    • Demand volatility: Fluctuations in customer demand make it difficult to forecast and plan inventory levels
    • Shifts in demands lead to overstocking or stockouts impacting customer satisfaction

Multiple Objectives

Real-world optimization problems often have multiple, competing objectives

Maximize Profit

&

Minimize Late Orders

Minimize Shift Count

&

Maximize Worker Satisfaction

Minimize Cost

&

Maximize Product Durability

Maximize Profit

&

Minimize Risk

How does Gurobi handle the trade-offs?

  • Weighted or Blended: Optimize a weighted combination of the individual objectives
flowchart LR
    id1[Obj 1] --- id2[Obj 2] --- id3[Obj 3]

\[\min_{x \in C} w_1 f_1(x) + w_2 f_2(x) + w_3 f_3(x) \]

  • Hierarchical or Lexicographical: Optimize each objective in a given priority order while limiting the degradation of the higher-priority objectives
flowchart TD
    id1[Obj 1] --> id2[Obj 2] --> id3[Obj 3]

\[ \begin{align*} \min_{x \in C} & ~f_1(x) \\ \end{align*} \]

\[ \begin{align*} \min_{x \in C} & ~f_2(x) \\ & ~f_1(x) \leq \epsilon_1 \end{align*} \]

\[ \begin{align*} \min_{x \in C} & ~f_3(x) \\ & ~f_1(x) \leq \epsilon_1 \\ & ~f_2(x) \leq \epsilon_2 \end{align*} \]

  • Weighted + Hierarchical: Combine both approaches
  • Gurobi does not offer methods to compute the Pareto front (so far)

  • Audi needs to solve logistics and scheduling problems for car assembly:
    • complex automotive parts with many options
    • limited space in the assembly line
  • Previously, 3-week manual planning process
  • Now, with math optimization they have a one-click solution
  • Still, very challenging huge-scale MILPs (millions of variables and constraints)

  • ARAUCO is a wood pulp, engineered wood, and forestry company
  • Network of over 4300 customers
  • Aleph5 decision support system integrates Gurobi
  • Balance raw material supply and forecasted demand
  • Tradeoffs between multiple objectives:
    • minimize operating costs
    • maximize revenue growth
    • maximize demand fulfillment (customer satisfaction levels)
    • maximize resource utilization ​

  • Polymathian is a consulting company that
    • performs rapid what-if analyses
    • explores multiple scenarios
    • assesses how decisions will affect business objectives
  • Large-scale business problems across a 30-year time horizon involving millions of variables and constraints
  • A supply chain decision support tool allows their customers to
    • evaluate tradeoffs
    • identify strategic risks and opportunities
    • determine their best courses of action

How to handle challenging models?

  • Modeling phase
    • Clean up input data
    • Understand limited precision numerics, e.g., \(10^{10} + 10^{-10} = 10^{10}\)
    • Understand model strength
      • Tighten variable bounds
      • Reduce Big-M values
    • Reformulate model
  • Solution phase
    • Analyze solver logs
    • Run custom heuristics
    • Analyze model structure
    • Tune solver parameters

Why are advanced modeling skills important?

  • Integer problems can have many formulations for the same set of solutions, which one should you choose?
  • Stronger formulations often lead to better performance, even if the model has more variables and/or constraints
  • Art of Modeling
    • Identify and understand model strength
    • Find additional strong constraints
    • Reformulate model

Example: Facility Location

  • Input data:
    • \(S\): Set of supermarkets
    • \(W\): Set of candidate warehouse locations
    • \(f_{w}\): Fixed cost for building warehouse \(w\)
    • \(c_{ws}\): Cost of supplying supermarket \(s\) from warehouse \(w\)
  • Choose a subset of warehouses to supply all supermarkets, with minimal total building and supply costs
  • Decision Variables:
    • \(y_{w} \in \{0, 1\}\): Build warehouse \(w\) (\(y_w = 1\)) or not (\(y_w = 0\))
    • \(0 \leq x_{ws} \leq 1\): Fraction of demand of supermarket \(s\) served by warehouse \(w\)

Example: Facility Location

Model

  • Objective: Minimize total warehouse building and supply costs \[\text{min} \quad \sum_{w \in W} f_{w} \cdot y_{w} + \sum_{w \in W} \sum_{s \in S} c_{ws} \cdot x_{ws}\]
  • Each supermarket has to be fully supplied, i.e., the sum of fractions received from each warehouse must be equal to 1. \[\sum_{w \in W} x_{ws} = 1 \quad \forall s \in S\]
  • Warehouse \(w\) has to be opened if at least one supermarket is supplied. \[\sum_{s \in S} x_{ws} \leq |S| \cdot y_{w} \quad \forall w \in W\]

Example: Facility Location

Python Code

import gurobipy as gp
from gurobipy import GRB

# data preparation ...

model = gp.Model("facility_location")
    
# add variables
x = model.addVars(numWarehouses, numSupermarkets, lb=0, ub=1, vtype=GRB.CONTINUOUS, name="x")
y = model.addVars(numWarehouses, vtype=GRB.BINARY, name="y")

# supermarket supply constraints
model.addConstrs((x.sum("*", s) == 1 for s in range(numSupermarkets)), name="Demand")

# warehouse opening and linking constraints
bigM = numSupermarkets
model.addConstrs((x.sum(w, "*") <= bigM * y[w] for w in range(numWarehouses)), name="Open")

# minimize total costs
model.setObjective(x.prod(shippingCost) + y.prod(openingCost), GRB.MINIMIZE)

model.optimize()

Example: Facility Location

200 warehouse locations, 2000 supermarkets

Optimize a model with 2200 rows, 400200 columns and 800200 nonzeros
Model fingerprint: 0x889c7bde
Variable types: 400000 continuous, 200 integer (200 binary)
Coefficient statistics:
  Matrix range     [1e+00, 2e+03]
  Objective range  [1e+00, 4e+03]
  Bounds range     [1e+00, 1e+00]
  RHS range        [1e+00, 1e+00]
Found heuristic solution: objective 1657011.0000
Presolve time: 0.89s
Presolved: 2200 rows, 400200 columns, 800200 nonzeros
Variable types: 400000 continuous, 200 integer (200 binary)

Root relaxation: objective 7.496728e+04, 0 iterations, 0.57 seconds (0.48 work units)

    Nodes    |    Current Node    |     Objective Bounds      |     Work
 Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time

H    0     0                    655075.00000 74967.2750  88.6%     -    2s
H    0     0                    653009.00000 74967.2750  88.5%     -    2s
H    0     0                    649303.00000 74967.2750  88.5%     -    2s
H    0     0                    315273.00000 74967.2750  76.2%     -    4s
     0     0 90077.2092    0  189 315273.000 90077.2092  71.4%     -    7s
H    0     0                    309486.00000 113880.544  63.2%     -   12s
     0     0 113880.637    0  199 309486.000 113880.637  63.2%     -   12s
     0     0 113880.637    0  199 309486.000 113880.637  63.2%     -   13s
H    0     0                    288245.00000 113880.637  60.5%     -   14s
     0     0 127672.131    0  198 288245.000 127672.131  55.7%     -   24s
     0     0 141821.354    0  200 288245.000 141821.354  50.8%     -   38s
     0     0 141821.894    0  200 288245.000 141821.894  50.8%     -   38s
H    0     0                    287028.02305 152967.493  46.7%     -   54s
H    0     0                    286382.72460 152967.493  46.6%     -   54s
H    0     0                    284520.36419 152967.493  46.2%     -   54s
H    0     0                    283286.52103 152967.493  46.0%     -   54s
H    0     0                    279335.29108 152967.493  45.2%     -   54s
H    0     0                    278389.32228 152967.493  45.1%     -   54s
H    0     0                    276709.11508 152967.493  44.7%     -   54s
H    0     0                    274845.59080 152967.493  44.3%     -   55s
H    0     0                    272863.07200 152967.493  43.9%     -   55s
H    0     0                    270067.36859 152967.493  43.4%     -   55s
H    0     0                    269215.59182 152967.493  43.2%     -   55s
H    0     0                    267058.50246 152967.493  42.7%     -   55s
H    0     0                    264503.60754 152967.493  42.2%     -   55s
H    0     0                    262566.00000 152967.493  41.7%     -   55s
H    0     0                    260417.00000 152967.493  41.3%     -   55s
H    0     0                    259862.00000 152967.493  41.1%     -   55s
     0     0 152967.493    0  198 259862.000 152967.493  41.1%     -   55s
H    0     0                    247309.00000 164695.350  33.4%     -   77s
     0     0 164695.350    0  200 247309.000 164695.350  33.4%     -   77s
     0     0 164697.220    0  200 247309.000 164697.220  33.4%     -   78s
     0     0 174779.528    0  196 247309.000 174779.528  29.3%     -   97s
H    0     0                    244829.39820 184077.164  24.8%     -  147s
H    0     0                    243771.44447 184077.164  24.5%     -  147s
H    0     0                    241969.66983 184077.164  23.9%     -  147s
H    0     0                    241173.06143 184077.164  23.7%     -  147s
H    0     0                    238695.59670 184077.164  22.9%     -  148s
H    0     0                    238519.36803 184077.164  22.8%     -  148s
H    0     0                    235385.31861 184077.164  21.8%     -  148s
H    0     0                    233305.45931 184077.164  21.1%     -  148s
H    0     0                    230649.58224 184077.164  20.2%     -  148s
H    0     0                    226799.00000 184077.164  18.8%     -  148s
     0     0 184077.164    0  196 226799.000 184077.164  18.8%     -  148s
     0     0 184114.003    0  196 226799.000 184114.003  18.8%     -  149s
     0     0 192114.343    0  194 226799.000 192114.343  15.3%     -  176s
H    0     0                    219877.00000 195184.674  11.2%     -  219s
     0     0 195184.674    0  196 219877.000 195184.674  11.2%     -  219s
     0     0 195926.373    0  196 219877.000 195926.373  10.9%     -  222s
     0     0 196165.395    0  196 219877.000 196165.395  10.8%     -  223s
     0     0 196225.826    0  196 219877.000 196225.826  10.8%     -  225s
     0     0 196225.826    0  196 219877.000 196225.826  10.8%     -  227s
     0     2 196225.826    0  196 219877.000 196225.826  10.8%     -  235s
    23    28 196769.371    7  189 219877.000 196769.371  10.5%  25.9  240s
    63    68 197474.225   17  181 219877.000 197225.191  10.3%  19.4  245s
    98   107 198364.408   25  173 219877.000 197225.191  10.3%  18.5  250s
   143   155 199324.970   36  162 219877.000 197225.191  10.3%  20.1  255s
   183   194 200229.907   47  151 219877.000 197225.191  10.3%  21.8  260s
   223   233 201567.765   56  142 219877.000 197225.191  10.3%  23.1  266s
   259   271 202726.045   64  134 219877.000 197225.191  10.3%  25.0  271s
   298   316 204081.770   72  127 219877.000 197225.191  10.3%  27.1  276s
   330   345 206740.858   79  120 219877.000 197225.191  10.3%  28.3  280s
   358   380 206797.231   84  115 219877.000 197225.191  10.3%  29.6  285s
   404   439 208523.098   94  104 219877.000 197225.191  10.3%  30.7  290s
   473   503 210330.037  107   91 219877.000 197225.191  10.3%  30.4  296s
   533   541 214736.349  123   72 219877.000 197225.191  10.3%  32.7  302s
   561   574 215748.307  129   65 219877.000 197225.191  10.3%  33.9  305s
   644   631     cutoff  168      219877.000 197231.207  10.3%  33.5  312s
   672   651 197448.104    8  188 219877.000 197448.104  10.2%  33.5  315s
   718   697 199094.241   22  176 219877.000 197475.343  10.2%  32.9  321s
H  733   688                    219526.00000 197475.343  10.0%  32.8  321s
   738   710 200028.714   28  170 219526.000 197475.343  10.0%  32.8  325s
H  760   714                    218836.00000 197475.343  9.76%  33.0  329s
H  771   713                    218823.00000 197475.343  9.76%  33.3  329s
   776   734 201927.105   38  159 218823.000 197475.343  9.76%  33.4  333s
   797   763 202687.326   42  155 218823.000 197475.343  9.76%  33.8  337s
   826   791 203413.089   47  150 218823.000 197475.343  9.76%  33.5  341s
   854   816 203917.562   51  147 218823.000 197475.343  9.76%  33.6  345s
   879   839 204990.022   60  138 218823.000 197475.343  9.76%  34.0  350s
   902   876 207260.562   66  132 218823.000 197475.343  9.76%  34.6  355s
   939   911 208445.648   79  119 218823.000 197475.343  9.76%  34.7  360s
   974   952 209719.263   88  110 218823.000 197475.343  9.76%  35.0  365s
  1015   999 211292.539   95  102 218823.000 197475.343  9.76%  35.4  372s
  1063  1000 213064.979   75  196 218823.000 197475.343  9.76%  36.1  399s
* 1064   950              12    215114.00000 215114.000  0.00%  36.0  407s

Explored 1064 nodes (62733 simplex iterations) in 407.36 seconds (209.74 work units)
Thread count was 8 (of 8 available processors)

Solution count 10: 215114 218823 218836 ... 238519

Optimal solution found (tolerance 1.00e-04)
Best objective 2.151140000000e+05, best bound 2.151140000000e+05, gap 0.0000%

Example: Facility Location

Model Reformulation

  • Warehouse \(w\) has to be opened if at least one supermarket is supplied. \[\sum_{s \in S} x_{ws} \leq |S| \cdot y_{w} \quad \forall w \in W\]
  • In most solutions, the left-hand side will be much smaller than \(|S| \cdot y_w\)
  • In the LP relaxation, due to the large Big-M value \(|S|\) and since we minimize \(f_w \cdot y_w\), the value for \(y_w\) can be set to a small fractional value
  • Constraint Disaggregation: If any single supermarket is supplied by a warehouse, the warehouse has to be opened. \[x_{ws} \leq y_{w} \quad \forall w \in W, \forall s \in S\]

Example: Facility Location

Python Code

import gurobipy as gp
from gurobipy import GRB

# data preparation ...

model = gp.Model("facility_location")
    
# add variables
x = model.addVars(numWarehouses, numSupermarkets, lb=0, ub=1, vtype=GRB.CONTINUOUS, name="x")
y = model.addVars(numWarehouses, vtype=GRB.BINARY, name="y")

# supermarket supply constraints
model.addConstrs((x.sum("*", s) == 1 for s in range(numSupermarkets)), name="Demand")

# strong warehouse opening and linking constraints
model.addConstrs((x[w, s] <= y[w] for s in range(numSupermarkets) for w in range(numWarehouses)), name="Open")

# minimize total costs
model.setObjective(x.prod(shippingCost) + y.prod(openingCost), GRB.MINIMIZE)

model.optimize()

Example: Facility Location

Optimize a model with 402000 rows, 400200 columns and 1200000 nonzeros
Model fingerprint: 0xab88c055
Variable types: 400000 continuous, 200 integer (200 binary)
Coefficient statistics:
  Matrix range     [1e+00, 1e+00]
  Objective range  [1e+00, 4e+03]
  Bounds range     [1e+00, 1e+00]
  RHS range        [1e+00, 1e+00]
Found heuristic solution: objective 1657011.0000
Presolve time: 2.35s
Presolved: 402000 rows, 400200 columns, 1200000 nonzeros
Variable types: 400000 continuous, 200 integer (200 binary)
Deterministic concurrent LP optimizer: primal simplex, dual simplex, and barrier
Showing barrier log only...

Root barrier log...

Ordering time: 0.18s

Barrier statistics:
 Dense cols : 200
 AA' NZ     : 8.000e+05
 Factor NZ  : 1.645e+06 (roughly 340 MB of memory)
 Factor Ops : 9.667e+07 (less than 1 second per iteration)
 Threads    : 2

                  Objective                Residual
Iter       Primal          Dual         Primal    Dual     Compl     Time
   0   2.21451667e+07  7.45226501e+05  2.00e+01 2.66e+02  7.12e+01     5s
   1   2.83097541e+06 -7.72382509e+05  2.48e+00 7.53e+01  7.12e+00     6s
   2   6.94893623e+05 -1.44052241e+05  6.66e-15 1.63e-01  7.08e-01     6s
   3   6.19409426e+05  3.44940542e+04  9.10e-15 1.61e-01  4.92e-01     7s
   4   5.64068664e+05  9.87373612e+04  1.38e-14 1.04e-01  3.91e-01     7s
   5   5.49580322e+05  1.16302608e+05  1.33e-14 6.42e-02  3.64e-01     8s
   6   5.25675690e+05  1.29417444e+05  1.60e-14 6.21e-02  3.33e-01     8s
   7   4.94701173e+05  1.38858058e+05  7.55e-15 6.10e-02  2.99e-01     9s
   8   4.45389485e+05  1.76495697e+05  7.55e-15 8.92e-03  2.26e-01    10s
   9   4.01222789e+05  1.97074403e+05  1.34e-14 1.80e-02  1.71e-01    10s
  10   3.72653325e+05  2.05428659e+05  1.43e-14 1.57e-02  1.40e-01    11s
  11   3.45938327e+05  2.09878961e+05  1.19e-14 1.31e-02  1.14e-01    12s
  12   3.15836621e+05  2.11984365e+05  4.77e-15 9.89e-03  8.72e-02    13s
  13   2.95957845e+05  2.13062637e+05  7.55e-15 7.99e-03  6.97e-02    13s
  14   2.79458149e+05  2.13924452e+05  2.55e-14 5.93e-03  5.51e-02    14s

Barrier performed 14 iterations in 13.93 seconds (4.14 work units)
Barrier solve interrupted - model solved by another algorithm

Concurrent spin time: 1.23s (can be avoided by choosing Method=3)

Solved with dual simplex

Root relaxation: objective 2.151140e+05, 13089 iterations, 11.13 seconds (2.90 work units)

    Nodes    |    Current Node    |     Objective Bounds      |     Work
 Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time

*    0     0               0    215114.00000 215114.000  0.00%     -   14s

Explored 1 nodes (13089 simplex iterations) in 14.05 seconds (4.26 work units)
Thread count was 8 (of 8 available processors)

Solution count 2: 215114 1.65701e+06 

Optimal solution found (tolerance 1.00e-04)
Best objective 2.151140000000e+05, best bound 2.151140000000e+05, gap 0.0000%

General (Nonlinear) Constraints

Python API for Function Constraints

Example: Natural Exponential

\[ \begin{align*} \min ~& -2x + e^x \\ \text{s. t. } ~& 0 \leq x \leq 1 \end{align*} \]

# pip install gurobipy

import gurobipy as gp

model = gp.Model("gen")

x = model.addVar(lb=0, ub=1, name="x")
y = model.addVar(name="y")

# y = exp(x)
gc = model.addGenConstrExp(x, y)

model.setObjective(-2 * x + y)

model.optimize()

Piecewise-Linear (PWL) approximation

  • Static:
    • Nonlinear function is PWL-approximated
    • Once before MIP solving starts
  • Cost vs. Accuracy:
    • More accurate PWL \(\rightarrow\) more segments
    • More segments \(\rightarrow\) more difficult to solve
  • Underestimate, overestimate, or somewhere in between?

Outer Approximation + Spatial Branch&Bound

New in Gurobi v11

  • Dynamic: At each branch-and-bound node, the approximation is refined
  • Exact: Produces globally optimal solutions (within tolerances), but can be expensive

Outer Approximation + Spatial Branch&Bound

Academic Program