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