Source code for niapy.algorithms.other.sa

# encoding=utf8
import logging

import numpy as np

from niapy.algorithms.algorithm import Algorithm

logging.basicConfig()
logger = logging.getLogger('niapy.algorithms.other')
logger.setLevel('INFO')

__all__ = ['SimulatedAnnealing', 'cool_delta', 'cool_linear']


def cool_delta(current_temperature, delta_temperature, **_kwargs):
    r"""Calculate new temperature by differences.

    Args:
        current_temperature (float):
        delta_temperature (float):

    Returns:
        float: New temperature.

    """
    return current_temperature - delta_temperature


def cool_linear(current_temperature, starting_temperature, max_evals, **_kwargs):
    r"""Calculate temperature with linear function.

    Args:
        current_temperature (float): Current temperature.
        starting_temperature (float):
        max_evals (int): Number of evaluations done.
        _kwargs (Dict[str, Any]): Additional arguments.

    Returns:
        float: New temperature.

    """
    return current_temperature - starting_temperature / max_evals


[docs]class SimulatedAnnealing(Algorithm): r"""Implementation of Simulated Annealing Algorithm. Algorithm: Simulated Annealing Algorithm Date: 2018 Authors: Jan Popič and Klemen Berkovič License: MIT Reference URL: Reference paper: Attributes: Name (List[str]): List of strings representing algorithm name. delta (float): Movement for neighbour search. starting_temperature (float); Starting temperature. delta_temperature (float): Change in temperature. cooling_method (Callable): Neighbourhood function. epsilon (float): Error value. See Also: * :class:`niapy.algorithms.Algorithm` """ Name = ['SimulatedAnnealing', 'SA']
[docs] @staticmethod def info(): r"""Get basic information of algorithm. Returns: str: Basic information of algorithm. See Also: * :func:`niapy.algorithms.Algorithm.info` """ return r"""None"""
[docs] def __init__(self, delta=0.5, starting_temperature=2000, delta_temperature=0.8, cooling_method=cool_delta, epsilon=1e-23, *args, **kwargs): """Initialize SimulatedAnnealing. Args: delta (Optional[float]): Movement for neighbour search. starting_temperature (Optional[float]); Starting temperature. delta_temperature (Optional[float]): Change in temperature. cooling_method (Optional[Callable]): Neighbourhood function. epsilon (Optional[float]): Error value. See Also * :func:`niapy.algorithms.Algorithm.__init__` """ kwargs.pop('population_size', None) super().__init__(1, *args, **kwargs) self.delta = delta self.starting_temperature = starting_temperature self.delta_temperature = delta_temperature self.cooling_method = cooling_method self.epsilon = epsilon
[docs] def set_parameters(self, delta=0.5, starting_temperature=2000, delta_temperature=0.8, cooling_method=cool_delta, epsilon=1e-23, **kwargs): r"""Set the algorithm parameters/arguments. Args: delta (Optional[float]): Movement for neighbour search. starting_temperature (Optional[float]); Starting temperature. delta_temperature (Optional[float]): Change in temperature. cooling_method (Optional[Callable]): Neighbourhood function. epsilon (Optional[float]): Error value. See Also * :func:`niapy.algorithms.Algorithm.set_parameters` """ kwargs.pop('population_size', None) super().set_parameters(population_size=1, **kwargs) self.delta = delta self.starting_temperature = starting_temperature self.delta_temperature = delta_temperature self.cooling_method = cooling_method self.epsilon = epsilon
[docs] def get_parameters(self): r"""Get algorithms parameters values. Returns: Dict[str, Any]: See Also * :func:`niapy.algorithms.Algorithm.get_parameters` """ d = super().get_parameters() d.pop('population_size', None) d.update({ 'delta': self.delta, 'delta_temperature': self.delta_temperature, 'starting_temperature': self.starting_temperature, 'epsilon': self.epsilon }) return d
[docs] def init_population(self, task): r"""Initialize the starting population. Args: task (Task): Optimization task. Returns: Tuple[numpy.ndarray, float, dict]: 1. Initial solution 2. Initial solutions fitness/objective value 3. Additional arguments """ x = task.lower + task.range * self.random(task.dimension) current_temperature, x_fit = self.starting_temperature, task.eval(x) return x, x_fit, {'current_temperature': current_temperature}
[docs] def run_iteration(self, task, x, x_fit, best_x, best_fitness, **params): r"""Core function of the algorithm. Args: task (Task): x (numpy.ndarray): x_fit (float): best_x (numpy.ndarray): best_fitness (float): **params (dict): Additional arguments. Returns: Tuple[numpy.ndarray, float, numpy.ndarray, float, dict]: 1. New solution 2. New solutions fitness/objective value 3. New global best solution 4. New global best solutions fitness/objective value 5. Additional arguments """ current_temperature = params.pop('current_temperature') c = task.repair(x - self.delta / 2 + self.random(task.dimension) * self.delta, rng=self.rng) c_fit = task.eval(c) delta_fit, r = c_fit - x_fit, self.random() if delta_fit < 0 or r < np.exp(delta_fit / current_temperature): x, x_fit = c, c_fit current_temperature = self.cooling_method(current_temperature, starting_temperature=self.starting_temperature, delta_temperature=self.delta_temperature, max_evals=task.max_evals) best_x, best_fitness = self.get_best(x, x_fit, best_x, best_fitness) return x, x_fit, best_x, best_fitness, {'current_temperature': current_temperature}