Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
79bcd07
Renaming warn() to warning()
whart222 Jul 1, 2025
50c4ea4
Renaming solnpool.py to gurobi_solnpool.py
whart222 Jul 1, 2025
e50aadf
Renaming test file
whart222 Jul 1, 2025
789ac79
Pulling-in solution pool logic from forestlib
whart222 Jul 1, 2025
39f386d
Rework of solnpools for Balas
whart222 Jul 1, 2025
1f419b7
Integration of pool managers
whart222 Jul 2, 2025
4dc67f3
Removing index_to_variable maps
whart222 Jul 2, 2025
f749087
Rounding discrete values
whart222 Jul 2, 2025
4d789cc
Misc API changes
whart222 Jul 2, 2025
a2c7ba2
Merge branch 'Pyomo:main' into solnpool
whart222 Jul 9, 2025
ab50d29
Reformatting
whart222 Jul 9, 2025
96de282
Refining Bunch API to align with Munch
whart222 Jul 9, 2025
d7ea2ef
Isolating use of "Munch"
whart222 Jul 9, 2025
cafd3a6
Removing import of munch
whart222 Jul 9, 2025
ed7b154
Removing munch import
whart222 Jul 9, 2025
5299493
Rework of dataclass setup
whart222 Jul 9, 2025
6eeb219
Further update to the dataclass
whart222 Jul 9, 2025
fd371a6
Conditional use of dataclass options
whart222 Jul 9, 2025
4ea2d9b
Reformatting with black
whart222 Jul 9, 2025
b80c1bb
Add comparison methods for solutions
whart222 Jul 9, 2025
13e6853
Fixing AOS doctests
whart222 Jul 9, 2025
f638889
Several test fixes
whart222 Jul 9, 2025
834cd95
Reformatting
whart222 Jul 10, 2025
235b702
Added num_solution checks to balas
viens-code Aug 18, 2025
d1668b5
Added num_solution checks to lp_enum
viens-code Aug 18, 2025
9548607
Add num_solution checks to lp_enum_solnpool
viens-code Aug 18, 2025
ac9f517
Updated gurobi_solnpool to check num_solutions and allow PoolSearchMo…
viens-code Aug 18, 2025
1a83132
Added checks to SolutionPool where max_pool_size exists
viens-code Aug 18, 2025
fe41db1
Added tests for invalid policies in SolutionPool
viens-code Aug 18, 2025
706c8db
Added pool name methods to PoolManager
viens-code Aug 18, 2025
14a33bd
Added policy type to SolutionPoolBase
viens-code Aug 18, 2025
0942029
Added methods to get pool/pools policy and max_pool_sizes
viens-code Aug 18, 2025
2430679
Added get_pool_sizes method
viens-code Aug 18, 2025
de7db76
Changed to .items in dict comprehensions where keys and values needed
viens-code Aug 18, 2025
221be05
Readability tweaks to emphasize active pool and set of pools
viens-code Aug 18, 2025
73fd086
Documentation adds for SolutionPool methods
viens-code Aug 19, 2025
249188e
Documentation Updates
viens-code Sep 2, 2025
09b4d66
Updates sense information in KeepBest pool
viens-code Sep 2, 2025
ec110a0
Enforce pass through behavior with PoolManager to_dict method
viens-code Sep 2, 2025
3e12b37
Added PoolManager to_dict pass through test
viens-code Sep 2, 2025
217bdc6
SolutionPool Updates
viens-code Sep 2, 2025
6262edc
Fixed issues caused by absence of to_dict method in Bunch/MyMunch
viens-code Sep 4, 2025
84ec9d0
Merge remote-tracking branch 'origin/main' into solnpool
whart222 Sep 5, 2025
5f4cdbd
Merge branch 'or-fusion:solnpool' into solnpool
viens-code Sep 5, 2025
73f8567
Merge pull request #1 from viens-code/solnpool
viens-code Sep 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
325 changes: 264 additions & 61 deletions doc/OnlineDocs/explanation/analysis/alternative_solutions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ more context than this result. For example,
The *alternative-solutions library* provides a variety of functions that
can be used to generate optimal or near-optimal solutions for a pyomo
model. Conceptually, these functions are like pyomo solvers. They can
be configured with solver names and options, and they return a list of
be configured with solver names and options, and they return a pool of
solutions for the pyomo model. However, these functions are independent
of pyomo's solver interface because they return a custom solution object.
of pyomo's solver interface because they return a custom pool manager object.

The following functions are defined in the alternative-solutions library:

Expand Down Expand Up @@ -73,7 +73,7 @@ solutions have integer objective values ranging from 0 to 90.
>>> m.c = pyo.Constraint(expr=sum(weights[i] * m.x[i] for i in range(4)) <= capacity)

We can execute the ``enumerate_binary_solutions`` function to generate a
list of ``Solution`` objects that represent alternative optimal
pool of ``Solution`` objects that represent alternative optimal
solutions:

.. doctest::
Expand All @@ -92,15 +92,50 @@ For example:

>>> print(solns[0])
{
"fixed_variables": [],
"objective": "o",
"objective_value": 90.0,
"solution": {
"x[0]": 0,
"x[1]": 1,
"x[2]": 0,
"x[3]": 1
}
"id": 0,
"objectives": [
{
"index": 0,
"name": "o",
"suffix": {},
"value": 90.0
}
],
"suffix": {},
"variables": [
{
"discrete": true,
"fixed": false,
"index": 0,
"name": "x[0]",
"suffix": {},
"value": 0
},
{
"discrete": true,
"fixed": false,
"index": 1,
"name": "x[1]",
"suffix": {},
"value": 1
},
{
"discrete": true,
"fixed": false,
"index": 2,
"name": "x[2]",
"suffix": {},
"value": 0
},
{
"discrete": true,
"fixed": false,
"index": 3,
"name": "x[3]",
"suffix": {},
"value": 1
}
]
}


Expand Down Expand Up @@ -157,56 +192,224 @@ precision issues.

>>> solns = aos.enumerate_binary_solutions(m, num_solutions=10, solver="glpk", abs_opt_gap = 0.5)
>>> assert(len(solns) == 4)
>>> for soln in sorted(solns, key=lambda s: str(s.get_variable_name_values())):
>>> for soln in sorted(solns):
... print(soln)
{
"fixed_variables": [],
"objective": "o",
"objective_value": 12.0,
"solution": {
"x[0]": 0,
"x[1]": 1,
"x[2]": 1,
"x[3]": 0,
"x[4]": 1
}
}
{
"fixed_variables": [],
"objective": "o",
"objective_value": 12.0,
"solution": {
"x[0]": 0,
"x[1]": 1,
"x[2]": 1,
"x[3]": 1,
"x[4]": 0
}
}
{
"fixed_variables": [],
"objective": "o",
"objective_value": 12.0,
"solution": {
"x[0]": 1,
"x[1]": 0,
"x[2]": 0,
"x[3]": 1,
"x[4]": 1
}
}
{
"fixed_variables": [],
"objective": "o",
"objective_value": 12.0,
"solution": {
"x[0]": 1,
"x[1]": 0,
"x[2]": 1,
"x[3]": 0,
"x[4]": 0
}
}
{
"id": 3,
"objectives": [
{
"index": 0,
"name": "o",
"suffix": {},
"value": 12.0
}
],
"suffix": {},
"variables": [
{
"discrete": true,
"fixed": false,
"index": 0,
"name": "x[0]",
"suffix": {},
"value": 0
},
{
"discrete": true,
"fixed": false,
"index": 1,
"name": "x[1]",
"suffix": {},
"value": 1
},
{
"discrete": true,
"fixed": false,
"index": 2,
"name": "x[2]",
"suffix": {},
"value": 1
},
{
"discrete": true,
"fixed": false,
"index": 3,
"name": "x[3]",
"suffix": {},
"value": 0
},
{
"discrete": true,
"fixed": false,
"index": 4,
"name": "x[4]",
"suffix": {},
"value": 1
}
]
}
{
"id": 2,
"objectives": [
{
"index": 0,
"name": "o",
"suffix": {},
"value": 12.0
}
],
"suffix": {},
"variables": [
{
"discrete": true,
"fixed": false,
"index": 0,
"name": "x[0]",
"suffix": {},
"value": 0
},
{
"discrete": true,
"fixed": false,
"index": 1,
"name": "x[1]",
"suffix": {},
"value": 1
},
{
"discrete": true,
"fixed": false,
"index": 2,
"name": "x[2]",
"suffix": {},
"value": 1
},
{
"discrete": true,
"fixed": false,
"index": 3,
"name": "x[3]",
"suffix": {},
"value": 1
},
{
"discrete": true,
"fixed": false,
"index": 4,
"name": "x[4]",
"suffix": {},
"value": 0
}
]
}
{
"id": 1,
"objectives": [
{
"index": 0,
"name": "o",
"suffix": {},
"value": 12.0
}
],
"suffix": {},
"variables": [
{
"discrete": true,
"fixed": false,
"index": 0,
"name": "x[0]",
"suffix": {},
"value": 1
},
{
"discrete": true,
"fixed": false,
"index": 1,
"name": "x[1]",
"suffix": {},
"value": 0
},
{
"discrete": true,
"fixed": false,
"index": 2,
"name": "x[2]",
"suffix": {},
"value": 0
},
{
"discrete": true,
"fixed": false,
"index": 3,
"name": "x[3]",
"suffix": {},
"value": 1
},
{
"discrete": true,
"fixed": false,
"index": 4,
"name": "x[4]",
"suffix": {},
"value": 1
}
]
}
{
"id": 0,
"objectives": [
{
"index": 0,
"name": "o",
"suffix": {},
"value": 12.0
}
],
"suffix": {},
"variables": [
{
"discrete": true,
"fixed": false,
"index": 0,
"name": "x[0]",
"suffix": {},
"value": 1
},
{
"discrete": true,
"fixed": false,
"index": 1,
"name": "x[1]",
"suffix": {},
"value": 0
},
{
"discrete": true,
"fixed": false,
"index": 2,
"name": "x[2]",
"suffix": {},
"value": 1
},
{
"discrete": true,
"fixed": false,
"index": 3,
"name": "x[3]",
"suffix": {},
"value": 0
},
{
"discrete": true,
"fixed": false,
"index": 4,
"name": "x[4]",
"suffix": {},
"value": 0
}
]
}


Interface Documentation
Expand Down
Loading
Loading