diff --git a/miplearn/benchmark.py b/miplearn/benchmark.py index 3013395..ab9aea7 100644 --- a/miplearn/benchmark.py +++ b/miplearn/benchmark.py @@ -78,9 +78,12 @@ class BenchmarkRunner: @staticmethod def _compute_gap(ub, lb): - # solver did not find a solution and/or bound, use maximum gap possible if lb is None or ub is None or lb * ub < 0: + # solver did not find a solution and/or bound, use maximum gap possible return 1.0 + elif abs(ub - lb) < 1e-6: + # avoid division by zero when ub = lb = 0 + return 0.0 else: # divide by max(abs(ub),abs(lb)) to ensure gap <= 1 return (ub - lb) / max(abs(ub), abs(lb)) @@ -97,8 +100,8 @@ class BenchmarkRunner: result["Solver"] = solver_name result["Instance"] = instance result["Gap"] = self._compute_gap( - ub=result["Lower bound"], - lb=result["Upper bound"], + ub=result["Upper bound"], + lb=result["Lower bound"], ) result["Mode"] = solver.mode self.results = self.results.append(pd.DataFrame([result])) diff --git a/miplearn/tests/test_benchmark.py b/miplearn/tests/test_benchmark.py index d7bb0cf..ab838df 100644 --- a/miplearn/tests/test_benchmark.py +++ b/miplearn/tests/test_benchmark.py @@ -35,3 +35,13 @@ def test_benchmark(): benchmark = BenchmarkRunner(test_solvers) benchmark.load_results("/tmp/benchmark.csv") assert benchmark.raw_results().values.shape == (12, 14) + + +def test_gap(): + assert BenchmarkRunner._compute_gap(ub=0.0, lb=0.0) == 0.0 + assert BenchmarkRunner._compute_gap(ub=1.0, lb=0.5) == 0.5 + assert BenchmarkRunner._compute_gap(ub=1.0, lb=1.0) == 0.0 + assert BenchmarkRunner._compute_gap(ub=1.0, lb=-1.0) == 1.0 + assert BenchmarkRunner._compute_gap(ub=1.0, lb=None) == 1.0 + assert BenchmarkRunner._compute_gap(ub=None, lb=1.0) == 1.0 + assert BenchmarkRunner._compute_gap(ub=None, lb=None) == 1.0