PyConDE & PyData Berlin 2024
Principal Developer, Gurobi Optimization
pip install gurobipy
Decision variables
An objective function measuring the KPIs of interest
Constraints involving the decision variables
Linear optimization problem \[\begin{align*} \min_x \quad & c^T x \\ \mbox{s.t.}\quad & A x = b\\ & x \ge 0 \end{align*}\]
Mixed-integer linear optimization problem: \[\begin{align*} \min_x \quad & c^T x \\ \mbox{s.t.}\quad & A x = b\\ & x \ge 0\\ & x_i \in \mathbf{Z}, i \in I \end{align*}\]
Mixed-integer quadratically constrained optimization problems
Mixed-integer nonlinear, nonconvex optimization problems
Many other variations…
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
Decision variables
\(x_{ij} \in \{0,1\}\): assign project \(i\) to team \(j\)?
Objective function
Maximize profit from completed projects
Constraints
\[\begin{align*} \max_{x} \quad & \sum_{i,j} p_i x_{ij}\\ & \sum_i w_i x_{ij} \le c_j \quad \mbox{for all $j$}\\ & \sum_j x_{ij} \le 1 \quad \mbox{for all $i$}\\ & x_{ij} \in \{0,1\} \end{align*}\]
>>> projects.head(3) # w_i
resource
project
p0 1.1
p1 1.4
p2 1.2
>>> teams.head(3) # c_j
capacity
team
t0 2.4
t1 1.8
t2 1.1
>>> project_values.head(5)
profit
project team
p0 t4 0.4
p1 t4 1.3
p2 t0 1.7
t1 1.7
t2 1.7
import gurobipy as gp
import gurobipy_pandas as gppd
model = gp.Model()
model.ModelSense = GRB.MAXIMIZE
assignments = project_values.gppd.add_vars(
model, vtype=GRB.BINARY, obj="profit", name="x"
)
assignments.head() # p_ij & x_ij
profit x
project team
p0 t4 0.4 <gurobi.Var x[p0,t4]>
p1 t4 1.3 <gurobi.Var x[p1,t4]>
p2 t0 1.7 <gurobi.Var x[p2,t0]>
t1 1.7 <gurobi.Var x[p2,t1]>
t2 1.7 <gurobi.Var x[p2,t2]>
capacity_constraints = gppd.add_constrs(
model,
(projects["resource"] * assignments["x"]).groupby("team").sum(),
GRB.LESS_EQUAL,
teams["capacity"],
name='capacity',
)
capacity_constraints.apply(model.getRow).head()
team
t0 1.2 x[p2,t0] + 0.9 x[p4,t0] + 1.3 x[p5,t0] + x...
t1 1.2 x[p2,t1] + 0.9 x[p4,t1] + 1.3 x[p5,t1] + x...
t2 1.2 x[p2,t2] + 0.9 x[p4,t2] + 1.3 x[p5,t2] + x...
t3 1.2 x[p2,t3] + 0.9 x[p4,t3] + 1.3 x[p5,t3] + x...
t4 1.1 x[p0,t4] + 1.4 x[p1,t4] + 1.2 x[p2,t4] + 1...
Name: capacity, dtype: object
allocate_once = gppd.add_constrs(
model,
assignments['x'].groupby('project').sum(),
GRB.LESS_EQUAL,
1.0,
name="allocate_once",
)
allocate_once.apply(model.getRow).head()
project
p0 x[p0,t4]
p1 x[p1,t4]
p10 x[p10,t0] + x[p10,t1] + x[p10,t2] + x[p10,t3] ...
p11 x[p11,t0] + x[p11,t1] + x[p11,t2] + x[p11,t3] ...
p12 x[p12,t3] + x[p12,t4]
Name: allocate_once, dtype: object
model.optimize()
(
assignments["x"].gppd.X.to_frame()
.query("x >= 0.9").reset_index()
.groupby("team").agg({"project": list})
)
project
team
t0 [p4, p5]
t1 [p2]
t2 [p11]
t3 [p6, p29]
t4 [p14, p15, p26]
https://github.com/Gurobi/gurobipy-pandas
from sklearn import datasets
from sklearn.model_selection import train_test_split
from gurobi_optimods.regression import LADRegression
# Load the diabetes dataset
diabetes = datasets.load_diabetes()
# Split data for fit assessment
X_train, X_test, y_train, y_test = train_test_split(
diabetes["data"], diabetes["target"], random_state=42
)
# Fit model and obtain predictions
lad = LADRegression()
lad.fit(X_train, y_train)
y_pred = lad.predict(X_test)
A package to use trained regression models in mathematical optimization models.
Supported APIs: sklearn, Keras, PyTorch, XGBoost, LightGBM
Given a trained network, how robust is the classification w.r.t. noise?
Classified as “4”
Classified as “9”
pip install gurobipy-pandas
Thanks!
©️ Gurobi Optimization