# encoding=utf8
import logging
from niapy.algorithms.algorithm import Algorithm
from niapy.util import levy_flight
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): Switch probability.
See Also:
* :class:`niapy.algorithms.Algorithm`
"""
Name = ['FlowerPollinationAlgorithm', 'FPA']
[docs] @staticmethod
def info():
r"""Get default information of algorithm.
Returns:
str: Basic information.
See Also:
* :func:`niapy.algorithms.Algorithm.info`
"""
return r"""Yang, Xin-She. "Flower pollination algorithm for global optimization. International conference on unconventional computing and natural computation. Springer, Berlin, Heidelberg, 2012."""
[docs] def __init__(self, population_size=20, p=0.8, *args, **kwargs):
"""Initialize FlowerPollinationAlgorithm.
Args:
population_size (int): Population size.
p (float): Switch probability.
See Also:
* :func:`niapy.algorithms.Algorithm.__init__`
"""
super().__init__(population_size, *args, **kwargs)
self.p = p
[docs] def set_parameters(self, population_size=25, p=0.8, **kwargs):
r"""Set core parameters of FlowerPollinationAlgorithm algorithm.
Args:
population_size (int): Population size.
p (float): Switch probability.
See Also:
* :func:`niapy.algorithms.Algorithm.set_parameters`
"""
super().set_parameters(population_size=population_size, **kwargs)
self.p = p
[docs] def init_population(self, task):
"""Initialize population."""
pop, fpop, d = super().init_population(task)
d.update({'solutions': pop.copy()})
return pop, fpop, d
[docs] def run_iteration(self, task, population, population_fitness, best_x, best_fitness, **params):
r"""Core function of FlowerPollinationAlgorithm algorithm.
Args:
task (Task): Optimization task.
population (numpy.ndarray): Current population.
population_fitness (numpy.ndarray): Current population fitness/function values.
best_x (numpy.ndarray): Global best solution.
best_fitness (float): Global best solution function/fitness value.
**params (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.
"""
solutions = params.pop('solutions')
for i in range(self.population_size):
if self.random() > self.p:
step_size = levy_flight(size=task.dimension, rng=self.rng)
solutions[i] = population[i] + step_size * (population[i] - best_x)
solutions[i] = task.repair(solutions[i], rng=self.rng)
else:
j, k = self.rng.choice(self.population_size, size=2, replace=False)
solutions[i] += self.random() * (population[j] - population[k])
solutions[i] = task.repair(solutions[i], rng=self.rng)
f_i = task.eval(solutions[i])
if f_i <= population_fitness[i]:
population[i], population_fitness[i] = solutions[i].copy(), f_i
if f_i <= best_fitness:
best_x, best_fitness = solutions[i].copy(), f_i
return population, population_fitness, best_x, best_fitness, {'solutions': solutions}