Source code for NiaPy.algorithms.basic.fpa

# encoding=utf8
import logging

from scipy.special import gamma as Gamma
from numpy import where, sin, fabs, pi, zeros

from NiaPy.algorithms.algorithm import Algorithm

logging.basicConfig()
logger = logging.getLogger('NiaPy.algorithms.basic')
logger.setLevel('INFO')

__all__ = ['FlowerPollinationAlgorithm']

[docs]class FlowerPollinationAlgorithm(Algorithm): r"""Implementation of Flower Pollination algorithm. Algorithm: Flower Pollination algorithm Date: 2018 Authors: Dusan Fister, Iztok Fister Jr. and Klemen Berkovič License: MIT Reference paper: Yang, Xin-She. "Flower pollination algorithm for global optimization. International conference on unconventional computing and natural computation. Springer, Berlin, Heidelberg, 2012. References URL: Implementation is based on the following MATLAB code: https://www.mathworks.com/matlabcentral/fileexchange/45112-flower-pollination-algorithm?requestedDomain=true Attributes: Name (List[str]): List of strings representing algorithm names. p (float): probability switch. beta (float): Shape of the gamma distribution (should be greater than zero). See Also: * :class:`NiaPy.algorithms.Algorithm` """ Name = ['FlowerPollinationAlgorithm', 'FPA']
[docs] @staticmethod def algorithmInfo(): r"""Get default information of algorithm. Returns: str: Basic information. See Also: * :func:`NiaPy.algorithms.Algorithm.algorithmInfo` """ return r"""Yang, Xin-She. "Flower pollination algorithm for global optimization. International conference on unconventional computing and natural computation. Springer, Berlin, Heidelberg, 2012."""
[docs] @staticmethod def typeParameters(): r"""TODO. Returns: Dict[str, Callable]: * p (function): TODO * beta (function): TODO See Also: * :func:`NiaPy.algorithms.Algorithm.typeParameters` """ d = Algorithm.typeParameters() d.update({ 'p': lambda x: isinstance(x, float) and 0 <= x <= 1, 'beta': lambda x: isinstance(x, (float, int)) and x > 0, }) return d
[docs] def setParameters(self, NP=25, p=0.35, beta=1.5, **ukwargs): r"""Set core parameters of FlowerPollinationAlgorithm algorithm. Arguments: NP (int): Population size. p (float): Probability switch. beta (float): Shape of the gamma distribution (should be greater than zero). See Also: * :func:`NiaPy.algorithms.Algorithm.setParameters` """ Algorithm.setParameters(self, NP=NP, **ukwargs) self.p, self.beta = p, beta self.S = zeros((NP, 10))
[docs] def repair(self, x, task): r"""Repair solution to search space. Args: x (numpy.ndarray): Solution to fix. task (Task): Optimization task. Returns: numpy.ndarray: fixed solution. """ ir = where(x > task.Upper) x[ir] = task.Lower[ir] + x[ir] % task.bRange[ir] ir = where(x < task.Lower) x[ir] = task.Lower[ir] + x[ir] % task.bRange[ir] return x
[docs] def levy(self, D): r"""Levy function. Returns: float: Next Levy number. """ sigma = (Gamma(1 + self.beta) * sin(pi * self.beta / 2) / (Gamma((1 + self.beta) / 2) * self.beta * 2 ** ((self.beta - 1) / 2))) ** (1 / self.beta) return 0.01 * (self.normal(0, 1, D) * sigma / fabs(self.normal(0, 1, D)) ** (1 / self.beta))
[docs] def initPopulation(self, task): pop, fpop, d = Algorithm.initPopulation(self, task) d.update({'S': zeros((self.NP, task.D))}) return pop, fpop, d
[docs] def runIteration(self, task, Sol, Sol_f, xb, fxb, S, **dparams): r"""Core function of FlowerPollinationAlgorithm algorithm. Args: task (Task): Optimization task. Sol (numpy.ndarray): Current population. Sol_f (numpy.ndarray): Current population fitness/function values. xb (numpy.ndarray): Global best solution. fxb (float): Global best solution function/fitness value. **dparams (Dict[str, Any]): Additional arguments. Returns: Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, float, Dict[str, Any]]: 1. New population. 2. New populations fitness/function values. 3. New global best solution. 4. New global best solution fitness/objective value. 5. Additional arguments. """ for i in range(self.NP): if self.uniform(0, 1) > self.p: S[i] += self.levy(task.D) * (Sol[i] - xb) else: JK = self.Rand.permutation(self.NP) S[i] += self.uniform(0, 1) * (Sol[JK[0]] - Sol[JK[1]]) S[i] = self.repair(S[i], task) f_i = task.eval(S[i]) if f_i <= Sol_f[i]: Sol[i], Sol_f[i] = S[i], f_i if f_i <= fxb: xb, fxb = S[i].copy(), f_i return Sol, Sol_f, xb, fxb, {'S': S}
# vim: tabstop=3 noexpandtab shiftwidth=3 softtabstop=3