Federico
Federico

Reputation: 2133

Obtain all feasible solutions in Python while Gurobi is running

Using the gurobipy Python library for Gurobi I would like to obtain all feasible models while the solver is running, to store or process them on the fly. I found that callbacks seem the best way to do so. However:

  1. Is it enough to check where == GRB.Callback.MIPSOL to obtain all feasible solutions, as in the code below? Is it guaranteed that the objective function strictly improves between consecutive MIPSOL calls of the callback?
  2. If I try to read the value of the variables from inside the callback (line (b) below) I get an AttributeError, while cbGetSolution (line (a) below) works fine but forces me to map each value in the returned list to the appropriate variable. Is there a way to make line (b) work?
import gurobipy as gp
from gurobipy import GRB

model = gp.Model("mymodel")
y = model.addVar(vtype=GRB.INTEGER)
x = model.addVar(vtype=GRB.INTEGER)
model.update()
model.addConstr(x + 3 * y <= 1000)
model.addConstr(5 * x + y <= 1000)
model.setObjective(x + y, GRB.MAXIMIZE)

def mycallback(model, where):
    if where == GRB.Callback.MIPSOL:
        print("Feasible solution:", model.cbGetSolution(model._vars))  # (a) Ok
        print("Feasible solution:", x.x, y.x)  # (b) AttributeError

model._vars = model.getVars()
model.optimize(mycallback)

if model.status == GRB.OPTIMAL:
    print("Optimal solution:", x.x, y.x)

Upvotes: 1

Views: 770

Answers (1)

mattmilten
mattmilten

Reputation: 6716

There is currently no other way than (a) to query the solution values from within a callback. In general, only improving solutions should be found as "new solution". To be sure, you could check the objective value against the previous incumbent.

You can also use the SolFiles parameter to write new solutions to disk right away.

Upvotes: 0

Related Questions