Source code for edo.operators.shrink

""" Functions for shrinking the search space. """


def _get_param_values(parents, subtype, name):
    """Get the parameter values from the parents for a particular distribution
    subtype parameter."""

    values = []
    for _, metadata in parents:
        for pdf in metadata:
            if isinstance(pdf, subtype):
                try:
                    for val in vars(pdf)[name]:
                        values.append(val)
                except TypeError:
                    values.append(vars(pdf)[name])

    return values


def _adjust_subtype_param_limits(parents, subtype, itr, shrinkage):
    r"""Adjust the search space of a distribution subtype's parameters
    according to a power law on its limits:

    .. math::

        u_{t+1} - l_{t+1} = (u_t - l_t) * k^t,

    where :math:`t` is the current timestep, :math:`u_t, l_t` denote the upper
    and lower limits of the parameter at iteration :math:`t`, and :math:`k \in
    (0, 1)` is some ``shrinkage`` factor.
    """

    for name, limits in subtype.param_limits.items():
        values = _get_param_values(parents, subtype, name)
        if values:
            midpoint = sum(values) / len(values)
            shift = (max(limits) - min(limits)) * (shrinkage ** itr) / 2

            lower = max(min(limits), midpoint - shift)
            upper = min(min(limits), midpoint + shift)

            subtype.param_limits[name] = sorted([lower, upper])

    return subtype


[docs]def shrink(parents, families, itr, shrinkage): """Given the current progress of the evolutionary algorithm, shrink its search space, i.e. the parameter spaces for each of the distribution classes in ``families``. Parameters ---------- parents : list of `Individual` instances The parent individuals for this iteration. families : list of `Distribution` instances The families of distributions to be shrunk. itr : int The current iteration. shrinkage : float The shrinkage factor between 0 and 1. Returns ------- families : list of `Distribution` instances The altered families. """ for family in families: for i, subtype in family.subtypes.items(): subtype = _adjust_subtype_param_limits( parents, subtype, itr, shrinkage ) family.subtypes[i] = subtype return families