Skip to content

Commit 4e6ebbe

Browse files
authored
Merge branch 'main' into doc-reorg
2 parents f2827f1 + d643e8f commit 4e6ebbe

File tree

6 files changed

+30
-38
lines changed

6 files changed

+30
-38
lines changed

pyomo/contrib/alternative_solutions/lp_enum_solnpool.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ def __init__(
4545
self.num_solutions = num_solutions
4646

4747
def cut_generator_callback(self, cb_m, cb_opt, cb_where):
48-
from gurobipy import GRB
49-
50-
if cb_where == GRB.Callback.MIPSOL:
48+
if cb_where == gurobipy.GRB.Callback.MIPSOL:
5149
cb_opt.cbGetSolution(vars=self.variables)
5250
logger.info("***FOUND SOLUTION***")
5351

pyomo/contrib/alternative_solutions/solnpool.py

-5
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
from pyomo.common.dependencies import attempt_import
1717
from pyomo.common.errors import ApplicationError
1818

19-
gurobipy, gurobipy_available = attempt_import("gurobipy")
20-
2119
import pyomo.environ as pe
2220
from pyomo.contrib import appsi
2321
import pyomo.contrib.alternative_solutions.aos_utils as aos_utils
@@ -68,10 +66,7 @@ def gurobi_generate_solutions(
6866
#
6967
# Setup gurobi
7068
#
71-
if not gurobipy_available:
72-
raise ApplicationError("Solver (gurobi) not available")
7369
opt = appsi.solvers.Gurobi()
74-
7570
if not opt.available():
7671
raise ApplicationError("Solver (gurobi) not available")
7772

pyomo/contrib/alternative_solutions/tests/test_lp_enum_solnpool.py

+11-7
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,29 @@
99
# This software is distributed under the 3-clause BSD License.
1010
# ___________________________________________________________________________
1111

12-
import pyomo.environ as pe
13-
import pyomo.opt
12+
from pyomo.common.dependencies import numpy_available
13+
from pyomo.common import unittest
1414

1515
import pyomo.contrib.alternative_solutions.tests.test_cases as tc
1616
from pyomo.contrib.alternative_solutions import lp_enum
1717
from pyomo.contrib.alternative_solutions import lp_enum_solnpool
18+
from pyomo.opt import check_available_solvers
1819

19-
from pyomo.common.dependencies import attempt_import
20+
import pyomo.environ as pe
2021

21-
numpy, numpy_available = attempt_import("numpy")
22-
gurobipy, gurobi_available = attempt_import("gurobipy")
22+
# lp_enum_solnpool uses both 'gurobi' and 'appsi_gurobi'
23+
gurobi_available = len(check_available_solvers('gurobi', 'appsi_gurobi')) == 2
2324

2425
#
2526
# TODO: Setup detailed tests here
2627
#
2728

2829

29-
def test_here():
30-
if numpy_available:
30+
@unittest.skipUnless(gurobi_available, "Gurobi MIP solver not available")
31+
@unittest.skipUnless(numpy_available, "NumPy not found")
32+
class TestLPEnumSolnpool(unittest.TestCase):
33+
34+
def test_here(self):
3135
n = tc.get_pentagonal_pyramid_mip()
3236
n.x.domain = pe.Reals
3337
n.y.domain = pe.Reals

pyomo/contrib/alternative_solutions/tests/test_solnpool.py

+12-16
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,17 @@
99
# This software is distributed under the 3-clause BSD License.
1010
# ___________________________________________________________________________
1111

12-
from pyomo.common.dependencies import numpy as numpy, numpy_available
13-
14-
if numpy_available:
15-
from numpy.testing import assert_array_almost_equal
16-
from pyomo.common.dependencies import attempt_import
17-
18-
gurobipy, gurobipy_available = attempt_import("gurobipy")
19-
2012
from collections import Counter
2113

22-
import pyomo.environ as pe
14+
from pyomo.common.dependencies import numpy as np, numpy_available
2315
from pyomo.common import unittest
24-
2516
from pyomo.contrib.alternative_solutions import gurobi_generate_solutions
17+
from pyomo.contrib.appsi.solvers import Gurobi
18+
2619
import pyomo.contrib.alternative_solutions.tests.test_cases as tc
20+
import pyomo.environ as pe
21+
22+
gurobipy_available = Gurobi().available()
2723

2824

2925
@unittest.skipIf(not gurobipy_available, "Gurobi MIP solver not available")
@@ -51,7 +47,7 @@ def test_ip_feasibility(self):
5147
objectives = [round(result.objective[1], 2) for result in results]
5248
actual_solns_by_obj = m.num_ranked_solns
5349
unique_solns_by_obj = [val for val in Counter(objectives).values()]
54-
assert_array_almost_equal(unique_solns_by_obj, actual_solns_by_obj)
50+
np.testing.assert_array_almost_equal(unique_solns_by_obj, actual_solns_by_obj)
5551

5652
@unittest.skipIf(not numpy_available, "Numpy not installed")
5753
def test_ip_num_solutions(self):
@@ -66,7 +62,7 @@ def test_ip_num_solutions(self):
6662
objectives = [round(result.objective[1], 2) for result in results]
6763
actual_solns_by_obj = [6, 2]
6864
unique_solns_by_obj = [val for val in Counter(objectives).values()]
69-
assert_array_almost_equal(unique_solns_by_obj, actual_solns_by_obj)
65+
np.testing.assert_array_almost_equal(unique_solns_by_obj, actual_solns_by_obj)
7066

7167
@unittest.skipIf(not numpy_available, "Numpy not installed")
7268
def test_mip_feasibility(self):
@@ -80,7 +76,7 @@ def test_mip_feasibility(self):
8076
objectives = [round(result.objective[1], 2) for result in results]
8177
actual_solns_by_obj = m.num_ranked_solns
8278
unique_solns_by_obj = [val for val in Counter(objectives).values()]
83-
assert_array_almost_equal(unique_solns_by_obj, actual_solns_by_obj)
79+
np.testing.assert_array_almost_equal(unique_solns_by_obj, actual_solns_by_obj)
8480

8581
@unittest.skipIf(not numpy_available, "Numpy not installed")
8682
def test_mip_rel_feasibility(self):
@@ -95,7 +91,7 @@ def test_mip_rel_feasibility(self):
9591
objectives = [round(result.objective[1], 2) for result in results]
9692
actual_solns_by_obj = m.num_ranked_solns[0:2]
9793
unique_solns_by_obj = [val for val in Counter(objectives).values()]
98-
assert_array_almost_equal(unique_solns_by_obj, actual_solns_by_obj)
94+
np.testing.assert_array_almost_equal(unique_solns_by_obj, actual_solns_by_obj)
9995

10096
@unittest.skipIf(not numpy_available, "Numpy not installed")
10197
def test_mip_rel_feasibility_options(self):
@@ -112,7 +108,7 @@ def test_mip_rel_feasibility_options(self):
112108
objectives = [round(result.objective[1], 2) for result in results]
113109
actual_solns_by_obj = m.num_ranked_solns[0:2]
114110
unique_solns_by_obj = [val for val in Counter(objectives).values()]
115-
assert_array_almost_equal(unique_solns_by_obj, actual_solns_by_obj)
111+
np.testing.assert_array_almost_equal(unique_solns_by_obj, actual_solns_by_obj)
116112

117113
@unittest.skipIf(not numpy_available, "Numpy not installed")
118114
def test_mip_abs_feasibility(self):
@@ -127,7 +123,7 @@ def test_mip_abs_feasibility(self):
127123
objectives = [round(result.objective[1], 2) for result in results]
128124
actual_solns_by_obj = m.num_ranked_solns[0:3]
129125
unique_solns_by_obj = [val for val in Counter(objectives).values()]
130-
assert_array_almost_equal(unique_solns_by_obj, actual_solns_by_obj)
126+
np.testing.assert_array_almost_equal(unique_solns_by_obj, actual_solns_by_obj)
131127

132128
@unittest.skipIf(True, "Ignoring fragile test for solver timeout.")
133129
def test_mip_no_time(self):

pyomo/contrib/alternative_solutions/tests/test_solution.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
import pyomo.contrib.alternative_solutions.aos_utils as au
1616
from pyomo.contrib.alternative_solutions import Solution
1717

18-
pyomo.opt.check_available_solvers("gurobi")
1918
mip_solver = "gurobi"
19+
mip_available = pyomo.opt.check_available_solvers(mip_solver)
2020

2121

2222
class TestSolutionUnit(unittest.TestCase):
@@ -40,10 +40,7 @@ def get_model(self):
4040
m.con_z = pe.Constraint(expr=m.z <= 3)
4141
return m
4242

43-
@unittest.skipUnless(
44-
pe.SolverFactory(mip_solver).available(exception_flag=False),
45-
"MIP solver not available",
46-
)
43+
@unittest.skipUnless(mip_available, "MIP solver not available")
4744
def test_solution(self):
4845
"""
4946
Create a Solution Object, call its functions, and ensure the correct

pyomo/solvers/tests/mip/test_qp.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,17 @@ def _qp_model(self):
5353
return m
5454

5555
@unittest.skipUnless(
56-
gurobi_lp.available(exception_flag=False), "needs Gurobi LP interface"
56+
gurobi_lp.available(exception_flag=False) and gurobi_lp.license_is_valid(),
57+
"needs Gurobi LP interface",
5758
)
5859
def test_qp_objective_gurobi_lp(self):
5960
m = self._qp_model()
6061
results = gurobi_lp.solve(m)
6162
self.assertEqual(m.obj(), results['Problem'][0]['Upper bound'])
6263

6364
@unittest.skipUnless(
64-
gurobi_nl.available(exception_flag=False), "needs Gurobi NL interface"
65+
gurobi_nl.available(exception_flag=False) and gurobi_nl.license_is_valid(),
66+
"needs Gurobi NL interface",
6567
)
6668
def test_qp_objective_gurobi_nl(self):
6769
m = self._qp_model()

0 commit comments

Comments
 (0)