Skip to content
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

Fix PyROS Iteration Logging for Edge Case Involving Discrete Sets #3170

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion pyomo/contrib/pyros/pyros_algorithm_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,7 @@ def ROSolver_iterative_solve(model_data, config):
len(scaled_violations) == len(separation_model.util.performance_constraints)
and not separation_results.subsolver_error
and not separation_results.time_out
)
) or separation_results.all_discrete_scenarios_exhausted

iter_log_record = IterationLogRecord(
iteration=k,
Expand Down
1 change: 1 addition & 0 deletions pyomo/contrib/pyros/separation_problem_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,7 @@ def perform_separation_loop(model_data, config, solve_globally):
solver_call_results=ComponentMap(),
solved_globally=solve_globally,
worst_case_perf_con=None,
all_discrete_scenarios_exhausted=True,
)

perf_con_to_maximize = sorted_priority_groups[
Expand Down
29 changes: 27 additions & 2 deletions pyomo/contrib/pyros/solve_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,16 +347,23 @@ class SeparationLoopResults:
solver_call_results : ComponentMap
Mapping from performance constraints to corresponding
``SeparationSolveCallResults`` objects.
worst_case_perf_con : None or int, optional
worst_case_perf_con : None or Constraint
Performance constraint mapped to ``SeparationSolveCallResults``
object in `self` corresponding to maximally violating
separation problem solution.
all_discrete_scenarios_exhausted : bool, optional
For problems with discrete uncertainty sets,
True if all scenarios were explicitly accounted for in master
(which occurs if there have been
as many PyROS iterations as there are scenarios in the set)
False otherwise.
Attributes
----------
solver_call_results
solved_globally
worst_case_perf_con
all_discrete_scenarios_exhausted
found_violation
violating_param_realization
scaled_violations
Expand All @@ -365,11 +372,18 @@ class SeparationLoopResults:
time_out
"""

def __init__(self, solved_globally, solver_call_results, worst_case_perf_con):
def __init__(
self,
solved_globally,
solver_call_results,
worst_case_perf_con,
all_discrete_scenarios_exhausted=False,
):
"""Initialize self (see class docstring)."""
self.solver_call_results = solver_call_results
self.solved_globally = solved_globally
self.worst_case_perf_con = worst_case_perf_con
self.all_discrete_scenarios_exhausted = all_discrete_scenarios_exhausted

@property
def found_violation(self):
Expand Down Expand Up @@ -599,6 +613,17 @@ def get_violating_attr(self, attr_name):
"""
return getattr(self.main_loop_results, attr_name, None)

@property
def all_discrete_scenarios_exhausted(self):
"""
bool : For problems where the uncertainty set is of type
DiscreteScenarioSet,
True if last master problem solved explicitly
accounts for all scenarios in the uncertainty set,
False otherwise.
"""
return self.get_violating_attr("all_discrete_scenarios_exhausted")

@property
def worst_case_perf_con(self):
"""
Expand Down