PyPI in 2023: 1.2+ Trillion requests, 607+ Petabytes served
PyCon conference tour
Embraced by schools and academia
Next generation of Python developers getting industry ready while we speak
Domain agnostic
“Good bye!” domain specific languages
import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Fetches and installs gurobipy including optimizer libraries
All Gurobi features supported, no restrictions
Add your license information as usual
Term-based API
\[
\begin{align*}
\max \quad & x + y + 2z\\
\mbox{s.t.} \quad & x + 2y + 3z \le 4\\
& x + y \ge 1\\
& x, y, z \; \text{binary}
\end{align*}
\]
import gurobipy as gpm = gp.Model("mip1")x = m.addVar(vtype=GRB.BINARY)y = m.addVar(vtype=GRB.BINARY)z = m.addVar(vtype=GRB.BINARY)m.setObjective(x + y +2* z, gp.GRB.MAXIMIZE)m.addConstr(x +2* y +3* z <=4)m.addConstr(x + y >=1)
Write model entities term-by-term
Use dicts for sparse multidimensional index sets
Extends nicely to iteration via dictionary comprehension
Matrix-Friendly API
Build models entities based on ndarray-like data, using matrix variables (MVar):
x = model.addMVar(shape)
A class representing an ndarray of optimization variables
Understands Python’s matmul operator @
Very efficient if data comes in naturally
as an ndarray or
a SciPy sparse matrix
Indexing like in NumPy
Slicing like in NumPy
Broadcasting like in NumPy
… like in NumPy!
Matrix-friendly example
\[
\begin{align*}
\min \; & x^T Q x \\
\mbox{s.t.} \; & Ax \geq b \\
& 0 \leq x \leq 1
\end{align*}
\]
import gurobipy as gpimport numpy as npimport scipy.sparse as spm = gp.Model()Q = sp.diags([1, 2, 3])A = np.array([ [1, 2, 3], [1, 1, 0] ])x = m.addMVar(3, ub=1.0)m.setObjective(x @ Q @ x)m.addConstr(A @ x >=1)
Automatic performance monitoring of common modelling patterns
gurobipy-pandas
Project-Team assignment
We’re running a fantasy consulting company that is organized by a set of fixed teams \(J\), and we have a set of projects \(I\) that await to be worked on. Which team should be assigned to which project?
Data
Profit of completing project \(i \in I\): \(p_i\)
Resource requirement for project \(i \in I\): \(w_i\)
Capacity of team \(j \in J\): \(c_j\)
Decision variables
\(x_{ij} \in \{0,1\}\): assign project \(i\) to team \(j\)?
Has a data-driven API for a common optimization problem
Takes data in “natural” form, returns a solution in “natural” form
Solves a mathematical optimization problem using Gurobi technology
Least absolute value (LAD) regression
from sklearn import datasetsfrom sklearn.model_selection import train_test_splitfrom gurobi_optimods.regression import LADRegression# Load the diabetes datasetdiabetes = datasets.load_diabetes()# Split data for fit assessmentX_train, X_test, y_train, y_test = train_test_split( diabetes["data"], diabetes["target"], random_state=42)# Fit model and obtain predictionslad = LADRegression()lad.fit(X_train, y_train)y_pred = lad.predict(X_test)
LAD is more robust than ordinary linear regression w.r.t. outliers