# ____________________________________________________________________________________
#
# Pyomo: Python Optimization Modeling Objects
# Copyright (c) 2008-2026 National Technology and Engineering Solutions of Sandia, LLC
# Under the terms of Contract DE-NA0003525 with National Technology and Engineering
# Solutions of Sandia, LLC, the U.S. Government retains certain rights in this
# software. This software is distributed under the 3-clause BSD License.
# ____________________________________________________________________________________
"""Helper functions for variable reinitialization."""
import logging
import random
from pyomo.core import Var
logger = logging.getLogger('pyomo.contrib.multistart')
[docs]
def rand(val, lb, ub):
return random.uniform(lb, ub) # uniform distribution between lb and ub
[docs]
def midpoint_guess_and_bound(val, lb, ub):
"""Midpoint between current value and farthest bound."""
far_bound = ub if ((ub - val) >= (val - lb)) else lb # farther bound
return (far_bound + val) / 2
[docs]
def rand_guess_and_bound(val, lb, ub):
"""Random choice between current value and farthest bound."""
far_bound = ub if ((ub - val) >= (val - lb)) else lb # farther bound
return random.uniform(val, far_bound)
[docs]
def rand_distributed(val, lb, ub, divisions=9):
"""Random choice among evenly distributed set of values between bounds."""
set_distributed_vals = linspace(lb, ub, divisions)
return random.choice(set_distributed_vals)
[docs]
def simple_midpoint(val, lb, ub):
return (lb + ub) * 0.5
[docs]
def linspace(lower, upper, n):
"""Linearly spaced range."""
return [lower + x * (upper - lower) / (n - 1) for x in range(n)]
strategies = {
"rand": rand,
"midpoint_guess_and_bound": midpoint_guess_and_bound,
"rand_guess_and_bound": rand_guess_and_bound,
"rand_distributed": rand_distributed,
"midpoint": simple_midpoint,
}
[docs]
def reinitialize_variables(model, config):
"""Reinitializes all variable values in the model.
Excludes fixed, noncontinuous, and unbounded variables.
"""
for var in model.component_data_objects(ctype=Var, descend_into=True):
if var.is_fixed() or not var.is_continuous():
continue
if var.lb is None or var.ub is None:
if not config.suppress_unbounded_warning:
logger.warning(
'Skipping reinitialization of unbounded variable '
'%s with bounds (%s, %s). '
'To suppress this message, set the '
'suppress_unbounded_warning flag.' % (var.name, var.lb, var.ub)
)
continue
val = var.value if var.value is not None else (var.lb + var.ub) / 2
# apply reinitialization strategy to variable
var.set_value(
strategies[config.strategy](val, var.lb, var.ub), skip_validation=True
)