Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyomo/contrib/gdpopt/branch_and_bound.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ def _solve_gdp(self, model, config):
config.logger.info(
'Final bound values: LB: {} UB: {}'.format(self.LB, self.UB)
)
return self._get_final_results_object()
return self._get_final_pyomo_results_object()

# Handle current node
if not node_data.is_screened:
Expand Down
47 changes: 45 additions & 2 deletions pyomo/contrib/gdpopt/tests/test_LBB.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,17 @@
from pyomo.common.log import LoggingIntercept
import pyomo.contrib.gdpopt.tests.common_tests as ct
from pyomo.contrib.satsolver.satsolver import z3_available
from pyomo.environ import SolverFactory, value, ConcreteModel, Var, Objective, maximize
from pyomo.gdp import Disjunction
from pyomo.contrib.gdpopt.branch_and_bound import GDP_LBB_Solver
from pyomo.environ import (
SolverFactory,
value,
ConcreteModel,
Constraint,
Var,
Objective,
maximize,
)
from pyomo.gdp import Disjunct, Disjunction
from pyomo.opt import TerminationCondition

currdir = dirname(abspath(__file__))
Expand All @@ -35,6 +44,40 @@
)


class TestGDPopt_LBB_TimeLimit(unittest.TestCase):
"""Tests for solver-independent LBB termination paths."""

def test_time_limit_returns_pyomo_results_object(self):
m = ConcreteModel()
m.x = Var(bounds=(0, 2))
m.d1 = Disjunct()
m.d2 = Disjunct()
m.d1.c = Constraint(expr=m.x <= 0.5)
m.d2.c = Constraint(expr=m.x >= 1.5)
m.disj = Disjunction(expr=[m.d1, m.d2])
m.obj = Objective(expr=m.x)

orig_reached_time_limit = GDP_LBB_Solver.reached_time_limit

def force_time_limit(solver, config):
solver.pyomo_results.solver.termination_condition = (
TerminationCondition.maxTimeLimit
)
return True

GDP_LBB_Solver.reached_time_limit = force_time_limit
try:
results = SolverFactory('gdpopt.lbb').solve(m, time_limit=1, tee=False)
finally:
GDP_LBB_Solver.reached_time_limit = orig_reached_time_limit

self.assertEqual(
results.solver.termination_condition, TerminationCondition.maxTimeLimit
)
self.assertEqual(results.problem.lower_bound, float('-inf'))
self.assertEqual(results.problem.upper_bound, float('inf'))


@unittest.skipUnless(
solver_available, "Required subsolver %s is not available" % (minlp_solver,)
)
Expand Down
21 changes: 20 additions & 1 deletion pyomo/contrib/mindtpy/tests/test_mindtpy_no_discrete.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@

from unittest.mock import MagicMock, patch

from pyomo.opt import TerminationCondition as tc, SolverStatus
from pyomo.common import timing
from pyomo.contrib.mindtpy.global_outer_approximation import MindtPy_GOA_Solver
from pyomo.opt import TerminationCondition as tc, SolverStatus, SolverResults
import pyomo.common.unittest as unittest

from pyomo.environ import (
Expand Down Expand Up @@ -455,6 +457,23 @@ def test_solver_status_and_message_mirrored(self):
self.assertEqual(algo.results.solver.message, "All good")


class TestMindtPyGOATimeLimit(unittest.TestCase):
def test_goa_time_limit_sets_solver_results_condition(self):
solver = MindtPy_GOA_Solver()
solver.config = _SimpleNamespace(
logger=MagicMock(), single_tree=False, time_limit=1
)
solver.results = SolverResults()
solver.timing = _SimpleNamespace(
main_timer_start_time=timing.default_timer() - 2
)
solver.primal_bound = float('inf')
solver.dual_bound = float('-inf')

self.assertTrue(solver.reached_time_limit())
self.assertEqual(solver.results.solver.termination_condition, tc.maxTimeLimit)


class _FakeLegacyMIPSolver:
def __init__(
self,
Expand Down
Loading