Completed
Push — master ( fc4c38...3e2db1 )
by Grega
11s
created

ArtificialBeeColonyAlgorithm.__init__()   B

Complexity

Conditions 1

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
c 0
b 0
f 0
dl 0
loc 30
rs 8.8571
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
    # pylint: disable=too-many-instance-attributes
56
    def __init__(self, D, NP, nFES, benchmark):
57
        """**__init__(self, D, NP, nFES, benchmark)**.
58
59
        Arguments:
60
            D {integer} -- dimension of problem
61
62
            NP {integer} -- population size
63
64
            nFES {integer} -- number of function evaluations
65
66
            benchmark {object} -- benchmark implementation object
67
68
        Raises:
69
            TypeError -- Raised when given benchmark function which does not exists.
70
71
        """
72
73
        self.benchmark = Utility().get_benchmark(benchmark)
74
        self.D = D
75
        self.NP = NP
76
        self.FoodNumber = int(self.NP / 2)
77
        self.Limit = 100
78
        self.Trial = []
79
        self.Foods = []
80
        self.Probs = []
81
        self.nFES = nFES
82
        self.Lower = self.benchmark.Lower
83
        self.Upper = self.benchmark.Upper
84
        SolutionABC.FuncEval = staticmethod(self.benchmark.function())
85
        self.Best = SolutionABC(self.D, self.Lower, self.Upper)
86
87
    def init(self):
88
        self.Probs = [0 for i in range(self.FoodNumber)]
89
        self.Trial = [0 for i in range(self.FoodNumber)]
90
        for i in range(self.FoodNumber):
91
            self.Foods.append(SolutionABC(self.D, self.Lower, self.Upper))
92
            self.Foods[i].evaluate()
93
            self.checkForBest(self.Foods[i])
94
95
    def CalculateProbs(self):
96
        self.Probs = [1.0 / (self.Foods[i].Fitness + 0.01)
97
                      for i in range(self.FoodNumber)]
98
        s = sum(self.Probs)
99
        self.Probs = [self.Probs[i] / s for i in range(self.FoodNumber)]
100
101
    def checkForBest(self, Solution):
102
        if Solution.Fitness <= self.Best.Fitness:
103
            self.Best = copy.deepcopy(Solution)
104
105
    def run(self):
106
        self.init()
107
        FEs = self.FoodNumber
108
        while FEs < self.nFES:
109
            self.Best.toString()
110
            for i in range(self.FoodNumber):
111
                newSolution = copy.deepcopy(self.Foods[i])
112
                param2change = int(rnd.random() * self.D)
113
                neighbor = int(self.FoodNumber * rnd.random())
114
                newSolution.Solution[param2change] = self.Foods[i].Solution[param2change] \
115
                    + (-1 + 2 * rnd.random()) * \
116
                    (self.Foods[i].Solution[param2change] -
117
                     self.Foods[neighbor].Solution[param2change])
118
                newSolution.repair()
119
                newSolution.evaluate()
120
                if newSolution.Fitness < self.Foods[i].Fitness:
121
                    self.checkForBest(newSolution)
122
                    self.Foods[i] = newSolution
123
                    self.Trial[i] = 0
124
                else:
125
                    self.Trial[i] += 1
126
            FEs += self.FoodNumber
127
            self.CalculateProbs()
128
            t, s = 0, 0
129
            while t < self.FoodNumber:
130
                if rnd.random() < self.Probs[s]:
131
                    t += 1
132
                    Solution = copy.deepcopy(self.Foods[s])
133
                    param2change = int(rnd.random() * self.D)
134
                    neighbor = int(self.FoodNumber * rnd.random())
135
                    while neighbor == s:
136
                        neighbor = int(self.FoodNumber * rnd.random())
137
                    Solution.Solution[param2change] = self.Foods[s].Solution[param2change] \
138
                        + (-1 + 2 * rnd.random()) * (
139
                            self.Foods[s].Solution[param2change] -
140
                            self.Foods[neighbor].Solution[param2change])
141
                    Solution.repair()
142
                    Solution.evaluate()
143
                    FEs += 1
144
                    if Solution.Fitness < self.Foods[s].Fitness:
145
                        self.checkForBest(newSolution)
146
                        self.Foods[s] = Solution
147
                        self.Trial[s] = 0
148
                    else:
149
                        self.Trial[s] += 1
150
                s += 1
151
                if s == self.FoodNumber:
152
                    s = 0
153
154
            mi = self.Trial.index(max(self.Trial))
155
            if self.Trial[mi] >= self.Limit:
156
                self.Foods[mi] = SolutionABC(self.D, self.Lower, self.Upper)
157
                self.Foods[mi].evaluate()
158
                FEs += 1
159
                self.Trial[mi] = 0
160
        return self.Best.Fitness
161