Temporarily remove native solver callbacks; add iteration_cb

This commit is contained in:
2020-09-23 17:30:39 -05:00
parent e731f46b72
commit 425ea2b7cc
10 changed files with 201 additions and 189 deletions

View File

@@ -6,10 +6,9 @@ import logging
from io import StringIO
import pyomo.environ as pe
from miplearn import BasePyomoSolver
from miplearn.problems.knapsack import ChallengeA
from miplearn.solvers import RedirectOutput
from miplearn import BasePyomoSolver, GurobiSolver
from miplearn.solvers import RedirectOutput
from . import _get_instance, _get_internal_solvers
logger = logging.getLogger(__name__)
@@ -99,17 +98,59 @@ def test_internal_solver():
assert solution["x"][2] == 1.0
assert solution["x"][3] == 1.0
# Add a brand new constraint
if isinstance(solver, BasePyomoSolver):
model.cut = pe.Constraint(expr=model.x[0] <= 0.5)
model.cut = pe.Constraint(expr=model.x[0] <= 0.0, name="cut")
solver.add_constraint(model.cut)
solver.solve_lp()
assert model.x[0].value == 0.5
elif isinstance(solver, GurobiSolver):
x = model.getVarByName("x[0]")
solver.add_constraint(x <= 0.0, name="cut")
else:
raise Exception("Illegal state")
# New constraint should affect solution and should be listed in
# constraint ids
assert solver.get_constraints_ids() == ["eq_capacity", "cut"]
stats = solver.solve()
assert stats["Lower bound"] == 1030.0
if isinstance(solver, GurobiSolver):
# Extract new constraint
cobj = solver.extract_constraint("cut")
# New constraint should no longer affect solution and should no longer
# be listed in constraint ids
assert solver.get_constraints_ids() == ["eq_capacity"]
stats = solver.solve()
assert stats["Lower bound"] == 1183.0
# New constraint should not be satisfied by current solution
assert not solver.is_constraint_satisfied(cobj)
# Re-add constraint
solver.add_constraint(cobj)
# Constraint should affect solution again
assert solver.get_constraints_ids() == ["eq_capacity", "cut"]
stats = solver.solve()
assert stats["Lower bound"] == 1030.0
# New constraint should now be satisfied
assert solver.is_constraint_satisfied(cobj)
# def test_node_count():
# for solver in _get_internal_solvers():
# challenge = ChallengeA()
# solver.set_time_limit(1)
# solver.set_instance(challenge.test_instances[0])
# stats = solver.solve(tee=True)
# assert stats["Nodes"] > 1
def test_iteration_cb():
for solver_class in _get_internal_solvers():
logger.info("Solver: %s" % solver_class)
instance = _get_instance(solver_class)
solver = solver_class()
solver.set_instance(instance)
count = 0
def custom_iteration_cb():
nonlocal count
count += 1
return count < 5
solver.solve(iteration_cb=custom_iteration_cb)
assert count == 5