Skip to content

Commit

Permalink
Merge pull request #1335 from carldlaird/solve_status_rapper
Browse files Browse the repository at this point in the history
Added helper functions to retrieve solver success (or not)
  • Loading branch information
carldlaird authored Mar 13, 2020
2 parents e49f63e + cff363f commit 0c859c5
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 3 deletions.
3 changes: 2 additions & 1 deletion pyomo/opt/results/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
#from old_results import *
from pyomo.opt.results.container import *
import pyomo.opt.results.problem
from pyomo.opt.results.solver import SolverStatus, TerminationCondition
from pyomo.opt.results.solver import SolverStatus, TerminationCondition, \
check_optimal_termination, assert_optimal_termination
from pyomo.opt.results.problem import ProblemSense
from pyomo.opt.results.solution import SolutionStatus, Solution
from pyomo.opt.results.results_ import SolverResults
40 changes: 39 additions & 1 deletion pyomo/opt/results/solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# This software is distributed under the 3-clause BSD License.
# ___________________________________________________________________________

__all__ = ['SolverInformation', 'SolverStatus', 'TerminationCondition']
__all__ = ['SolverInformation', 'SolverStatus', 'TerminationCondition', 'check_optimal_termination', 'assert_optimal_termination']

from pyutilib.enum import Enum
from pyomo.opt.results.container import MapContainer, ScalarType
Expand Down Expand Up @@ -68,6 +68,44 @@
)


def check_optimal_termination(results):
"""
This function returns True if the termination condition for the solver
is 'optimal', 'locallyOptimal', or 'globallyOptimal', and the status is 'ok'
Parameters
----------
results : Pyomo results object returned from solver.solve
Returns
-------
`bool`
"""
if results.solver.status == SolverStatus.ok and \
(results.solver.termination_condition == TerminationCondition.optimal
or results.solver.termination_condition == TerminationCondition.locallyOptimal
or results.solver.termination_condition == TerminationCondition.globallyOptimal):
return True
return False


def assert_optimal_termination(results):
"""
This function checks if the termination condition for the solver
is 'optimal', 'locallyOptimal', or 'globallyOptimal', and the status is 'ok'
and it raises a RuntimeError exception if this is not true.
Parameters
----------
results : Pyomo results object returned from solver.solve
"""
if not check_optimal_termination(results):
msg = 'Solver failed to return an optimal solution. ' \
'Solver status: {}, Termination condition: {}'.format(results.solver.status,
results.solver.termination_condition)
raise RuntimeError(msg)


class BranchAndBoundStats(MapContainer):

def __init__(self):
Expand Down
11 changes: 10 additions & 1 deletion pyomo/opt/tests/base/test_sol.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
import pyomo.opt
from pyomo.opt import (TerminationCondition,
SolutionStatus,
SolverStatus)
SolverStatus,
check_optimal_termination,
assert_optimal_termination)

old_tempdir = pyutilib.services.TempfileManager.tempdir

Expand Down Expand Up @@ -60,6 +62,11 @@ def test_infeasible1(self):
SolutionStatus.infeasible)
self.assertEqual(soln.solver.status,
SolverStatus.warning)

self.assertFalse(check_optimal_termination(soln))

with self.assertRaises(RuntimeError):
assert_optimal_termination(soln)

def test_infeasible2(self):
with pyomo.opt.ReaderFactory("sol") as reader:
Expand All @@ -84,6 +91,8 @@ def test_conopt_optimal(self):
SolutionStatus.optimal)
self.assertEqual(soln.solver.status,
SolverStatus.ok)
self.assertTrue(check_optimal_termination(soln))
assert_optimal_termination(soln)

def test_bad_options(self):
with pyomo.opt.ReaderFactory("sol") as reader:
Expand Down

0 comments on commit 0c859c5

Please sign in to comment.