Is there a way by which we can print the underlying algebraic form of constraints or objective function. For instance with AMPL
there is a handy functionality display
which prints the algebraic form of the constraint or the objective function. I understand that we can always write the model in an LP form and then investigate, but can we print (interactively) the constraint in the python console ?
A concrete example:
import gurobipy as gp
from gurobipy import GRB
products, price = gp.multidict({"table": 80, "chair": 45})
resources, availability = gp.multidict({"mahogany": 400, "labour": 450})
bom = {
("mahogany", "chair"): 5,
("mahogany", "table"): 20,
("labour", "chair"): 10,
("labour", "table"): 15,
}
model = gp.Model("furniture")
make = model.addVars(products, name="make", obj=list(price.values()), vtype=GRB.INTEGER)
res = model.addConstrs(
gp.quicksum(bom[r, p] * make[p] for p in products) <= availability[r]
for r in resources
)
model.ModelSense = GRB.MAXIMIZE
model.optimize()
Now, I make add another product to the formulation -
add_prod = "bed"
make[add_prod] = model.addVar(
obj=90, vtype=GRB.INTEGER, column=gp.Column([15, 18], res.values()), name="make[bed]"
)
model.optimize()
If, I want to verify whether the change I have made has happened in an expected manner, I want to print the constraint and objective function. I can write the model in an .lp
format but is there a way I can print the constraint, without having to look at the .lp
file. Especially, if the model is very large, and I want to see only one constraint, then seeing the entire lp file could be an overkill.
Model.getRow() retrieves the LinExpr object that represents the linear expression for a constraint, and Model.getObjective() retrieves the LinExpr or QuadExpr object for the objective function. If you simply want to print this for debugging, just print these objects directly like this:
model.update()
print(f"Obj: {model.getObjective()}")
for r in resources:
print(f"{res[r].ConstrName}: {model.getRow(res[r])} {res[r].Sense} {res[r].RHS}")
If you need to work with the variables and coefficients, then you can iterate over a LinExpr object like this:
obj = model.getObjective()
for i in range(obj.size()):
print(f"{obj.getCoeff(i)} * {obj.getVar(i).VarName}")
Finally, it's good practice to name constraints by adding a string when calling Model.addConstrs():
res = model.addConstrs(
(gp.quicksum(bom[r, p] * make[p] for p in products) <= availability[r]
for r in resources), name="avail"
)
Note that I added a call to Model.update() to process the model modifications; without this, you may not see the changes to your model.
(Disclaimer: I work at Gurobi).