Gurobi / gurobipy-pandas

Convenience wrapper for building optimization models from pandas data
https://gurobipy-pandas.readthedocs.io/en/stable/
Apache License 2.0
83 stars 15 forks source link

Accept constraint senses as a Series or column #59

Closed simonbowly closed 8 months ago

simonbowly commented 9 months ago

Implements #58, so users can do:

import pandas as pd
import gurobipy as gp
import gurobipy_pandas as gppd

data = pd.DataFrame(
    {
        "bound": ["upper", "lower", "eq", "upper", "lower"],
        "a": [1.0, 2.0, -3.0, 4.0, -5.0],
        "b": [5.0, -4.0, 3.0, -2.0, 1.0],
        "c": [1.1, -2.1, 3.6, -1.5, 1.2],
    }
)

with gp.Env() as env, gp.Model(env=env) as model:
    frame = (
        data.gppd.add_vars(model, name="x")
        .gppd.add_vars(model, name="y")
        .assign(
            lhs=lambda df: df["a"] * df["x"] + df["b"] * df["y"],
            sense=lambda df: df["bound"].map({"lower": ">", "upper": "<", "eq": "="}),
        )
        .gppd.add_constrs(model, lhs="lhs", sense="sense", rhs="c", name="constr")
    )
    model.write("model1.lp")

or:

with gp.Env() as env, gp.Model(env=env) as model:
    x = gppd.add_vars(model, data.index, name="x")
    y = gppd.add_vars(model, data.index, name="y")
    constrs = gppd.add_constrs(
        model,
        data["a"] * x + data["b"] * y,
        data["bound"].map({"lower": ">", "upper": "<", "eq": "="}),
        data["c"],
        name="constr",
    )
    model.write("model2.lp")

to produce the following LP:

\ LP format - for model browsing. Use MPS format to capture full model detail.
Minimize

Subject To
 constr[0]: x[0] + 5 y[0] <= 1.1
 constr[1]: 2 x[1] - 4 y[1] >= -2.1
 constr[2]: - 3 x[2] + 3 y[2] = 3.6
 constr[3]: 4 x[3] - 2 y[3] <= -1.5
 constr[4]: - 5 x[4] + y[4] >= 1.2
Bounds
End