You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
45 lines
1.3 KiB
45 lines
1.3 KiB
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
|
# Copyright (C) 2020-2023, UChicago Argonne, LLC. All rights reserved.
|
|
# Released under the modified BSD license. See COPYING.md for more details.
|
|
import logging
|
|
from typing import Any, Hashable, List
|
|
|
|
import pyomo.environ as pe
|
|
|
|
from miplearn.solvers.pyomo import PyomoModel
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _build_model() -> PyomoModel:
|
|
m = pe.ConcreteModel()
|
|
m.x = pe.Var(bounds=(0, 5), domain=pe.Integers)
|
|
m.obj = pe.Objective(expr=-m.x)
|
|
m.cons = pe.ConstraintList()
|
|
|
|
def lazy_separate(model: PyomoModel) -> List[Hashable]:
|
|
model.solver.cbGetSolution(vars=[m.x])
|
|
if m.x.value > 0.5:
|
|
return [m.x.value]
|
|
else:
|
|
return []
|
|
|
|
def lazy_enforce(model: PyomoModel, violations: List[Any]) -> None:
|
|
for v in violations:
|
|
model.add_constr(m.cons.add(m.x <= round(v - 1)))
|
|
|
|
return PyomoModel(
|
|
m,
|
|
"gurobi_persistent",
|
|
lazy_separate=lazy_separate,
|
|
lazy_enforce=lazy_enforce,
|
|
)
|
|
|
|
|
|
def test_pyomo_callback() -> None:
|
|
model = _build_model()
|
|
model.optimize()
|
|
assert model._lazy is not None
|
|
assert len(model._lazy) > 0
|
|
assert model.inner.x.value == 0.0
|