From 4057a6550608e2db0753f69d0ebd7089bb8927b6 Mon Sep 17 00:00:00 2001 From: "Alinson S. Xavier" Date: Thu, 7 Jan 2021 11:54:00 -0600 Subject: [PATCH] ConvertTightIneqs: Convert only inequalities, not equalities --- miplearn/components/steps/convert_tight.py | 2 +- miplearn/components/steps/drop_redundant.py | 2 +- miplearn/components/tests/test_relaxation.py | 6 +++--- miplearn/solvers/gurobi.py | 5 +++-- miplearn/solvers/internal.py | 2 +- miplearn/solvers/pyomo/base.py | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/miplearn/components/steps/convert_tight.py b/miplearn/components/steps/convert_tight.py index 4b7fb96..bfd1bf6 100644 --- a/miplearn/components/steps/convert_tight.py +++ b/miplearn/components/steps/convert_tight.py @@ -57,7 +57,7 @@ class ConvertTightIneqsIntoEqsStep(Component): logger.info(f"Converted {n_converted} inequalities into equalities") def after_solve(self, solver, instance, model, results): - instance.slacks = solver.internal_solver.get_constraint_slacks() + instance.slacks = solver.internal_solver.get_inequality_slacks() def fit(self, training_instances): logger.debug("Extracting x and y...") diff --git a/miplearn/components/steps/drop_redundant.py b/miplearn/components/steps/drop_redundant.py index 7682bd2..f642bfa 100644 --- a/miplearn/components/steps/drop_redundant.py +++ b/miplearn/components/steps/drop_redundant.py @@ -68,7 +68,7 @@ class DropRedundantInequalitiesStep(Component): logger.info("Extracted %d predicted constraints" % len(self.pool)) def after_solve(self, solver, instance, model, results): - instance.slacks = solver.internal_solver.get_constraint_slacks() + instance.slacks = solver.internal_solver.get_inequality_slacks() def fit(self, training_instances): logger.debug("Extracting x and y...") diff --git a/miplearn/components/tests/test_relaxation.py b/miplearn/components/tests/test_relaxation.py index e901543..c172c7a 100644 --- a/miplearn/components/tests/test_relaxation.py +++ b/miplearn/components/tests/test_relaxation.py @@ -14,7 +14,7 @@ def _setup(): internal = solver.internal_solver = Mock(spec=InternalSolver) internal.get_constraint_ids = Mock(return_value=["c1", "c2", "c3", "c4"]) - internal.get_constraint_slacks = Mock( + internal.get_inequality_slacks = Mock( side_effect=lambda: { "c1": 0.5, "c2": 0.0, @@ -112,8 +112,8 @@ def test_drop_redundant(): # LearningSolver calls after_solve component.after_solve(solver, instance, None, None) - # Should query slack for all constraints - internal.get_constraint_slacks.assert_called_once() + # Should query slack for all inequalities + internal.get_inequality_slacks.assert_called_once() # Should store constraint slacks in instance object assert hasattr(instance, "slacks") diff --git a/miplearn/solvers/gurobi.py b/miplearn/solvers/gurobi.py index e76f738..f469c65 100644 --- a/miplearn/solvers/gurobi.py +++ b/miplearn/solvers/gurobi.py @@ -271,8 +271,9 @@ class GurobiSolver(InternalSolver): else: raise Exception("Unknown sense: %s" % sense) - def get_constraint_slacks(self): - return {c.ConstrName: c.Slack for c in self.model.getConstrs()} + def get_inequality_slacks(self): + ineqs = [c for c in self.model.getConstrs() if c.sense != "="] + return {c.ConstrName: c.Slack for c in ineqs} def set_constraint_sense(self, cid, sense): c = self.model.getConstrByName(cid) diff --git a/miplearn/solvers/internal.py b/miplearn/solvers/internal.py index 84c946b..334175a 100644 --- a/miplearn/solvers/internal.py +++ b/miplearn/solvers/internal.py @@ -184,7 +184,7 @@ class InternalSolver(ABC): pass @abstractmethod - def get_constraint_slacks(self): + def get_inequality_slacks(self): """ Returns a dictionary mapping constraint name to the constraint slack in the current solution. diff --git a/miplearn/solvers/pyomo/base.py b/miplearn/solvers/pyomo/base.py index d44de7e..eca4903 100644 --- a/miplearn/solvers/pyomo/base.py +++ b/miplearn/solvers/pyomo/base.py @@ -252,7 +252,7 @@ class BasePyomoSolver(InternalSolver): def relax(self): raise Exception("not implemented") - def get_constraint_slacks(self): + def get_inequality_slacks(self): raise Exception("not implemented") def set_constraint_sense(self, cid, sense):