This notebook contains course material from CBE40455 by Jeffrey Kantor (jeff at nd.edu); the content is available on Github. The text is released under the CC-BY-NC-ND-4.0 license, and code is released under the MIT license.
Gurobi is a commercial, state-of-the-art mathematical programming engines used in a diverse array of industries. It is available under academic licensing terms that allow free use by faculty and students in accredited insitutions, and comes with a very complete Python interface. The purpose of this notebook is to help you get started using Gurobi via the Python interface.
from gurobi import *
m = Model()
v0 = m.addVar()
v1 = m.addVar()
m.update()
m.getVars()
m.addConstr(v0 - v1 <= 4)
m.addConstr(v0 + v1 <= 4)
m.addConstr(-0.25*v0 + v1 <= 1)
m.setObjective(v1, GRB.MAXIMIZE)
m.params.outputflag = 0
m.optimize()
[v0.x,v1.x]
[2.4, 1.6]
import pandas as pd
LOCATIONS = ['Austin','Boston','Chicago','Denver','Edmonton']
distances = pd.DataFrame(index=LOCATIONS)
distances['Atlanta'] = [921,1078,716,1400,3764]
distances['Boise'] = [1627, 2661, 1693, 815, 1718]
distances['Charlotte'] = [1166, 837, 756, 1561, 3848]
distances['Dallas'] = [196, 1767, 925, 788, 3310]
distances['Fresno'] = [1594, 3107, 2140, 1142, 2835]
distances
Atlanta | Boise | Charlotte | Dallas | Fresno | |
---|---|---|---|---|---|
Austin | 921 | 1627 | 1166 | 196 | 1594 |
Boston | 1078 | 2661 | 837 | 1767 | 3107 |
Chicago | 716 | 1693 | 756 | 925 | 2140 |
Denver | 1400 | 815 | 1561 | 788 | 1142 |
Edmonton | 3764 | 1718 | 3848 | 3310 | 2835 |
import gurobi as grb
m = grb.Model()
RESOURCES = distances.index
TASKS = distances.columns
x = m.addVars(RESOURCES,TASKS,vtype=grb.GRB.BINARY)
m.addConstrs(sum([x[r,t] for t in TASKS]) == 1 for r in RESOURCES)
m.addConstrs(sum([x[r,t] for r in RESOURCES]) == 1 for t in TASKS)
m.setObjective(sum([distances.ix[r,t]*x[r,t] for r in RESOURCES for t in TASKS]),
grb.GRB.MINIMIZE)
m.optimize();
m.status
Optimize a model with 10 rows, 25 columns and 50 nonzeros Variable types: 0 continuous, 25 integer (25 binary) Coefficient statistics: Matrix range [1e+00, 1e+00] Objective range [2e+02, 4e+03] Bounds range [1e+00, 1e+00] RHS range [1e+00, 1e+00] Found heuristic solution: objective 8790 Presolve time: 0.00s Presolved: 10 rows, 25 columns, 50 nonzeros Variable types: 0 continuous, 25 integer (25 binary) Root relaxation: objective 4.609000e+03, 6 iterations, 0.00 seconds Nodes | Current Node | Objective Bounds | Work Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time * 0 0 0 4609.0000000 4609.00000 0.00% - 0s Explored 0 nodes (6 simplex iterations) in 0.02 seconds Thread count was 8 (of 8 available processors) Solution count 2: 4609 8790 Pool objective bound 4609 Optimal solution found (tolerance 1.00e-04) Best objective 4.609000000000e+03, best bound 4.609000000000e+03, gap 0.0000%
2
for r in RESOURCES:
for t in TASKS:
if int(round(x[r,t].x)):
print("Assign {0:10s} to {1:10s} Cost: {2:5.0f}".format(r,t,distances.ix[r,t]))
Assign Austin to Dallas Cost: 196 Assign Boston to Charlotte Cost: 837 Assign Chicago to Atlanta Cost: 716 Assign Denver to Fresno Cost: 1142 Assign Edmonton to Boise Cost: 1718