-
Notifications
You must be signed in to change notification settings - Fork 561
Solution Pool #3657
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Solution Pool #3657
Changes from all commits
79bcd07
50c4ea4
e50aadf
789ac79
39f386d
1f419b7
4dc67f3
f749087
4d789cc
a2c7ba2
ab50d29
96de282
d7ea2ef
cafd3a6
ed7b154
5299493
6eeb219
fd371a6
4ea2d9b
b80c1bb
13e6853
f638889
834cd95
235b702
d1668b5
9548607
ac9f517
1a83132
fe41db1
706c8db
14a33bd
0942029
2430679
de7db76
221be05
73fd086
249188e
09b4d66
ec110a0
3e12b37
217bdc6
6262edc
84ec9d0
5f4cdbd
73f8567
5136b62
4ee9a22
7e70695
4284a9e
c0be0c5
11894e2
5a8818d
b72f28a
57df61a
0d79e42
e0c7574
6c49227
f183ce3
eb2b6fd
f4b1266
603d379
a9ddca0
1e87960
1cdb5f2
07758af
168b9e0
e282d40
6f7046b
eeddcef
b656684
c8f9248
6a67528
9ffa3a6
674fe78
0dcf146
0f10069
41b49d1
7849484
ebac878
394238a
977382b
2cbeeaf
2ebf141
535b814
04e5578
f81a4da
91fc05b
858b9b0
f2ad6c0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,7 +15,7 @@ | |
|
|
||
| import pyomo.environ as pyo | ||
| from pyomo.common.collections import ComponentSet | ||
| from pyomo.contrib.alternative_solutions import Solution | ||
| from pyomo.contrib.alternative_solutions import PyomoPoolManager, PoolPolicy | ||
| import pyomo.contrib.alternative_solutions.aos_utils as aos_utils | ||
|
|
||
|
|
||
|
|
@@ -31,6 +31,7 @@ def enumerate_binary_solutions( | |
| solver_options={}, | ||
| tee=False, | ||
| seed=None, | ||
| pool_manager=None, | ||
| ): | ||
| """ | ||
| Finds alternative optimal solutions for a binary problem using no-good | ||
|
|
@@ -44,7 +45,7 @@ def enumerate_binary_solutions( | |
| model : ConcreteModel | ||
| A concrete Pyomo model | ||
| num_solutions : int | ||
| The maximum number of solutions to generate. | ||
| The maximum number of solutions to generate. Must be positive | ||
| variables: None or a collection of Pyomo _GeneralVarData variables | ||
| The variables for which bounds will be generated. None indicates | ||
| that all variables will be included. Alternatively, a collection of | ||
|
|
@@ -71,25 +72,34 @@ def enumerate_binary_solutions( | |
| Boolean indicating that the solver output should be displayed. | ||
| seed : int | ||
| Optional integer seed for the numpy random number generator | ||
| pool_manager : None | ||
| Optional pool manager that will be used to collect solutions | ||
|
Comment on lines
+75
to
+76
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't it make more sense to pass in the specific pool the user wants to the routine to use and not the whole pool manager?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above |
||
|
|
||
| Returns | ||
| ------- | ||
| solutions | ||
| A list of Solution objects. | ||
| [Solution] | ||
| pool_manager | ||
| A PyomoPoolManager object | ||
|
Comment on lines
+80
to
+81
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't it make more sense for this to return the pool and not the pool manager? You are implicitly trusting that the "active pool" stays constant not only throughout this routine, but also after it exits. (This comment applies to all AOS routines.)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think so. An AOS method can populate multiple pools. Hence, a pool manager seems like the right level of abstraction. |
||
|
|
||
| """ | ||
| logger.info("STARTING NO-GOOD CUT ANALYSIS") | ||
|
|
||
| assert search_mode in [ | ||
| "optimal", | ||
| "random", | ||
| "hamming", | ||
| ], 'search mode must be "optimal", "random", or "hamming".' | ||
| if not (num_solutions >= 1): | ||
| raise RuntimeError("num_solutions must be positive integer") | ||
| if num_solutions == 1: | ||
| logger.warning("Running alternative_solutions method to find only 1 solution!") | ||
|
|
||
| if not (search_mode in ["optimal", "random", "hamming"]): | ||
| raise ValueError('search mode must be "optimal", "random", or "hamming".') | ||
|
|
||
| if seed is not None: | ||
| aos_utils._set_numpy_rng(seed) | ||
|
|
||
| if pool_manager is None: | ||
| pool_manager = PyomoPoolManager() | ||
| pool_manager.add_pool( | ||
| name="enumerate_binary_solutions", policy=PoolPolicy.keep_all | ||
| ) | ||
|
|
||
| all_variables = aos_utils.get_model_variables(model, include_fixed=True) | ||
| if variables == None: | ||
| binary_variables = [ | ||
|
|
@@ -108,18 +118,18 @@ def enumerate_binary_solutions( | |
| else: # pragma: no cover | ||
| non_binary_variables.append(var.name) | ||
| if len(non_binary_variables) > 0: | ||
| logger.warn( | ||
| logger.warning( | ||
| ( | ||
| "Warning: The following non-binary variables were included" | ||
| "in the variable list and will be ignored:" | ||
| ) | ||
| ) | ||
| logger.warn(", ".join(non_binary_variables)) | ||
| logger.warning(", ".join(non_binary_variables)) | ||
|
|
||
| orig_objective = aos_utils.get_active_objective(model) | ||
|
|
||
| if len(binary_variables) == 0: | ||
| logger.warn("No binary variables found!") | ||
| logger.warning("No binary variables found!") | ||
|
|
||
| # | ||
| # Setup solver | ||
|
|
@@ -152,7 +162,6 @@ def enumerate_binary_solutions( | |
| else: | ||
| opt.update_config.check_for_new_objective = False | ||
| opt.update_config.update_objective = False | ||
|
|
||
| # | ||
| # Initial solve of the model | ||
| # | ||
|
|
@@ -172,12 +181,12 @@ def enumerate_binary_solutions( | |
| model.solutions.load_from(results) | ||
| orig_objective_value = pyo.value(orig_objective) | ||
| logger.info("Found optimal solution, value = {}.".format(orig_objective_value)) | ||
| solutions = [Solution(model, all_variables, objective=orig_objective)] | ||
| pool_manager.add(variables=all_variables, objective=orig_objective) | ||
| # | ||
| # Return just this solution if there are no binary variables | ||
| # | ||
| if len(binary_variables) == 0: | ||
| return solutions | ||
| return pool_manager | ||
|
|
||
| aos_block = aos_utils._add_aos_block(model, name="_balas") | ||
| logger.info("Added block {} to the model.".format(aos_block)) | ||
|
|
@@ -231,7 +240,7 @@ def enumerate_binary_solutions( | |
| logger.info( | ||
| "Iteration {}: objective = {}".format(solution_number, orig_obj_value) | ||
| ) | ||
| solutions.append(Solution(model, all_variables, objective=orig_objective)) | ||
| pool_manager.add(variables=all_variables, objective=orig_objective) | ||
| solution_number += 1 | ||
| elif ( | ||
| condition == pyo.TerminationCondition.infeasibleOrUnbounded | ||
|
|
@@ -257,4 +266,4 @@ def enumerate_binary_solutions( | |
|
|
||
| logger.info("COMPLETED NO-GOOD CUT ANALYSIS") | ||
|
|
||
| return solutions | ||
| return pool_manager | ||
Uh oh!
There was an error while loading. Please reload this page.