Adding Specialized Constraints¶
gurobipy-pandas
helper methods only cover building linear and quadratic
constraints. In some cases you may need to build other constraint types, such as
SOS or general constraints, using pandas series of variables or expressions.
This page provides recipes for these cases.
Indicator Constraints¶
This example builds a set of indicator constraints, such that the linear constraint \(x_i + y_i \le 1.0\) is enforced if the corresponding binary variable \(z_i\) is equal to 1.
>>> import pandas as pd
>>> import gurobipy as gp
>>> from gurobipy import GRB
>>> import gurobipy_pandas as gppd
>>> gppd.set_interactive()
>>> model = gp.Model()
>>> index = pd.RangeIndex(5)
>>> x = gppd.add_vars(model, index, name="x")
>>> y = gppd.add_vars(model, index, name="y")
>>> z = gppd.add_vars(model, index, vtype=GRB.BINARY, name="z")
There is no built-in gurobipy-pandas
method to add this constraint type. To
add indicator constraints, align your variables in a dataframe, then iterate
over the rows, creating a constraint for each row. To iterate over rows
efficiently, use .itertuples()
, and call the addGenConstrIndicator
function of the Gurobi model.
>>> df = pd.DataFrame({"z": z, "expression": x + y})
>>> df
z expression
0 <gurobi.Var z[0]> x[0] + y[0]
1 <gurobi.Var z[1]> x[1] + y[1]
2 <gurobi.Var z[2]> x[2] + y[2]
3 <gurobi.Var z[3]> x[3] + y[3]
4 <gurobi.Var z[4]> x[4] + y[4]
>>> constrs = []
>>> for row in df.itertuples(index=False):
... constr = model.addGenConstrIndicator(
... row.z, 1.0, row.expression, GRB.LESS_EQUAL, 1.0
... )
... constrs.append(constr)
>>> indicators = pd.Series(index=df.index, data=constrs, name="ind")
The resulting indicators
series stores the newly added indicator constraint
objects.
SOS Constraints¶
This example builds the constraint \(\text{SOS1}(x_i, y_i)\) for each \(i\) in the index.
>>> import pandas as pd
>>> import gurobipy as gp
>>> from gurobipy import GRB
>>> import gurobipy_pandas as gppd
>>> gppd.set_interactive()
>>> model = gp.Model()
>>> index = pd.RangeIndex(5)
>>> x = gppd.add_vars(model, index, name="x")
>>> y = gppd.add_vars(model, index, name="y")
There is no built-in gurobipy-pandas
method to add this constraint type. To
add SOS constraints, align your variables in a dataframe, then iterate over the
rows, creating a constraint for each row. To iterate over rows efficiently, use
.itertuples()
, and call the addSOS
function of the Gurobi model.
>>> df = pd.DataFrame({"x": x, "y": y})
>>> df
x y
0 <gurobi.Var x[0]> <gurobi.Var y[0]>
1 <gurobi.Var x[1]> <gurobi.Var y[1]>
2 <gurobi.Var x[2]> <gurobi.Var y[2]>
3 <gurobi.Var x[3]> <gurobi.Var y[3]>
4 <gurobi.Var x[4]> <gurobi.Var y[4]>
>>> cs = []
>>> for row in df.itertuples(index=False):
... c = model.addSOS(GRB.SOS_TYPE1, [row.x, row.y])
... cs.append(c)
>>> sos = pd.Series(index=df.index, data=cs, name="sos")
The resulting sos
series stores the newly added SOS constraint objects.