Passed
Pull Request — master (#24)
by Grega
01:26
created

ArtificialBeeColonyAlgorithm   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 88
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 88
rs 10
wmc 21

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __init__() 0 13 1
A reset() 0 2 1
A init() 0 7 4
D run() 0 52 10
A CalculateProbs() 0 5 3
A checkForBest() 0 3 2
1
"""Artificial Bee Colony algorithm.
2
3
Date: 12. 2. 2018
4
5
Authors : Uros Mlakar
6
7
License: MIT
8
9
Reference paper: Karaboga, D., and Bahriye B. "A powerful
10
and efficient algorithm for numerical function optimization: artificial
11
bee colony (ABC) algorithm." Journal of global optimization 39.3 (2007): 459-471.
12
13
"""
14
15
import random as rnd
16
import copy
17
18
__all__ = ['ArtificialBeeColonyAlgorithm']
19
20
21
class SolutionABC:
22
    def __init__(self, D, LB, UB):
23
        self.D = D
24
        self.Solution = []
25
        self.Fitness = float('inf')
26
        self.LB = LB
27
        self.UB = UB
28
        self.generateSolution()
29
30
    def generateSolution(self):
31
        self.Solution = [self.LB + (self.UB - self.LB)
32
                         * rnd.random() for i in range(self.D)]
33
34
    def repair(self):
35
        for i in range(self.D):
36
            if (self.Solution[i] > self.UB):
0 ignored issues
show
Unused Code Coding Style introduced by
There is an unnecessary parenthesis after if.
Loading history...
37
                self.Solution[i] = self.UB
38
            if self.Solution[i] < self.LB:
39
                self.Solution[i] = self.LB
40
41
    def evaluate(self):
42
        self.Fitness = SolutionABC.FuncEval(self.D, self.Solution)
43
44
    def toString(self):
45
        pass
46
47
48
class ArtificialBeeColonyAlgorithm:
0 ignored issues
show
best-practice introduced by
Too many instance attributes (11/7)
Loading history...
49
    def __init__(self, NP, D, nFES, Lower, Upper, function):
50
        self.NP = NP
51
        self.D = D
52
        self.FoodNumber = self.NP / 2
53
        self.Limit = 100
54
        self.Trial = []
55
        self.Foods = []
56
        self.Probs = []
57
        self.nFES = nFES
58
        self.Lower = Lower
59
        self.Upper = Upper
60
        SolutionABC.FuncEval = staticmethod(function)
61
        self.Best = SolutionABC(self.D, Lower, Upper)
62
63
    def reset(self):
64
        self.__init__(self.NP, self.D, self.MaxCycle)
0 ignored issues
show
Bug introduced by
The Instance of ArtificialBeeColonyAlgorithm does not seem to have a member named MaxCycle.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
65
66
    def init(self):
67
        self.Probs = [0 for i in range(self.FoodNumber)]
68
        self.Trial = [0 for i in range(self.FoodNumber)]
69
        for i in range(self.FoodNumber):
70
            self.Foods.append(SolutionABC(self.D, self.Lower, self.Upper))
71
            self.Foods[i].evaluate()
72
            self.checkForBest(self.Foods[i])
73
74
    def CalculateProbs(self):
75
        self.Probs = [1.0 / (self.Foods[i].Fitness + 0.01)
76
                      for i in range(self.FoodNumber)]
77
        s = sum(self.Probs)
78
        self.Probs = [self.Probs[i] / s for i in range(self.FoodNumber)]
79
80
    def checkForBest(self, Solution):
81
        if Solution.Fitness <= self.Best.Fitness:
82
            self.Best = copy.deepcopy(Solution)
83
84
    def run(self):
85
        self.init()
86
        FEs = self.FoodNumber
87
        while FEs < self.nFES:
88
            self.Best.toString()
89
            for i in range(self.FoodNumber):
90
                newSolution = copy.deepcopy(self.Foods[i])
91
                param2change = int(rnd.random() * self.D)
92
                neighbor = int(self.FoodNumber * rnd.random())
93
                newSolution.Solution[param2change] = self.Foods[i].Solution[param2change] + (-1 + 2 * rnd.random()) * (
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (119/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
94
                    self.Foods[i].Solution[param2change] - self.Foods[neighbor].Solution[param2change])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (103/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
95
                newSolution.repair()
96
                newSolution.evaluate()
97
                if newSolution.Fitness < self.Foods[i].Fitness:
98
                    self.checkForBest(newSolution)
99
                    self.Foods[i] = newSolution
100
                    self.Trial[i] = 0
101
                else:
102
                    self.Trial[i] += 1
103
            FEs += self.FoodNumber
104
            self.CalculateProbs()
105
            t, s = 0, 0
106
            while t < self.FoodNumber:
107
                if rnd.random() < self.Probs[s]:
108
                    t += 1
109
                    Solution = copy.deepcopy(self.Foods[s])
110
                    param2change = int(rnd.random() * self.D)
111
                    neighbor = int(self.FoodNumber * rnd.random())
112
                    while neighbor == s:
113
                        neighbor = int(self.FoodNumber * rnd.random())
114
                    Solution.Solution[param2change] = self.Foods[s].Solution[param2change] + (-1 + 2 * rnd.random()) * (
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (120/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
115
                        self.Foods[s].Solution[param2change] - self.Foods[neighbor].Solution[param2change])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (107/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
116
                    Solution.repair()
117
                    Solution.evaluate()
118
                    FEs += 1
119
                    if Solution.Fitness < self.Foods[s].Fitness:
120
                        self.checkForBest(newSolution)
121
                        self.Foods[s] = Solution
122
                        self.Trial[s] = 0
123
                    else:
124
                        self.Trial[s] += 1
125
                s += 1
126
                if s == self.FoodNumber:
127
                    s = 0
128
129
            mi = self.Trial.index(max(self.Trial))
130
            if self.Trial[mi] >= self.Limit:
131
                self.Foods[mi] = SolutionABC(self.D, self.Lower, self.Upper)
132
                self.Foods[mi].evaluate()
133
                FEs += 1
134
                self.Trial[mi] = 0
135
        return self.Best.Fitness
136