flowchart LR id1[Obj 1] --- id2[Obj 2] --- id3[Obj 3]
Seminars in Operations Research, ULisboa
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*} \]
Warning
You need to be an OR + Math + IT expert :)
We help commercial customers with:
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
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) \]
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*} \]
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()
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%
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()
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%
Example: Natural Exponential
\[ \begin{align*} \min ~& -2x + e^x \\ \text{s. t. } ~& 0 \leq x \leq 1 \end{align*} \]
©️ Gurobi Optimization