Source code for NiaPy.algorithms.basic.abc

import random as rnd
import copy
from NiaPy.benchmarks.utility import Utility

__all__ = ['ArtificialBeeColonyAlgorithm']


class SolutionABC:

    def __init__(self, D, LB, UB):
        self.D = D
        self.Solution = []
        self.Fitness = float('inf')
        self.LB = LB
        self.UB = UB
        self.generateSolution()

    def generateSolution(self):
        self.Solution = [self.LB + (self.UB - self.LB) * rnd.random()
                         for _i in range(self.D)]

    def repair(self):
        for i in range(self.D):
            if self.Solution[i] > self.UB:
                self.Solution[i] = self.UB

            if self.Solution[i] < self.LB:
                self.Solution[i] = self.LB

    def evaluate(self):
        self.Fitness = SolutionABC.FuncEval(self.D, self.Solution)

    def toString(self):
        pass


[docs]class ArtificialBeeColonyAlgorithm: r"""Implementation of Artificial Bee Colony algorithm. **Algorithm:** Artificial Bee Colony algorithm **Date:** 2018 **Author:** Uros Mlakar **License:** MIT **Reference paper:** Karaboga, D., and Bahriye B. "A powerful and efficient algorithm for numerical function optimization: artificial bee colony (ABC) algorithm." Journal of global optimization 39.3 (2007): 459-471. """ def __init__(self, D, NP, nFES, benchmark): """**__init__(self, D, NP, nFES, benchmark)**. Arguments: D {integer} -- dimension of problem NP {integer} -- population size nFES {integer} -- number of function evaluations benchmark {object} -- benchmark implementation object Raises: TypeError -- Raised when given benchmark function which does not exists. """ self.benchmark = Utility().get_benchmark(benchmark) self.D = D # dimension of the problem self.NP = NP # population size; number of search agents self.FoodNumber = int(self.NP / 2) self.Limit = 100 self.Trial = [] # trials self.Foods = [] # foods self.Probs = [] # probs self.nFES = nFES # number of function evaluations self.Lower = self.benchmark.Lower # lower bound self.Upper = self.benchmark.Upper # upper bound self.FEs = 0 self.Done = False SolutionABC.FuncEval = staticmethod(self.benchmark.function()) self.Best = SolutionABC(self.D, self.Lower, self.Upper)
[docs] def init(self): """Initialize positions.""" self.Probs = [0 for i in range(self.FoodNumber)] self.Trial = [0 for i in range(self.FoodNumber)] for i in range(self.FoodNumber): self.Foods.append(SolutionABC(self.D, self.Lower, self.Upper)) self.Foods[i].evaluate()
self.checkForBest(self.Foods[i])
[docs] def CalculateProbs(self): """Calculate probs.""" self.Probs = [1.0 / (self.Foods[i].Fitness + 0.01) for i in range(self.FoodNumber)] s = sum(self.Probs)
self.Probs = [self.Probs[i] / s for i in range(self.FoodNumber)]
[docs] def checkForBest(self, Solution): """Check best solution.""" if Solution.Fitness <= self.Best.Fitness:
self.Best = copy.deepcopy(Solution)
[docs] def tryEval(self, b): """Check evaluations.""" if self.FEs <= self.nFES: b.evaluate() self.FEs += 1 else:
self.Done = True
[docs] def run(self): """Run.""" self.init() self.FEs = self.FoodNumber while not self.Done: self.Best.toString() for i in range(self.FoodNumber): newSolution = copy.deepcopy(self.Foods[i]) param2change = int(rnd.random() * self.D) neighbor = int(self.FoodNumber * rnd.random()) newSolution.Solution[param2change] = self.Foods[i].Solution[param2change] \ + (-1 + 2 * rnd.random()) * \ (self.Foods[i].Solution[param2change] - self.Foods[neighbor].Solution[param2change]) newSolution.repair() self.tryEval(newSolution) if newSolution.Fitness < self.Foods[i].Fitness: self.checkForBest(newSolution) self.Foods[i] = newSolution self.Trial[i] = 0 else: self.Trial[i] += 1 self.CalculateProbs() t, s = 0, 0 while t < self.FoodNumber: if rnd.random() < self.Probs[s]: t += 1 Solution = copy.deepcopy(self.Foods[s]) param2change = int(rnd.random() * self.D) neighbor = int(self.FoodNumber * rnd.random()) while neighbor == s: neighbor = int(self.FoodNumber * rnd.random()) Solution.Solution[param2change] = self.Foods[s].Solution[param2change] \ + (-1 + 2 * rnd.random()) * ( self.Foods[s].Solution[param2change] - self.Foods[neighbor].Solution[param2change]) Solution.repair() self.tryEval(Solution) if Solution.Fitness < self.Foods[s].Fitness: self.checkForBest(newSolution) self.Foods[s] = Solution self.Trial[s] = 0 else: self.Trial[s] += 1 s += 1 if s == self.FoodNumber: s = 0 mi = self.Trial.index(max(self.Trial)) if self.Trial[mi] >= self.Limit: self.Foods[mi] = SolutionABC(self.D, self.Lower, self.Upper) self.tryEval(self.Foods[mi]) self.Trial[mi] = 0
return self.Best.Fitness