Skip to content

Commit

Permalink
Merge branch 'main' into rc_fixer_only_update_on_improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
DLWoodruff authored Nov 24, 2024
2 parents c2d36df + 6681326 commit d92b88d
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 11 deletions.
3 changes: 3 additions & 0 deletions doc/src/extensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ In its current state, the user might opt-in to presolve for two reasons:
2. For problems where a "fixer" extension or spoke is used, determining tight bounds on the
non-anticipative variables may improve the fixer's performance.

.. Note::
Like many solvers, the presolver will convert infinite bounds to 1e+100.

.. Note::
This capability requires the auto-persistent pyomo solver interface (APPSI) extensions
for Pyomo to be built on your system. This can be achieved by running ``pyomo build-extensions``
Expand Down
20 changes: 11 additions & 9 deletions mpisppy/cylinders/reduced_costs_spoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,22 +145,24 @@ def extract_and_store_reduced_costs(self):

# solver takes care of sign of rc, based on lb, ub and max,min
# rc can be of wrong sign if numerically 0 - accepted here, checked in extension
if (xb - xvar.lb <= self.bound_tol) or (xvar.ub - xb <= self.bound_tol):
if (xvar.lb is not None and xb - xvar.lb <= self.bound_tol) or (xvar.ub is not None and xvar.ub - xb <= self.bound_tol):
rc[ci] += sub._mpisppy_probability * sub.rc[xvar]
# not close to either bound -> rc = nan
else:
rc[ci] = np.nan

self._scenario_rc_buffer.fill(0)
ci = 0 # buffer index
for s in self.opt.local_scenarios.values():
for ndn_i, xvar in s._mpisppy_data.nonant_indices.items():
# fixed by modeler
if ndn_i in self._modeler_fixed_nonants[s]:
self._scenario_rc_buffer[ci] = np.nan
else:
self._scenario_rc_buffer[ci] = s.rc[xvar]
ci += 1
for sub in self.opt.local_subproblems.values():
for sn in sub.scen_list:
s = self.opt.local_scenarios[sn]
for ndn_i, xvar in s._mpisppy_data.nonant_indices.items():
# fixed by modeler
if ndn_i in self._modeler_fixed_nonants[s]:
self._scenario_rc_buffer[ci] = np.nan
else:
self._scenario_rc_buffer[ci] = sub.rc[xvar]
ci += 1
self.rc_scenario = self._scenario_rc_buffer
# print(f"In ReducedCostsSpoke; {self.rc_scenario=}")

Expand Down
5 changes: 3 additions & 2 deletions mpisppy/opt/presolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

from mpisppy import MPI

_INF = 1e+100

class _SPPresolver(abc.ABC):
"""Defines a presolver for distributed stochastic optimization problems
Expand Down Expand Up @@ -379,15 +380,15 @@ def _lb_generator(var_iterable):
for v in var_iterable:
lb = v.lb
if lb is None:
yield -np.inf
yield -_INF
yield lb


def _ub_generator(var_iterable):
for v in var_iterable:
ub = v.ub
if ub is None:
yield np.inf
yield _INF
yield ub


Expand Down

0 comments on commit d92b88d

Please sign in to comment.