Reputation: 162
I have started using Pyomo for modelling of MILPs and need to add problem specific cutting planes at certain MILP-feasible solutions. I know that it is possible to do that via callbacks in Gurobi's own gurobipy API. However, since I am using Pyomo atm I would like to stick to it if possible. I have seen that there exist persistent/direct solver IO options, however, I could not figure out how to make use of those options for my purposes.
Any help is appreciated.
Upvotes: 1
Views: 1612
Reputation: 2345
Callbacks and lazy constraints are currently supported by Pyomo for the Gurobi Persistent solver interface. Here is a small example from the documentation of that interface:
from gurobipy import GRB
import pyomo.environ as pe
from pyomo.core.expr.taylor_series import taylor_series_expansion
m = pe.ConcreteModel()
m.x = pe.Var(bounds = (0, 4))
m.y = pe.Var(within = pe.Integers, bounds = (0, None))
m.obj = pe.Objective(expr = 2 * m.x + m.y)
m.cons = pe.ConstraintList() # for the cutting planes
def _add_cut(xval):
# a function to generate the cut
m.x.value = xval
return m.cons.add(m.y >= taylor_series_expansion((m.x - 2) ** 2))
_add_cut(0) # start with 2 cuts at the bounds of x
_add_cut(4) # this is an arbitrary choice
opt = pe.SolverFactory('gurobi_persistent')
opt.set_instance(m)
opt.set_gurobi_param('PreCrush', 1)
opt.set_gurobi_param('LazyConstraints', 1)
def my_callback(cb_m, cb_opt, cb_where):
if cb_where == GRB.Callback.MIPSOL:
cb_opt.cbGetSolution(vars = [m.x, m.y])
if m.y.value < (m.x.value - 2) ** 2 - 1e-6:
print('adding cut')
cb_opt.cbLazy(_add_cut(m.x.value))
opt.set_callback(my_callback)
opt.solve()
assert abs(m.x.value - 1) <= 1e-6
assert abs(m.y.value - 1) <= 1e-6
Changed value of parameter PreCrush to 1
Prev: 0 Min: 0 Max: 1 Default: 0
Changed value of parameter LazyConstraints to 1
Prev: 0 Min: 0 Max: 1 Default: 0
adding cut
adding cut
adding cut
adding cut
adding cut
adding cut
adding cut
adding cut
For further details on the methods available within this Pyomo callback interface, see the GurobiPersistent
class.
Upvotes: 1