Completed
Push — master ( 602eea...026eaa )
by
unknown
04:14 queued 01:18
created

ArtificialBeeColonyAlgorithm   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 132
Duplicated Lines 11.36 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 15
loc 132
rs 10
wmc 22

6 Methods

Rating   Name   Duplication   Size   Complexity  
B __init__() 0 34 1
A tryEval() 0 6 2
A init() 0 7 4
C run() 0 54 10
A CalculateProbs() 0 5 3
A checkForBest() 0 3 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
import random as rnd
2
import copy
3
from NiaPy.benchmarks.utility import Utility
4
5
__all__ = ['ArtificialBeeColonyAlgorithm']
6
7
8
class SolutionABC(object):
9
10
    def __init__(self, D, LB, UB):
11
        self.D = D
12
        self.Solution = []
13
        self.Fitness = float('inf')
14
        self.LB = LB
15
        self.UB = UB
16
        self.generateSolution()
17
18
    def generateSolution(self):
19
        self.Solution = [self.LB + (self.UB - self.LB) * rnd.random()
20
                         for _i in range(self.D)]
21
22
    def repair(self):
23
        for i in range(self.D):
24
            if self.Solution[i] > self.UB:
25 View Code Duplication
                self.Solution[i] = self.UB
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
26
27
            if self.Solution[i] < self.LB:
28
                self.Solution[i] = self.LB
29
30
    def evaluate(self):
31
        self.Fitness = SolutionABC.FuncEval(self.D, self.Solution)
32
33
    def toString(self):
34
        pass
35
36
37
class ArtificialBeeColonyAlgorithm(object):
38
    """Artificial Bee Colony algorithm.
39
40
    Date: 12. 2. 2018
41
42
    Authors : Uros Mlakar
43
44
    License: MIT
45
46
    Reference paper: Karaboga, D., and Bahriye B. "A powerful
47
    and efficient algorithm for numerical function optimization: artificial
48
    bee colony (ABC) algorithm." Journal of global optimization 39.3 (2007): 459-471.
49
50
    EDITED - TODO: More tests are required! Validation!
51
52
    TODO: EVALUATIONS!
53
    """
54
55
    def __init__(self, D, NP, nFES, benchmark):
56
        """**__init__(self, D, NP, nFES, benchmark)**.
57
58
        Arguments:
59
            D {integer} -- dimension of problem
60
61
            NP {integer} -- population size
62
63
            nFES {integer} -- number of function evaluations
64
65
            benchmark {object} -- benchmark implementation object
66
67
        Raises:
68
            TypeError -- Raised when given benchmark function which does not exists.
69
70
        """
71
72
        self.benchmark = Utility().get_benchmark(benchmark)
73
        self.D = D
74
        self.NP = NP
75
        self.FoodNumber = int(self.NP / 2)
76
        self.Limit = 100
77
        self.Trial = []
78
        self.Foods = []
79
        self.Probs = []
80
        self.nFES = nFES
81
        self.Lower = self.benchmark.Lower
82
        self.Upper = self.benchmark.Upper
83
84
        self.FEs = 0
85
        self.Done = False
86
87
        SolutionABC.FuncEval = staticmethod(self.benchmark.function())
88
        self.Best = SolutionABC(self.D, self.Lower, self.Upper)
89
90
    def init(self):
91
        self.Probs = [0 for i in range(self.FoodNumber)]
92
        self.Trial = [0 for i in range(self.FoodNumber)]
93
        for i in range(self.FoodNumber):
94
            self.Foods.append(SolutionABC(self.D, self.Lower, self.Upper))
95
            self.Foods[i].evaluate()
96
            self.checkForBest(self.Foods[i])
97
98
    def CalculateProbs(self):
99
        self.Probs = [1.0 / (self.Foods[i].Fitness + 0.01)
100
                      for i in range(self.FoodNumber)]
101
        s = sum(self.Probs)
102
        self.Probs = [self.Probs[i] / s for i in range(self.FoodNumber)]
103
104
    def checkForBest(self, Solution):
105
        if Solution.Fitness <= self.Best.Fitness:
106
            self.Best = copy.deepcopy(Solution)
107
108
    def tryEval(self,b):
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
Loading history...
109
        if self.FEs <= self.nFES:
110
            b.evaluate()
111
            self.FEs+=1
0 ignored issues
show
Coding Style introduced by
Exactly one space required around assignment
Loading history...
112
        else:
113
            self.Done = True
114
115
    def run(self):
116
        self.init()
117
        self.FEs = self.FoodNumber
118
        while not self.Done:
119
            self.Best.toString()
120
            for i in range(self.FoodNumber):
121
                newSolution = copy.deepcopy(self.Foods[i])
122
                param2change = int(rnd.random() * self.D)
123
                neighbor = int(self.FoodNumber * rnd.random())
124
                newSolution.Solution[param2change] = self.Foods[i].Solution[param2change] \
125
                    + (-1 + 2 * rnd.random()) * \
126
                    (self.Foods[i].Solution[param2change] -
127
                     self.Foods[neighbor].Solution[param2change])
128
                newSolution.repair()
129
                self.tryEval(newSolution)
130
                if newSolution.Fitness < self.Foods[i].Fitness:
131
                    self.checkForBest(newSolution)
132
                    self.Foods[i] = newSolution
133
                    self.Trial[i] = 0
134
                else:
135
                    self.Trial[i] += 1
136
137
            self.CalculateProbs()
138
            t, s = 0, 0
139
            while t < self.FoodNumber:
140
                if rnd.random() < self.Probs[s]:
141
                    t += 1
142
                    Solution = copy.deepcopy(self.Foods[s])
143
                    param2change = int(rnd.random() * self.D)
144
                    neighbor = int(self.FoodNumber * rnd.random())
145
                    while neighbor == s:
146
                        neighbor = int(self.FoodNumber * rnd.random())
147
                    Solution.Solution[param2change] = self.Foods[s].Solution[param2change] \
148
                        + (-1 + 2 * rnd.random()) * (
149
                            self.Foods[s].Solution[param2change] -
150
                            self.Foods[neighbor].Solution[param2change])
151
                    Solution.repair()
152
                    self.tryEval(Solution)
153
                    if Solution.Fitness < self.Foods[s].Fitness:
154
                        self.checkForBest(newSolution)
155
                        self.Foods[s] = Solution
156
                        self.Trial[s] = 0
157
                    else:
158
                        self.Trial[s] += 1
159
                s += 1
160
                if s == self.FoodNumber:
161
                    s = 0
162
163
            mi = self.Trial.index(max(self.Trial))
164
            if self.Trial[mi] >= self.Limit:
165
                self.Foods[mi] = SolutionABC(self.D, self.Lower, self.Upper)
166
                self.tryEval(self.Foods[mi])
167
                self.Trial[mi] = 0
168
        return self.Best.Fitness
169