Pyomo和Gurobi:Pyomo是否支持对Gurobi的求解器回调?

问题描述 投票:0回答:1

我已经开始使用Pyomo对MILP进行建模,并需要在某些MILP可行的解决方案中添加特定于问题的切割平面。我知道可以通过Gurobi自己的gurobipy API中的回调来做到这一点。但是,由于我使用的是Pyomo atm,因此我会尽可能坚持下去。我已经看到存在持久性/直接求解器IO选项,但是,我不知道如何将这些选项用于我的目的。

感谢您的任何帮助。

pyomo gurobi
1个回答
0
投票

Pyomo当前支持Gurobi持久求解器界面的回调和惰性约束。这是该接口文档中的一个小示例:

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
© www.soinside.com 2019 - 2024. All rights reserved.