Pyomo 和 Gurobi:Pyomo 是否支持求解器回调到 Gurobi?
Pyomo and Gurobi: Does Pyomo support solver callbacks to Gurobi?
我已经开始使用 Pyomo 对 MILP 进行建模,并且需要在某些 MILP 可行的解决方案中添加问题特定的切割平面。我知道可以通过 Gurobi 自己的 gurobipy API 中的回调来做到这一点。但是,由于我使用的是 Pyomo atm,所以如果可能的话,我想坚持使用它。我已经看到存在 persistent/direct 求解器 IO 选项,但是,我无法弄清楚如何将这些选项用于我的目的。
感谢任何帮助。
Pyomo 目前支持 Gurobi Persistent 求解器接口的回调和惰性约束。这是该接口文档中的一个小示例:
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
有关此 Pyomo 回调接口中可用方法的更多详细信息,请参阅 GurobiPersistent
class。
我已经开始使用 Pyomo 对 MILP 进行建模,并且需要在某些 MILP 可行的解决方案中添加问题特定的切割平面。我知道可以通过 Gurobi 自己的 gurobipy API 中的回调来做到这一点。但是,由于我使用的是 Pyomo atm,所以如果可能的话,我想坚持使用它。我已经看到存在 persistent/direct 求解器 IO 选项,但是,我无法弄清楚如何将这些选项用于我的目的。
感谢任何帮助。
Pyomo 目前支持 Gurobi Persistent 求解器接口的回调和惰性约束。这是该接口文档中的一个小示例:
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
有关此 Pyomo 回调接口中可用方法的更多详细信息,请参阅 GurobiPersistent
class。