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。