Skip to content

Commit 73f8567

Browse files
authored
Merge pull request #1 from viens-code/solnpool
Updates to Solution Pool and MyMunch
2 parents 84ec9d0 + 5f4cdbd commit 73f8567

File tree

11 files changed

+996
-56
lines changed

11 files changed

+996
-56
lines changed

pyomo/contrib/alternative_solutions/aos_utils.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,9 @@ def get_model_variables(
306306

307307

308308
class MyMunch(Munch):
309-
310-
to_dict = Munch.toDict
309+
#WEH, MPV needed to add a to_dict since Bunch did not have one
310+
def to_dict(self):
311+
return _to_dict(self)
311312

312313

313314
def _to_dict(x):
@@ -319,4 +320,5 @@ def _to_dict(x):
319320
elif xtype in [dict, Munch, MyMunch]:
320321
return {k: _to_dict(v) for k, v in x.items()}
321322
else:
323+
print(f'Here: {x=} {type(x)}')
322324
return x.to_dict()

pyomo/contrib/alternative_solutions/balas.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def enumerate_binary_solutions(
4545
model : ConcreteModel
4646
A concrete Pyomo model
4747
num_solutions : int
48-
The maximum number of solutions to generate.
48+
The maximum number of solutions to generate. Must be positive
4949
variables: None or a collection of Pyomo _GeneralVarData variables
5050
The variables for which bounds will be generated. None indicates
5151
that all variables will be included. Alternatively, a collection of
@@ -83,6 +83,10 @@ def enumerate_binary_solutions(
8383
"""
8484
logger.info("STARTING NO-GOOD CUT ANALYSIS")
8585

86+
assert num_solutions >= 1, "num_solutions must be positive integer"
87+
if num_solutions == 1:
88+
logger.warning("Running alternative_solutions method to find only 1 solution!")
89+
8690
assert search_mode in [
8791
"optimal",
8892
"random",

pyomo/contrib/alternative_solutions/gurobi_solnpool.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def gurobi_generate_solutions(
3030
solver_options={},
3131
tee=False,
3232
poolmanager=None,
33+
pool_search_mode=2,
3334
):
3435
"""
3536
Finds alternative optimal solutions for discrete variables using Gurobi's
@@ -42,7 +43,7 @@ def gurobi_generate_solutions(
4243
A concrete Pyomo model.
4344
num_solutions : int
4445
The maximum number of solutions to generate. This parameter maps to
45-
the PoolSolutions parameter in Gurobi.
46+
the PoolSolutions parameter in Gurobi. Must be positive.
4647
rel_opt_gap : non-negative float or None
4748
The relative optimality gap for allowable alternative solutions.
4849
None implies that there is no limit on the relative optimality gap
@@ -59,12 +60,27 @@ def gurobi_generate_solutions(
5960
Boolean indicating that the solver output should be displayed.
6061
poolmanager : None
6162
Optional pool manager that will be used to collect solution
63+
pool_search_mode : 1 or 2
64+
The generation method for filling the pool.
65+
This parameter maps to the PoolSearchMode in gurobi.
66+
Method designed to work with value 2 as optimality ordered.
6267
6368
Returns
6469
-------
6570
poolmanager
6671
A PyomoPoolManager object
6772
"""
73+
74+
assert num_solutions >= 1, "num_solutions must be positive integer"
75+
if num_solutions == 1:
76+
logger.warning("Running alternative_solutions method to find only 1 solution!")
77+
78+
assert pool_search_mode in [1, 2], "pool_search_mode must be 1 or 2"
79+
if pool_search_mode == 1:
80+
logger.warning(
81+
"Running gurobi_solnpool with PoolSearchMode=1, best effort search may lead to unexpected behavior"
82+
)
83+
6884
if poolmanager is None:
6985
poolmanager = PyomoPoolManager()
7086
poolmanager.add_pool("gurobi_generate_solutions", policy="keep_all")
@@ -78,7 +94,7 @@ def gurobi_generate_solutions(
7894
opt.config.stream_solver = tee
7995
opt.config.load_solution = False
8096
opt.gurobi_options["PoolSolutions"] = num_solutions
81-
opt.gurobi_options["PoolSearchMode"] = 2
97+
opt.gurobi_options["PoolSearchMode"] = pool_search_mode
8298
if rel_opt_gap is not None:
8399
opt.gurobi_options["PoolGap"] = rel_opt_gap
84100
if abs_opt_gap is not None:

pyomo/contrib/alternative_solutions/lp_enum.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def enumerate_linear_solutions(
4747
model : ConcreteModel
4848
A concrete Pyomo model
4949
num_solutions : int
50-
The maximum number of solutions to generate.
50+
The maximum number of solutions to generate. Must be positive
5151
rel_opt_gap : float or None
5252
The relative optimality gap for the original objective for which
5353
variable bounds will be found. None indicates that a relative gap
@@ -83,6 +83,10 @@ def enumerate_linear_solutions(
8383
"""
8484
logger.info("STARTING LP ENUMERATION ANALYSIS")
8585

86+
assert num_solutions >= 1, "num_solutions must be positive integer"
87+
if num_solutions == 1:
88+
logger.warning("Running alternative_solutions method to find only 1 solution!")
89+
8690
assert search_mode in [
8791
"optimal",
8892
"random",

pyomo/contrib/alternative_solutions/lp_enum_solnpool.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def enumerate_linear_solutions_soln_pool(
104104
model : ConcreteModel
105105
A concrete Pyomo model
106106
num_solutions : int
107-
The maximum number of solutions to generate.
107+
The maximum number of solutions to generate. Must be positive.
108108
variables: None or a collection of Pyomo _GeneralVarData variables
109109
The variables for which bounds will be generated. None indicates
110110
that all variables will be included. Alternatively, a collection of
@@ -134,6 +134,10 @@ def enumerate_linear_solutions_soln_pool(
134134
"""
135135
logger.info("STARTING LP ENUMERATION ANALYSIS USING GUROBI SOLUTION POOL")
136136

137+
assert num_solutions >= 1, "num_solutions must be positive integer"
138+
if num_solutions == 1:
139+
logger.warning("Running alternative_solutions method to find only 1 solution!")
140+
137141
if poolmanager is None:
138142
poolmanager = PyomoPoolManager()
139143
poolmanager.add_pool("enumerate_binary_solutions", policy="keep_all")

0 commit comments

Comments
 (0)