Skip to content

Commit

Permalink
Merge branch 'main' into doc-reorg
Browse files Browse the repository at this point in the history
  • Loading branch information
jsiirola authored Oct 29, 2024
2 parents ff8e473 + 05eefac commit 0e7cdd2
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 21 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test_branches.yml
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ jobs:
if test -z "${{matrix.slim}}"; then
python -m pip install --cache-dir cache/pip cplex docplex \
|| echo "WARNING: CPLEX Community Edition is not available"
python -m pip install --cache-dir cache/pip gurobipy==10.0.3 \
python -m pip install --cache-dir cache/pip gurobipy \
|| echo "WARNING: Gurobi is not available"
python -m pip install --cache-dir cache/pip xpress \
|| echo "WARNING: Xpress Community Edition is not available"
Expand Down Expand Up @@ -369,7 +369,7 @@ jobs:
if test -z "${{matrix.slim}}"; then
PYVER=$(echo "py${{matrix.python}}" | sed 's/\.//g')
echo "Installing for $PYVER"
for PKG in 'cplex>=12.10' docplex 'gurobi=10.0.3' xpress cyipopt pymumps scip; do
for PKG in 'cplex>=12.10' docplex gurobi xpress cyipopt pymumps scip; do
echo ""
echo "*** Install $PKG ***"
# conda can literally take an hour to determine that a
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test_pr_and_main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ jobs:
if test -z "${{matrix.slim}}"; then
python -m pip install --cache-dir cache/pip cplex docplex \
|| echo "WARNING: CPLEX Community Edition is not available"
python -m pip install --cache-dir cache/pip gurobipy==10.0.3 \
python -m pip install --cache-dir cache/pip gurobipy \
|| echo "WARNING: Gurobi is not available"
python -m pip install --cache-dir cache/pip xpress \
|| echo "WARNING: Xpress Community Edition is not available"
Expand Down Expand Up @@ -392,7 +392,7 @@ jobs:
if test -z "${{matrix.slim}}"; then
PYVER=$(echo "py${{matrix.python}}" | sed 's/\.//g')
echo "Installing for $PYVER"
for PKG in 'cplex>=12.10' docplex 'gurobi=10.0.3' xpress cyipopt pymumps scip; do
for PKG in 'cplex>=12.10' docplex gurobi xpress cyipopt pymumps scip; do
echo ""
echo "*** Install $PKG ***"
# conda can literally take an hour to determine that a
Expand Down
35 changes: 25 additions & 10 deletions pyomo/contrib/appsi/solvers/tests/test_gurobi_persistent.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,16 @@ def test_lp(self):

class TestGurobiPersistent(unittest.TestCase):
def test_nonconvex_qcp_objective_bound_1(self):
# the goal of this test is to ensure we can get an objective bound
# for nonconvex but continuous problems even if a feasible solution
# is not found
# the goal of this test is to ensure we can get an objective
# bound for nonconvex but continuous problems even if a feasible
# solution is not found
#
# This is a fragile test because it could fail if Gurobi's algorithms improve
# (e.g., a heuristic solution is found before an objective bound of -8 is reached
# This is a fragile test because it could fail if Gurobi's
# algorithms improve (e.g., a heuristic solution is found before
# an objective bound of -8 is reached
#
# Update: as of Gurobi 11, this test no longer tests the
# intended behavior (the solver has improved)
m = pe.ConcreteModel()
m.x = pe.Var(bounds=(-5, 5))
m.y = pe.Var(bounds=(-5, 5))
Expand All @@ -208,14 +212,22 @@ def test_nonconvex_qcp_objective_bound_1(self):
opt.gurobi_options['BestBdStop'] = -8
opt.config.load_solution = False
res = opt.solve(m)
self.assertEqual(res.best_feasible_objective, None)
if opt.version() < (11, 0):
self.assertEqual(res.best_feasible_objective, None)
else:
self.assertEqual(res.best_feasible_objective, -4)
self.assertAlmostEqual(res.best_objective_bound, -8)

def test_nonconvex_qcp_objective_bound_2(self):
# the goal of this test is to ensure we can best_objective_bound properly
# for nonconvex but continuous problems when the solver terminates with a nonzero gap
# the goal of this test is to ensure we can best_objective_bound
# properly for nonconvex but continuous problems when the solver
# terminates with a nonzero gap
#
# This is a fragile test because it could fail if Gurobi's
# algorithms change
#
# This is a fragile test because it could fail if Gurobi's algorithms change
# Update: as of Gurobi 11, this test no longer tests the
# intended behavior (the solver has improved)
m = pe.ConcreteModel()
m.x = pe.Var(bounds=(-5, 5))
m.y = pe.Var(bounds=(-5, 5))
Expand All @@ -227,7 +239,10 @@ def test_nonconvex_qcp_objective_bound_2(self):
opt.gurobi_options['MIPGap'] = 0.5
res = opt.solve(m)
self.assertAlmostEqual(res.best_feasible_objective, -4)
self.assertAlmostEqual(res.best_objective_bound, -6)
if opt.version() < (11, 0):
self.assertAlmostEqual(res.best_objective_bound, -6)
else:
self.assertAlmostEqual(res.best_objective_bound, -4)

def test_range_constraints(self):
m = pe.ConcreteModel()
Expand Down
29 changes: 22 additions & 7 deletions pyomo/contrib/solver/tests/solvers/test_gurobi_persistent.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,12 @@ def test_nonconvex_qcp_objective_bound_1(self):
# for nonconvex but continuous problems even if a feasible solution
# is not found
#
# This is a fragile test because it could fail if Gurobi's algorithms improve
# (e.g., a heuristic solution is found before an objective bound of -8 is reached
# This is a fragile test because it could fail if Gurobi's
# algorithms improve (e.g., a heuristic solution is found before
# an objective bound of -8 is reached
#
# Update: as of Gurobi 11, this test no longer tests the
# intended behavior (the solver has improved)
m = pe.ConcreteModel()
m.x = pe.Var(bounds=(-5, 5))
m.y = pe.Var(bounds=(-5, 5))
Expand All @@ -206,14 +210,22 @@ def test_nonconvex_qcp_objective_bound_1(self):
opt.config.load_solutions = False
opt.config.raise_exception_on_nonoptimal_result = False
res = opt.solve(m)
self.assertEqual(res.incumbent_objective, None)
if opt.version() < (11, 0):
self.assertEqual(res.incumbent_objective, None)
else:
self.assertEqual(res.incumbent_objective, -4)
self.assertAlmostEqual(res.objective_bound, -8)

def test_nonconvex_qcp_objective_bound_2(self):
# the goal of this test is to ensure we can objective_bound properly
# for nonconvex but continuous problems when the solver terminates with a nonzero gap
# the goal of this test is to ensure we can objective_bound
# properly for nonconvex but continuous problems when the solver
# terminates with a nonzero gap
#
# This is a fragile test because it could fail if Gurobi's
# algorithms change
#
# This is a fragile test because it could fail if Gurobi's algorithms change
# Update: as of Gurobi 11, this test no longer tests the
# intended behavior (the solver has improved)
m = pe.ConcreteModel()
m.x = pe.Var(bounds=(-5, 5))
m.y = pe.Var(bounds=(-5, 5))
Expand All @@ -225,7 +237,10 @@ def test_nonconvex_qcp_objective_bound_2(self):
opt.config.solver_options['MIPGap'] = 0.5
res = opt.solve(m)
self.assertAlmostEqual(res.incumbent_objective, -4)
self.assertAlmostEqual(res.objective_bound, -6)
if opt.version() < (11, 0):
self.assertAlmostEqual(res.objective_bound, -6)
else:
self.assertAlmostEqual(res.objective_bound, -4)

def test_range_constraints(self):
m = pe.ConcreteModel()
Expand Down

0 comments on commit 0e7cdd2

Please sign in to comment.