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 15, 2024
2 parents f2827f1 + d643e8f commit 4e6ebbe
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 38 deletions.
4 changes: 1 addition & 3 deletions pyomo/contrib/alternative_solutions/lp_enum_solnpool.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@ def __init__(
self.num_solutions = num_solutions

def cut_generator_callback(self, cb_m, cb_opt, cb_where):
from gurobipy import GRB

if cb_where == GRB.Callback.MIPSOL:
if cb_where == gurobipy.GRB.Callback.MIPSOL:
cb_opt.cbGetSolution(vars=self.variables)
logger.info("***FOUND SOLUTION***")

Expand Down
5 changes: 0 additions & 5 deletions pyomo/contrib/alternative_solutions/solnpool.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
from pyomo.common.dependencies import attempt_import
from pyomo.common.errors import ApplicationError

gurobipy, gurobipy_available = attempt_import("gurobipy")

import pyomo.environ as pe
from pyomo.contrib import appsi
import pyomo.contrib.alternative_solutions.aos_utils as aos_utils
Expand Down Expand Up @@ -68,10 +66,7 @@ def gurobi_generate_solutions(
#
# Setup gurobi
#
if not gurobipy_available:
raise ApplicationError("Solver (gurobi) not available")
opt = appsi.solvers.Gurobi()

if not opt.available():
raise ApplicationError("Solver (gurobi) not available")

Expand Down
18 changes: 11 additions & 7 deletions pyomo/contrib/alternative_solutions/tests/test_lp_enum_solnpool.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,29 @@
# This software is distributed under the 3-clause BSD License.
# ___________________________________________________________________________

import pyomo.environ as pe
import pyomo.opt
from pyomo.common.dependencies import numpy_available
from pyomo.common import unittest

import pyomo.contrib.alternative_solutions.tests.test_cases as tc
from pyomo.contrib.alternative_solutions import lp_enum
from pyomo.contrib.alternative_solutions import lp_enum_solnpool
from pyomo.opt import check_available_solvers

from pyomo.common.dependencies import attempt_import
import pyomo.environ as pe

numpy, numpy_available = attempt_import("numpy")
gurobipy, gurobi_available = attempt_import("gurobipy")
# lp_enum_solnpool uses both 'gurobi' and 'appsi_gurobi'
gurobi_available = len(check_available_solvers('gurobi', 'appsi_gurobi')) == 2

#
# TODO: Setup detailed tests here
#


def test_here():
if numpy_available:
@unittest.skipUnless(gurobi_available, "Gurobi MIP solver not available")
@unittest.skipUnless(numpy_available, "NumPy not found")
class TestLPEnumSolnpool(unittest.TestCase):

def test_here(self):
n = tc.get_pentagonal_pyramid_mip()
n.x.domain = pe.Reals
n.y.domain = pe.Reals
Expand Down
28 changes: 12 additions & 16 deletions pyomo/contrib/alternative_solutions/tests/test_solnpool.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,17 @@
# This software is distributed under the 3-clause BSD License.
# ___________________________________________________________________________

from pyomo.common.dependencies import numpy as numpy, numpy_available

if numpy_available:
from numpy.testing import assert_array_almost_equal
from pyomo.common.dependencies import attempt_import

gurobipy, gurobipy_available = attempt_import("gurobipy")

from collections import Counter

import pyomo.environ as pe
from pyomo.common.dependencies import numpy as np, numpy_available
from pyomo.common import unittest

from pyomo.contrib.alternative_solutions import gurobi_generate_solutions
from pyomo.contrib.appsi.solvers import Gurobi

import pyomo.contrib.alternative_solutions.tests.test_cases as tc
import pyomo.environ as pe

gurobipy_available = Gurobi().available()


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

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

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

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

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

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

@unittest.skipIf(True, "Ignoring fragile test for solver timeout.")
def test_mip_no_time(self):
Expand Down
7 changes: 2 additions & 5 deletions pyomo/contrib/alternative_solutions/tests/test_solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
import pyomo.contrib.alternative_solutions.aos_utils as au
from pyomo.contrib.alternative_solutions import Solution

pyomo.opt.check_available_solvers("gurobi")
mip_solver = "gurobi"
mip_available = pyomo.opt.check_available_solvers(mip_solver)


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

@unittest.skipUnless(
pe.SolverFactory(mip_solver).available(exception_flag=False),
"MIP solver not available",
)
@unittest.skipUnless(mip_available, "MIP solver not available")
def test_solution(self):
"""
Create a Solution Object, call its functions, and ensure the correct
Expand Down
6 changes: 4 additions & 2 deletions pyomo/solvers/tests/mip/test_qp.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,17 @@ def _qp_model(self):
return m

@unittest.skipUnless(
gurobi_lp.available(exception_flag=False), "needs Gurobi LP interface"
gurobi_lp.available(exception_flag=False) and gurobi_lp.license_is_valid(),
"needs Gurobi LP interface",
)
def test_qp_objective_gurobi_lp(self):
m = self._qp_model()
results = gurobi_lp.solve(m)
self.assertEqual(m.obj(), results['Problem'][0]['Upper bound'])

@unittest.skipUnless(
gurobi_nl.available(exception_flag=False), "needs Gurobi NL interface"
gurobi_nl.available(exception_flag=False) and gurobi_nl.license_is_valid(),
"needs Gurobi NL interface",
)
def test_qp_objective_gurobi_nl(self):
m = self._qp_model()
Expand Down

0 comments on commit 4e6ebbe

Please sign in to comment.