Skip to content
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
25 changes: 1 addition & 24 deletions doc/src/spokes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,30 +62,7 @@ is a sample json file:
ph_ob
^^^^^

This bounder is similar to the Lagrangian bounder, except that it executes a PH
algorithm to obtain its own W values. The idea is that it can use lower rho values
so as to obtain better outer (lower when minimizing) bounds. It can also provide
a Lagrangian bound even if the hub does not provide lagrangian multipliers.

The easiest way to use ``ph_ob`` is via the vanilla ``ph_ob_spoke`` method
as illustrated in ``examples.farmer.archive.farmer_cylinders.py``. This method takes values
from the config object (assuming the config object's ``ph_ob`` method
was called as shown in the function ``examples.farmer.archive.farmer_cylinders._parse_args``)
and sets up the options for the spoke.

The option ``ph-ob-initial-rho-rescale-factor`` defaults to 0.1, so if nothing
other than ``--ph-ob`` is given on the command line, the ph_ob spoke will use
one tenth the default rho (it might use one tenth of rho from
a rho setter if one is configured in the cylinders program and passed to the ph_ob
constructor). Additional control over rho values
is provided by the ``phob-rho-rescale-factors-json`` option which is a json
file that provides a dictionary with keys that are iteration numbers and values
that are rescale factors. Note that all rescaling is cummulative.

See ``examples.uc.gradient_uc_cylinders.py`` for an example that uses a cost-based
rho setter for the uc problem in the ph_ob cylinder.

As of August, 2024 use of a gradient based rho with ph_ob is untested.
This cylinder was deprecated in August of 2025 in favor of ph_dual.

Reduced Costs
^^^^^^^^^^^^^
Expand Down
4 changes: 0 additions & 4 deletions examples/afew.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,6 @@ def do_one(dirname, progname, np, argstring):


# for farmer, the first arg is num_scens and is required
do_one("farmer/archive", "farmer_cylinders.py", 3,
"--num-scens=3 --bundles-per-rank=0 --max-iterations=50 "
"--default-rho=1 --sep-rho --display-convergence-detail "
"--solver-name={} --xhatshuffle --lagrangian --use-norm-rho-updater".format(solver_name))
do_one("farmer", "farmer_lshapedhub.py", 2,
"--num-scens=3 --bundles-per-rank=0 --max-iterations=50 "
"--solver-name={} --rel-gap=0.0 "
Expand Down
12 changes: 2 additions & 10 deletions examples/distr/distr_admm_cylinders.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ def _parse_args():
cfg.aph_args()
cfg.xhatxbar_args()
cfg.lagrangian_args()
cfg.ph_ob_args()
cfg.tracking_args()
cfg.add_to_config("run_async",
description="Run with async projective hedging instead of progressive hedging",
Expand All @@ -46,7 +45,7 @@ def _parse_args():
# This need to be executed long before the cylinders are created
def _count_cylinders(cfg):
count = 1
cfglist = ["xhatxbar", "lagrangian", "ph_ob"] # All the cfg arguments that create a new cylinders
cfglist = ["xhatxbar", "lagrangian"] # All the cfg arguments that create a new cylinders
# Add to this list any cfg attribute that would create a spoke
for cylname in cfglist:
if cfg[cylname]:
Expand Down Expand Up @@ -133,12 +132,7 @@ def main():
rho_setter = None)


# ph outer bounder spoke
if cfg.ph_ob:
ph_ob_spoke = vanilla.ph_ob_spoke(*beans,
scenario_creator_kwargs=scenario_creator_kwargs,
rho_setter = None,
variable_probability=variable_probability)
# ph outer bounder spoke removed August 2025 (use ph_dual)

# xhat looper bound spoke
if cfg.xhatxbar:
Expand All @@ -147,8 +141,6 @@ def main():
list_of_spoke_dict = list()
if cfg.lagrangian:
list_of_spoke_dict.append(lagrangian_spoke)
if cfg.ph_ob:
list_of_spoke_dict.append(ph_ob_spoke)
if cfg.xhatxbar:
list_of_spoke_dict.append(xhatxbar_spoke)

Expand Down
9 changes: 1 addition & 8 deletions examples/farmer/CI/farmer_rho_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ def _parse_args():
cfg.fwph_args()
cfg.lagrangian_args()
cfg.lagranger_args()
cfg.ph_ob_args()
cfg.xhatshuffle_args()
cfg.dynamic_gradient_args() # gets gradient args for free
cfg.add_to_config("crops_mult",
Expand Down Expand Up @@ -144,11 +143,7 @@ def main():
scenario_creator_kwargs=scenario_creator_kwargs,
rho_setter = rho_setter)

# ph outer bounder spoke
if cfg.ph_ob:
ph_ob_spoke = vanilla.ph_ob_spoke(*beans,
scenario_creator_kwargs=scenario_creator_kwargs,
rho_setter = rho_setter)
# ph outer bounder spoke was removed August 2025

# xhat looper bound spoke
if cfg.xhatlooper:
Expand All @@ -165,8 +160,6 @@ def main():
list_of_spoke_dict.append(lagrangian_spoke)
if cfg.lagranger:
list_of_spoke_dict.append(lagranger_spoke)
if cfg.ph_ob:
list_of_spoke_dict.append(ph_ob_spoke)
if cfg.xhatlooper:
list_of_spoke_dict.append(xhatlooper_spoke)
if cfg.xhatshuffle:
Expand Down
13 changes: 1 addition & 12 deletions examples/farmer/archive/farmer_cylinders.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ def _parse_args():
cfg.fwph_args()
cfg.lagrangian_args()
cfg.lagranger_args()
cfg.ph_ob_args()
cfg.xhatshuffle_args()
cfg.converger_args()
cfg.wxbar_read_write_args()
Expand Down Expand Up @@ -154,15 +153,7 @@ def main():
lagranger_spoke = vanilla.lagranger_spoke(*beans,
scenario_creator_kwargs=scenario_creator_kwargs,
rho_setter = rho_setter)
# ph outer bounder spoke
if cfg.ph_ob:
ph_ob_spoke = vanilla.ph_ob_spoke(*beans,
scenario_creator_kwargs=scenario_creator_kwargs,
rho_setter = rho_setter)
if cfg.sep_rho:
vanilla.add_sep_rho(ph_ob_spoke, cfg)
if cfg.coeff_rho:
vanilla.add_coeff_rho(ph_ob_spoke, cfg)
# ph outer bounder spoke removed August 2025

# xhat looper bound spoke
if cfg.xhatlooper:
Expand All @@ -184,8 +175,6 @@ def main():
list_of_spoke_dict.append(lagrangian_spoke)
if cfg.lagranger:
list_of_spoke_dict.append(lagranger_spoke)
if cfg.ph_ob:
list_of_spoke_dict.append(ph_ob_spoke)
if cfg.xhatlooper:
list_of_spoke_dict.append(xhatlooper_spoke)
if cfg.xhatshuffle:
Expand Down
4 changes: 2 additions & 2 deletions examples/run_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ def do_one_mmw(dirname, modname, runefstring, npyfile, mmwargstring):

do_one("uc", "gradient_uc_cylinders.py", 15,
"--bundles-per-rank=0 --max-iterations=100 --default-rho=1 "
"--xhatshuffle --ph-ob --num-scens=5 --max-solver-threads=2 "
"--xhatshuffle --lagrangian --num-scens=5 --max-solver-threads=2 "
"--lagrangian-iter0-mipgap=1e-7 --ph-mipgaps-json=phmipgaps.json "
f"--solver-name={solver_name} --xhatpath uc_cyl_nonants.npy "
"--rel-gap 0.00001 --abs-gap=1 --intra-hub-conv-thresh=-1 "
Expand All @@ -412,7 +412,7 @@ def do_one_mmw(dirname, modname, runefstring, npyfile, mmwargstring):
"--solver-name={}".format(solver_name))
# as of May 2022, this one works well, but outputs some crazy messages
do_one("uc", "uc_ama.py", 3,
"--bundles-per-rank=0 --max-iterations=2 "
"--bundles-per-rank=0 --max-iterations=2 "
"--default-rho=1 --num-scens=3 "
"--fixer-tol=1e-2 --lagranger --xhatshuffle "
"--solver-name={}".format(solver_name))
Expand Down
13 changes: 2 additions & 11 deletions examples/stoch_distr/stoch_distr_admm_cylinders.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ def _parse_args():
cfg.xhatxbar_args()
cfg.fwph_args()
cfg.lagrangian_args()
cfg.ph_ob_args()
cfg.tracking_args()
cfg.add_to_config("run_async",
description="Run with async projective hedging instead of progressive hedging",
Expand All @@ -52,7 +51,7 @@ def _parse_args():

def _count_cylinders(cfg):
count = 1
cfglist = ["xhatxbar", "lagrangian", "ph_ob"] # All the cfg arguments that create a new cylinders
cfglist = ["xhatxbar", "lagrangian"] # All the cfg arguments that create a new cylinders
# Add to this list any cfg attribute that would create a spoke
for cylname in cfglist:
if cfg[cylname]:
Expand Down Expand Up @@ -127,13 +126,7 @@ def _wheel_creator(cfg, n_cylinders, scenario_creator, variable_probability, all
if cfg.fwph:
fw_spoke = vanilla.fwph_spoke(*beans, scenario_creator_kwargs=scenario_creator_kwargs)

# ph outer bounder spoke
if cfg.ph_ob:
ph_ob_spoke = vanilla.ph_ob_spoke(*beans,
scenario_creator_kwargs=scenario_creator_kwargs,
rho_setter = None,
all_nodenames=all_nodenames,
variable_probability=variable_probability)
# ph outer bounder spoke removed August 2025 (replace with ph_dual)

# xhat looper bound spoke
if cfg.xhatxbar:
Expand All @@ -148,8 +141,6 @@ def _wheel_creator(cfg, n_cylinders, scenario_creator, variable_probability, all
list_of_spoke_dict.append(fw_spoke)
if cfg.lagrangian:
list_of_spoke_dict.append(lagrangian_spoke)
if cfg.ph_ob:
list_of_spoke_dict.append(ph_ob_spoke)
if cfg.xhatxbar:
list_of_spoke_dict.append(xhatxbar_spoke)

Expand Down
9 changes: 1 addition & 8 deletions examples/uc/gradient_uc_cylinders.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ def _parse_args():
cfg.xhatshuffle_args()
cfg.cross_scenario_cuts_args()
cfg.dynamic_gradient_args() # gets you gradient_args for free
cfg.ph_ob_args()
cfg.add_to_config("ph_mipgaps_json",
description="json file with mipgap schedule (default None)",
domain=str,
Expand Down Expand Up @@ -176,11 +175,7 @@ def main():
if xhatlooper:
xhatlooper_spoke = vanilla.xhatlooper_spoke(*beans, scenario_creator_kwargs=scenario_creator_kwargs)

# ph outer bounder spoke
if cfg.ph_ob:
ph_ob_spoke = vanilla.ph_ob_spoke(*beans,
scenario_creator_kwargs=scenario_creator_kwargs,
rho_setter = rho_setter)
# ph outer bounder spoke removed August 2025

# xhat shuffle bound spoke
if xhatshuffle:
Expand All @@ -195,8 +190,6 @@ def main():
list_of_spoke_dict.append(fw_spoke)
if lagrangian:
list_of_spoke_dict.append(lagrangian_spoke)
if cfg.ph_ob:
list_of_spoke_dict.append(ph_ob_spoke)
if xhatlooper:
list_of_spoke_dict.append(xhatlooper_spoke)
if xhatshuffle:
Expand Down
Loading
Loading