1
|
|
|
# coding=utf-8 |
2
|
|
|
import logging |
3
|
|
|
from numpy import array, argsort, where |
4
|
|
|
from NiaPy.algorithms.algorithm import Algorithm |
5
|
|
|
|
6
|
|
|
__all__ = ['BeesAlgorithm'] |
7
|
|
|
|
8
|
|
|
logging.basicConfig() |
9
|
|
|
logger = logging.getLogger('NiaPy.algorithms.basic') |
10
|
|
|
logger.setLevel('INFO') |
11
|
|
|
|
12
|
|
|
|
13
|
|
|
class BeesAlgorithm(Algorithm): |
14
|
|
|
r"""Implementation of Bees algorithm. |
15
|
|
|
|
16
|
|
|
Algorithm: |
17
|
|
|
The Bees algorithm |
18
|
|
|
|
19
|
|
|
Date: |
20
|
|
|
2019 |
21
|
|
|
|
22
|
|
|
Authors: |
23
|
|
|
Rok Potočnik |
24
|
|
|
|
25
|
|
|
License: |
26
|
|
|
MIT |
27
|
|
|
|
28
|
|
|
Reference paper: |
29
|
|
|
DT Pham, A Ghanbarzadeh, E Koc, S Otri, S Rahim, and M Zaidi. The bees algorithm-a novel tool for complex optimisation problems. In Proceedings of the 2nd Virtual International Conference on Intelligent Production Machines and Systems (IPROMS 2006), pages 454–459, 2006 |
30
|
|
|
|
31
|
|
|
Attributes: |
32
|
|
|
NP (Optional[int]): Number of scout bees parameter. |
33
|
|
|
m (Optional[int]): Number of sites selected out of n visited sites parameter. |
34
|
|
|
e (Optional[int]): Number of best sites out of m selected sitest parameter. |
35
|
|
|
nep (Optional[int]): Number of bees recruited for best e sites parameter. |
36
|
|
|
nsp (Optional[int]): Number of bees recruited for the other selected sites parameter. |
37
|
|
|
ngh (Optional[float]): Initial size of patches parameter. |
38
|
|
|
ukwargs (Dict[str, Any]): Additional arguments. |
39
|
|
|
|
40
|
|
|
See Also: |
41
|
|
|
* :func:`NiaPy.algorithms.Algorithm.setParameters` |
42
|
|
|
|
43
|
|
|
""" |
44
|
|
|
Name = ['BeesAlgorithm', 'BEA'] |
45
|
|
|
|
46
|
|
|
@staticmethod |
47
|
|
|
def algorithmInfo(): |
48
|
|
|
r"""Get information about algorithm. |
49
|
|
|
|
50
|
|
|
Returns: |
51
|
|
|
str: Algorithm information |
52
|
|
|
|
53
|
|
|
See Also: |
54
|
|
|
* :func:`NiaPy.algorithms.Algorithm.algorithmInfo` |
55
|
|
|
""" |
56
|
|
|
return r"""DT Pham, A Ghanbarzadeh, E Koc, S Otri, S Rahim, and M Zaidi. The bees algorithm-a novel tool for complex optimisation problems. In Proceedings of the 2nd Virtual International Conference on Intelligent Production Machines and Systems (IPROMS 2006), pages 454–459, 2006""" |
57
|
|
|
|
58
|
|
View Code Duplication |
@staticmethod |
|
|
|
|
59
|
|
|
def typeParameters(): |
60
|
|
|
r"""Get dictionary with functions for checking values of parameters. |
61
|
|
|
|
62
|
|
|
Returns: |
63
|
|
|
Dict[str, Callable]: |
64
|
|
|
* NP (Callable[[int], bool]): Checks if number of bees parameter has a proper value. |
65
|
|
|
* m (Callable[[int], bool]): Checks if number of selected sites parameter has a proper value. |
66
|
|
|
* e (Callable[[int], bool]): Checks if number of elite selected sites parameter has a proper value. |
67
|
|
|
* nep (Callable[[int], bool]): Checks if number of elite bees parameter has a proper value. |
68
|
|
|
* nsp (Callable[[int], bool]): Checks if number of other bees parameter has a proper value. |
69
|
|
|
* ngh (Callable[[float], bool]): Checks if size of patches parameter has a proper value. |
70
|
|
|
|
71
|
|
|
See Also: |
72
|
|
|
* :func:`NiaPy.algorithms.algorithm.Algorithm.typeParameters` |
73
|
|
|
""" |
74
|
|
|
d = Algorithm.typeParameters() |
75
|
|
|
d.update({ |
76
|
|
|
'NP': lambda x: isinstance(x, int) and x > 0, |
77
|
|
|
'm': lambda x: isinstance(x, int) and x > 0, |
78
|
|
|
'e': lambda x: isinstance(x, int) and x > 0, |
79
|
|
|
'nep': lambda x: isinstance(x, int) and x > 0, |
80
|
|
|
'nsp': lambda x: isinstance(x, int) and x > 0, |
81
|
|
|
'ngh': lambda x: isinstance(x, float) and x > 0 |
82
|
|
|
}) |
83
|
|
|
return d |
84
|
|
|
|
85
|
|
|
def setParameters(self, NP=40, m=5, e=4, ngh=1, nep=4, nsp=2, **ukwargs): |
86
|
|
|
r"""Set the parameters of the algorithm. |
87
|
|
|
|
88
|
|
|
Args: |
89
|
|
|
NP (Optional[int]): Number of scout bees parameter. |
90
|
|
|
m (Optional[int]): Number of sites selected out of n visited sites parameter. |
91
|
|
|
e (Optional[int]): Number of best sites out of m selected sitest parameter. |
92
|
|
|
nep (Optional[int]): Number of bees recruited for best e sites parameter. |
93
|
|
|
nsp (Optional[int]): Number of bees recruited for the other selected sites parameter. |
94
|
|
|
ngh (Optional[float]): Initial size of patches parameter. |
95
|
|
|
ukwargs (Dict[str, Any]): Additional arguments. |
96
|
|
|
|
97
|
|
|
See Also: |
98
|
|
|
* :func:`NiaPy.algorithms.Algorithm.setParameters` |
99
|
|
|
""" |
100
|
|
|
Algorithm.setParameters(self, NP=NP, **ukwargs) |
101
|
|
|
self.n, self.m, self.e, self.nep, self.nsp, self.ngh = NP, m, e, nep, nsp, ngh |
102
|
|
|
|
103
|
|
|
def getParameters(self): |
104
|
|
|
r"""Get parameters of the algorithm. |
105
|
|
|
|
106
|
|
|
Returns: |
107
|
|
|
Dict[str, Any]: |
108
|
|
|
""" |
109
|
|
|
d = Algorithm.getParameters(self) |
110
|
|
|
d.update({ |
111
|
|
|
'm': self.m, |
112
|
|
|
'e': self.e, |
113
|
|
|
'ngh': self.ngh, |
114
|
|
|
'nep': self.nep, |
115
|
|
|
'nsp': self.nsp |
116
|
|
|
}) |
117
|
|
|
return d |
118
|
|
|
|
119
|
|
|
def beeDance(self, x, task, ngh): |
120
|
|
|
r"""Bees Dance. Search for new positions. |
121
|
|
|
|
122
|
|
|
Args: |
123
|
|
|
x (numpy.ndarray): One instance from the population. |
124
|
|
|
task (Task): Optimization task. |
125
|
|
|
ngh (float): A small value for patch search. |
126
|
|
|
|
127
|
|
|
Returns: |
128
|
|
|
Tuple[numpy.ndarray, float]: |
129
|
|
|
1. New population. |
130
|
|
|
2. New population fitness/function values. |
131
|
|
|
|
132
|
|
|
See Also: |
133
|
|
|
* :func:`NiaPy.algorithms.Algorithm.initPopulation` |
134
|
|
|
""" |
135
|
|
|
ind = self.randint(task.D) |
136
|
|
|
y = array(x, copy=True) |
137
|
|
|
y[ind] = x[ind] + self.uniform(-ngh, ngh) |
138
|
|
|
y = self.repair(y, task.Lower, task.Upper) |
139
|
|
|
res = task.eval(y) |
140
|
|
|
return y, res |
141
|
|
|
|
142
|
|
|
def initPopulation(self, task): |
143
|
|
|
r"""Initialize the starting population. |
144
|
|
|
|
145
|
|
|
Args: |
146
|
|
|
task (Task): Optimization task |
147
|
|
|
|
148
|
|
|
Returns: |
149
|
|
|
Tuple[numpy.ndarray, numpy.ndarray, Dict[str, Any]]: |
150
|
|
|
1. New population. |
151
|
|
|
2. New population fitness/function values. |
152
|
|
|
|
153
|
|
|
See Also: |
154
|
|
|
* :func:`NiaPy.algorithms.Algorithm.initPopulation` |
155
|
|
|
""" |
156
|
|
|
BeesPosition, BeesCost, _ = Algorithm.initPopulation(self, task) |
157
|
|
|
|
158
|
|
|
idxs = argsort(BeesCost) |
159
|
|
|
BeesCost = BeesCost[idxs] |
160
|
|
|
BeesPosition = BeesPosition[idxs, :] |
161
|
|
|
|
162
|
|
|
return BeesPosition, BeesCost, {'ngh': self.ngh} |
163
|
|
|
|
164
|
|
View Code Duplication |
def repair(self, x, lower, upper): |
|
|
|
|
165
|
|
|
r"""Truncate exceeded dimensions to the limits. |
166
|
|
|
|
167
|
|
|
Args: |
168
|
|
|
x (numpy.ndarray): Individual to repair. |
169
|
|
|
lower (numpy.ndarray): Lower limits for dimensions. |
170
|
|
|
upper (numpy.ndarray): Upper limits for dimensions. |
171
|
|
|
|
172
|
|
|
Returns: |
173
|
|
|
numpy.ndarray: Repaired individual. |
174
|
|
|
""" |
175
|
|
|
ir = where(x < lower) |
176
|
|
|
x[ir] = lower[ir] |
177
|
|
|
ir = where(x > upper) |
178
|
|
|
x[ir] = upper[ir] |
179
|
|
|
return x |
180
|
|
|
|
181
|
|
|
def runIteration(self, task, BeesPosition, BeesCost, xb, fxb, ngh, **dparams): |
182
|
|
|
r"""Core function of Forest Optimization Algorithm. |
183
|
|
|
|
184
|
|
|
Args: |
185
|
|
|
task (Task): Optimization task. |
186
|
|
|
BeesPosition (numpy.ndarray[float]): Current population. |
187
|
|
|
BeesCost (numpy.ndarray[float]): Current population function/fitness values. |
188
|
|
|
xb (numpy.ndarray): Global best individual. |
189
|
|
|
fxb (float): Global best individual fitness/function value. |
190
|
|
|
ngh (float): A small value used for patches. |
191
|
|
|
**dparams (Dict[str, Any]): Additional arguments. |
192
|
|
|
|
193
|
|
|
Returns: |
194
|
|
|
Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, float, Dict[str, Any]]: |
195
|
|
|
1. New population. |
196
|
|
|
2. New population fitness/function values. |
197
|
|
|
3. New global best solution. |
198
|
|
|
4. New global best fitness/objective value. |
199
|
|
|
5. Additional arguments: |
200
|
|
|
* ngh (float): A small value used for patches. |
201
|
|
|
""" |
202
|
|
|
for ies in range(self.e): |
203
|
|
|
BestBeeCost = float('inf') |
204
|
|
|
for ieb in range(self.nep): |
205
|
|
|
NewBeePos, NewBeeCost = self.beeDance(BeesPosition[ies, :], task, ngh) |
206
|
|
|
if NewBeeCost < BestBeeCost: |
207
|
|
|
BestBeeCost = NewBeeCost |
208
|
|
|
BestBeePos = NewBeePos |
209
|
|
|
if BestBeeCost < BeesCost[ies]: |
210
|
|
|
BeesPosition[ies, :] = BestBeePos |
|
|
|
|
211
|
|
|
BeesCost[ies] = BestBeeCost |
212
|
|
|
for ies in range(self.e, self.m): |
213
|
|
|
BestBeeCost = float('inf') |
214
|
|
|
for ieb in range(self.nsp): |
215
|
|
|
NewBeePos, NewBeeCost = self.beeDance(BeesPosition[ies, :], task, ngh) |
216
|
|
|
if NewBeeCost < BestBeeCost: |
217
|
|
|
BestBeeCost = NewBeeCost |
218
|
|
|
BestBeePos = NewBeePos |
219
|
|
|
if BestBeeCost < BeesCost[ies]: |
220
|
|
|
BeesPosition[ies, :] = BestBeePos |
221
|
|
|
BeesCost[ies] = BestBeeCost |
222
|
|
|
for ies in range(self.m, self.n): |
223
|
|
|
BeesPosition[ies, :] = array(self.uniform(task.Lower, task.Upper, task.D)) |
224
|
|
|
BeesCost[ies] = task.eval(BeesPosition[ies, :]) |
225
|
|
|
idxs = argsort(BeesCost) |
226
|
|
|
BeesCost = BeesCost[idxs] |
227
|
|
|
BeesPosition = BeesPosition[idxs, :] |
228
|
|
|
ngh = ngh * 0.95 |
229
|
|
|
return BeesPosition, BeesCost, BeesPosition[0].copy(), BeesCost[0], {'ngh': ngh} |
230
|
|
|
|
231
|
|
|
# vim: tabstop=3 noexpandtab shiftwidth=3 softtabstop=3 |
232
|
|
|
|