Skip to content

Commit 0e7cdd2

Browse files
authored
Merge branch 'main' into doc-reorg
2 parents ff8e473 + 05eefac commit 0e7cdd2

File tree

4 files changed

+51
-21
lines changed

4 files changed

+51
-21
lines changed

.github/workflows/test_branches.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ jobs:
286286
if test -z "${{matrix.slim}}"; then
287287
python -m pip install --cache-dir cache/pip cplex docplex \
288288
|| echo "WARNING: CPLEX Community Edition is not available"
289-
python -m pip install --cache-dir cache/pip gurobipy==10.0.3 \
289+
python -m pip install --cache-dir cache/pip gurobipy \
290290
|| echo "WARNING: Gurobi is not available"
291291
python -m pip install --cache-dir cache/pip xpress \
292292
|| echo "WARNING: Xpress Community Edition is not available"
@@ -369,7 +369,7 @@ jobs:
369369
if test -z "${{matrix.slim}}"; then
370370
PYVER=$(echo "py${{matrix.python}}" | sed 's/\.//g')
371371
echo "Installing for $PYVER"
372-
for PKG in 'cplex>=12.10' docplex 'gurobi=10.0.3' xpress cyipopt pymumps scip; do
372+
for PKG in 'cplex>=12.10' docplex gurobi xpress cyipopt pymumps scip; do
373373
echo ""
374374
echo "*** Install $PKG ***"
375375
# conda can literally take an hour to determine that a

.github/workflows/test_pr_and_main.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ jobs:
309309
if test -z "${{matrix.slim}}"; then
310310
python -m pip install --cache-dir cache/pip cplex docplex \
311311
|| echo "WARNING: CPLEX Community Edition is not available"
312-
python -m pip install --cache-dir cache/pip gurobipy==10.0.3 \
312+
python -m pip install --cache-dir cache/pip gurobipy \
313313
|| echo "WARNING: Gurobi is not available"
314314
python -m pip install --cache-dir cache/pip xpress \
315315
|| echo "WARNING: Xpress Community Edition is not available"
@@ -392,7 +392,7 @@ jobs:
392392
if test -z "${{matrix.slim}}"; then
393393
PYVER=$(echo "py${{matrix.python}}" | sed 's/\.//g')
394394
echo "Installing for $PYVER"
395-
for PKG in 'cplex>=12.10' docplex 'gurobi=10.0.3' xpress cyipopt pymumps scip; do
395+
for PKG in 'cplex>=12.10' docplex gurobi xpress cyipopt pymumps scip; do
396396
echo ""
397397
echo "*** Install $PKG ***"
398398
# conda can literally take an hour to determine that a

pyomo/contrib/appsi/solvers/tests/test_gurobi_persistent.py

+25-10
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,16 @@ def test_lp(self):
191191

192192
class TestGurobiPersistent(unittest.TestCase):
193193
def test_nonconvex_qcp_objective_bound_1(self):
194-
# the goal of this test is to ensure we can get an objective bound
195-
# for nonconvex but continuous problems even if a feasible solution
196-
# is not found
194+
# the goal of this test is to ensure we can get an objective
195+
# bound for nonconvex but continuous problems even if a feasible
196+
# solution is not found
197197
#
198-
# This is a fragile test because it could fail if Gurobi's algorithms improve
199-
# (e.g., a heuristic solution is found before an objective bound of -8 is reached
198+
# This is a fragile test because it could fail if Gurobi's
199+
# algorithms improve (e.g., a heuristic solution is found before
200+
# an objective bound of -8 is reached
201+
#
202+
# Update: as of Gurobi 11, this test no longer tests the
203+
# intended behavior (the solver has improved)
200204
m = pe.ConcreteModel()
201205
m.x = pe.Var(bounds=(-5, 5))
202206
m.y = pe.Var(bounds=(-5, 5))
@@ -208,14 +212,22 @@ def test_nonconvex_qcp_objective_bound_1(self):
208212
opt.gurobi_options['BestBdStop'] = -8
209213
opt.config.load_solution = False
210214
res = opt.solve(m)
211-
self.assertEqual(res.best_feasible_objective, None)
215+
if opt.version() < (11, 0):
216+
self.assertEqual(res.best_feasible_objective, None)
217+
else:
218+
self.assertEqual(res.best_feasible_objective, -4)
212219
self.assertAlmostEqual(res.best_objective_bound, -8)
213220

214221
def test_nonconvex_qcp_objective_bound_2(self):
215-
# the goal of this test is to ensure we can best_objective_bound properly
216-
# for nonconvex but continuous problems when the solver terminates with a nonzero gap
222+
# the goal of this test is to ensure we can best_objective_bound
223+
# properly for nonconvex but continuous problems when the solver
224+
# terminates with a nonzero gap
225+
#
226+
# This is a fragile test because it could fail if Gurobi's
227+
# algorithms change
217228
#
218-
# This is a fragile test because it could fail if Gurobi's algorithms change
229+
# Update: as of Gurobi 11, this test no longer tests the
230+
# intended behavior (the solver has improved)
219231
m = pe.ConcreteModel()
220232
m.x = pe.Var(bounds=(-5, 5))
221233
m.y = pe.Var(bounds=(-5, 5))
@@ -227,7 +239,10 @@ def test_nonconvex_qcp_objective_bound_2(self):
227239
opt.gurobi_options['MIPGap'] = 0.5
228240
res = opt.solve(m)
229241
self.assertAlmostEqual(res.best_feasible_objective, -4)
230-
self.assertAlmostEqual(res.best_objective_bound, -6)
242+
if opt.version() < (11, 0):
243+
self.assertAlmostEqual(res.best_objective_bound, -6)
244+
else:
245+
self.assertAlmostEqual(res.best_objective_bound, -4)
231246

232247
def test_range_constraints(self):
233248
m = pe.ConcreteModel()

pyomo/contrib/solver/tests/solvers/test_gurobi_persistent.py

+22-7
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,12 @@ def test_nonconvex_qcp_objective_bound_1(self):
192192
# for nonconvex but continuous problems even if a feasible solution
193193
# is not found
194194
#
195-
# This is a fragile test because it could fail if Gurobi's algorithms improve
196-
# (e.g., a heuristic solution is found before an objective bound of -8 is reached
195+
# This is a fragile test because it could fail if Gurobi's
196+
# algorithms improve (e.g., a heuristic solution is found before
197+
# an objective bound of -8 is reached
198+
#
199+
# Update: as of Gurobi 11, this test no longer tests the
200+
# intended behavior (the solver has improved)
197201
m = pe.ConcreteModel()
198202
m.x = pe.Var(bounds=(-5, 5))
199203
m.y = pe.Var(bounds=(-5, 5))
@@ -206,14 +210,22 @@ def test_nonconvex_qcp_objective_bound_1(self):
206210
opt.config.load_solutions = False
207211
opt.config.raise_exception_on_nonoptimal_result = False
208212
res = opt.solve(m)
209-
self.assertEqual(res.incumbent_objective, None)
213+
if opt.version() < (11, 0):
214+
self.assertEqual(res.incumbent_objective, None)
215+
else:
216+
self.assertEqual(res.incumbent_objective, -4)
210217
self.assertAlmostEqual(res.objective_bound, -8)
211218

212219
def test_nonconvex_qcp_objective_bound_2(self):
213-
# the goal of this test is to ensure we can objective_bound properly
214-
# for nonconvex but continuous problems when the solver terminates with a nonzero gap
220+
# the goal of this test is to ensure we can objective_bound
221+
# properly for nonconvex but continuous problems when the solver
222+
# terminates with a nonzero gap
223+
#
224+
# This is a fragile test because it could fail if Gurobi's
225+
# algorithms change
215226
#
216-
# This is a fragile test because it could fail if Gurobi's algorithms change
227+
# Update: as of Gurobi 11, this test no longer tests the
228+
# intended behavior (the solver has improved)
217229
m = pe.ConcreteModel()
218230
m.x = pe.Var(bounds=(-5, 5))
219231
m.y = pe.Var(bounds=(-5, 5))
@@ -225,7 +237,10 @@ def test_nonconvex_qcp_objective_bound_2(self):
225237
opt.config.solver_options['MIPGap'] = 0.5
226238
res = opt.solve(m)
227239
self.assertAlmostEqual(res.incumbent_objective, -4)
228-
self.assertAlmostEqual(res.objective_bound, -6)
240+
if opt.version() < (11, 0):
241+
self.assertAlmostEqual(res.objective_bound, -6)
242+
else:
243+
self.assertAlmostEqual(res.objective_bound, -4)
229244

230245
def test_range_constraints(self):
231246
m = pe.ConcreteModel()

0 commit comments

Comments
 (0)