1
|
|
|
# encoding=utf8 |
2
|
|
|
# pylint: disable=mixed-indentation, trailing-whitespace, multiple-statements, attribute-defined-outside-init, logging-not-lazy, arguments-differ, line-too-long, redefined-builtin, singleton-comparison, no-self-use, bad-continuation |
3
|
|
|
import logging |
4
|
|
|
from scipy.spatial.distance import euclidean as ed |
5
|
|
|
from numpy import apply_along_axis, argmin, argmax, sum, full, inf, asarray, mean, where, sqrt |
6
|
|
|
from NiaPy.util import fullArray |
7
|
|
|
from NiaPy.algorithms.algorithm import Algorithm |
8
|
|
|
|
9
|
|
|
logging.basicConfig() |
10
|
|
|
logger = logging.getLogger('NiaPy.algorithms.basic') |
11
|
|
|
logger.setLevel('INFO') |
12
|
|
|
|
13
|
|
|
__all__ = ['KrillHerdV1', 'KrillHerdV2', 'KrillHerdV3', 'KrillHerdV4', 'KrillHerdV11'] |
14
|
|
|
|
15
|
|
|
class KrillHerd(Algorithm): |
16
|
|
|
r"""Implementation of krill herd algorithm. |
17
|
|
|
|
18
|
|
|
Algorithm: |
19
|
|
|
Krill Herd Algorithm |
20
|
|
|
|
21
|
|
|
Date: |
22
|
|
|
2018 |
23
|
|
|
|
24
|
|
|
Authors: |
25
|
|
|
Klemen Berkovič |
26
|
|
|
|
27
|
|
|
License: |
28
|
|
|
MIT |
29
|
|
|
|
30
|
|
|
Reference URL: |
31
|
|
|
http://www.sciencedirect.com/science/article/pii/S1007570412002171 |
32
|
|
|
|
33
|
|
|
Reference paper: |
34
|
|
|
Amir Hossein Gandomi, Amir Hossein Alavi, Krill herd: A new bio-inspired optimization algorithm, Communications in Nonlinear Science and Numerical Simulation, Volume 17, Issue 12, 2012, Pages 4831-4845, ISSN 1007-5704, https://doi.org/10.1016/j.cnsns.2012.05.010. |
35
|
|
|
|
36
|
|
|
Attributes: |
37
|
|
|
Name (List[str]): List of strings representing algorithm names.. |
38
|
|
|
NP (int): Number of krill herds in population. |
39
|
|
|
N_max (float): Maximum induced speed. |
40
|
|
|
V_f (float): Foraging speed. |
41
|
|
|
D_max (float): Maximum diffusion speed. |
42
|
|
|
C_t (float): Constant :math:`\in [0, 2]` |
43
|
|
|
W_n (Union[int, float, numpy.ndarray]): Interta weights of the motion induced from neighbors :math:`\in [0, 1]`. |
44
|
|
|
W_f (Union[int, float, numpy.ndarray]): Interta weights of the motion induced from foraging :math`\in [0, 1]`. |
45
|
|
|
d_s (float): Maximum euclidean distance for neighbors. |
46
|
|
|
nn (int): Maximum neighbors for neighbors effect. |
47
|
|
|
Cr (float): Crossover probability. |
48
|
|
|
Mu (float): Mutation probability. |
49
|
|
|
epsilon (float): Small numbers for division. |
50
|
|
|
|
51
|
|
|
See Also: |
52
|
|
|
* :class:`NiaPy.algorithms.algorithm.Algorithm` |
53
|
|
|
""" |
54
|
|
|
Name = ['KrillHerd', 'KH'] |
55
|
|
|
|
56
|
|
|
@staticmethod |
57
|
|
|
def typeParameters(): |
58
|
|
|
r"""Get dictionary with functions for checking values of parameters. |
59
|
|
|
|
60
|
|
|
Returns: |
61
|
|
|
Dict[str, Callable]: |
62
|
|
|
* N_max (Callable[[Union[int, float]], bool]): TODO |
63
|
|
|
* V_f (Callable[[Union[int, float]], bool]): TODO |
64
|
|
|
* D_max (Callable[[Union[int, float]], bool]): TODO |
65
|
|
|
* C_t (Callable[[Union[int, float]], bool]): TODO |
66
|
|
|
* W_n (Callable[[Union[int, float]], bool]): TODO |
67
|
|
|
* W_f (Callable[[Union[int, float]], bool]): TODO |
68
|
|
|
* d_s (Callable[[Union[int, float]], boool]): TODO |
69
|
|
|
* nn (Callable[[int], bool]): TODO |
70
|
|
|
* Cr (Callable[[float], bool]): TODO |
71
|
|
|
* Mu (Callable[[float], bool]): TODO |
72
|
|
|
* epsilon (Callable[[float], bool]): TODO |
73
|
|
|
|
74
|
|
|
See Also: |
75
|
|
|
* :func:`NiaPy.algorithms.algorithm.Algorithm` |
76
|
|
|
""" |
77
|
|
|
d = Algorithm.typeParameters() |
78
|
|
|
d.update({ |
79
|
|
|
'N_max': lambda x: isinstance(x, (int, float)) and x > 0, |
80
|
|
|
'V_f': lambda x: isinstance(x, (int, float)) and x > 0, |
81
|
|
|
'D_max': lambda x: isinstance(x, (int, float)) and x > 0, |
82
|
|
|
'C_t': lambda x: isinstance(x, (int, float)) and x > 0, |
83
|
|
|
'W_n': lambda x: isinstance(x, (int, float)) and x > 0, |
84
|
|
|
'W_f': lambda x: isinstance(x, (int, float)) and x > 0, |
85
|
|
|
'd_s': lambda x: isinstance(x, (int, float)) and x > 0, |
86
|
|
|
'nn': lambda x: isinstance(x, int) and x > 0, |
87
|
|
|
'Cr': lambda x: isinstance(x, float) and 0 <= x <= 1, |
88
|
|
|
'Mu': lambda x: isinstance(x, float) and 0 <= x <= 1, |
89
|
|
|
'epsilon': lambda x: isinstance(x, float) and 0 < x < 1 |
90
|
|
|
}) |
91
|
|
|
return d |
92
|
|
|
|
93
|
|
|
def setParameters(self, NP=50, N_max=0.01, V_f=0.02, D_max=0.002, C_t=0.93, W_n=0.42, W_f=0.38, d_s=2.63, nn=5, Cr=0.2, Mu=0.05, epsilon=1e-31, **ukwargs): |
94
|
|
|
r"""Set the arguments of an algorithm. |
95
|
|
|
|
96
|
|
|
Arguments: |
97
|
|
|
NP (Optional[int]): Number of krill herds in population. |
98
|
|
|
N_max (Optional[float]): Maximum induced speed. |
99
|
|
|
V_f (Optional[float]): Foraging speed. |
100
|
|
|
D_max (Optional[float]): Maximum diffusion speed. |
101
|
|
|
C_t (Optional[float]): Constant $\in [0, 2]$. |
102
|
|
|
W_n (Optional[Union[int, float, numpy.ndarray]]): Intera weights of the motion induced from neighbors :math:`\in [0, 1]`. |
103
|
|
|
W_f (Optional[Union[int, float, numpy.ndarray]]): Intera weights of the motion induced from foraging :math:`\in [0, 1]`. |
104
|
|
|
d_s (Optional[float]): Maximum euclidean distance for neighbors. |
105
|
|
|
nn (Optional[int]): Maximum neighbors for neighbors effect. |
106
|
|
|
Cr (Optional[float]): Crossover probability. |
107
|
|
|
Mu (Optional[float]): Mutation probability. |
108
|
|
|
epsilon (Optional[float]): Small numbers for division. |
109
|
|
|
|
110
|
|
|
See Also: |
111
|
|
|
* :func:`NiaPy.algorithms.algorithm.Algorithm.setParameters` |
112
|
|
|
""" |
113
|
|
|
Algorithm.setParameters(self, NP=NP, **ukwargs) |
114
|
|
|
self.N_max, self.V_f, self.D_max, self.C_t, self.W_n, self.W_f, self.d_s, self.nn, self._Cr, self._Mu, self.epsilon = N_max, V_f, D_max, C_t, W_n, W_f, d_s, nn, Cr, Mu, epsilon |
115
|
|
|
if ukwargs: logger.info('Unused arguments: %s' % (ukwargs)) |
116
|
|
|
|
117
|
|
|
def initWeights(self, task): |
118
|
|
|
r"""Initialize weights. |
119
|
|
|
|
120
|
|
|
Args: |
121
|
|
|
task (Task): Optimization task. |
122
|
|
|
|
123
|
|
|
Returns: |
124
|
|
|
Tuple[numpy.ndarray, numpy.ndarray]: |
125
|
|
|
1. Weights for neighborhood. |
126
|
|
|
2. Weights for foraging. |
127
|
|
|
""" |
128
|
|
|
return fullArray(self.W_n, task.D), fullArray(self.W_f, task.D) |
129
|
|
|
|
130
|
|
|
def sensRange(self, ki, KH): |
131
|
|
|
r"""Calculate sense range for selected individual. |
132
|
|
|
|
133
|
|
|
Args: |
134
|
|
|
ki (int): Selected individual. |
135
|
|
|
KH (numpy.ndarray): Krill heard population. |
136
|
|
|
|
137
|
|
|
Returns: |
138
|
|
|
TODO |
139
|
|
|
""" |
140
|
|
|
return sum([ed(KH[ki], KH[i]) for i in range(self.NP)]) / (self.nn * self.NP) |
141
|
|
|
|
142
|
|
|
def getNeighbours(self, i, ids, KH): |
143
|
|
|
r"""Get neighbours. |
144
|
|
|
|
145
|
|
|
Args: |
146
|
|
|
i (int): Individual looking for neighbours. |
147
|
|
|
ids (float): Maximal distance for being a neighbour. |
148
|
|
|
KH (numpy.ndarray): Current population. |
149
|
|
|
|
150
|
|
|
Returns: |
151
|
|
|
numpy.ndarray: Neighbours of krill heard. |
152
|
|
|
""" |
153
|
|
|
N = list() |
154
|
|
|
for j in range(self.NP): |
155
|
|
|
if j != i and ids > ed(KH[i], KH[j]): N.append(j) |
156
|
|
|
if not N: N.append(self.randint(self.NP)) |
157
|
|
|
return asarray(N) |
158
|
|
|
|
159
|
|
|
def funX(self, x, y): return ((y - x) + self.epsilon) / (ed(y, x) + self.epsilon) |
160
|
|
|
|
161
|
|
|
def funK(self, x, y, b, w): return ((x - y) + self.epsilon) / ((w - b) + self.epsilon) |
162
|
|
|
|
163
|
|
|
def induceNeighborsMotion(self, i, n, W, KH, KH_f, ikh_b, ikh_w, task): |
164
|
|
|
Ni = self.getNeighbours(i, self.sensRange(i, KH), KH) |
165
|
|
|
Nx, Nf, f_b, f_w = KH[Ni], KH_f[Ni], KH_f[ikh_b], KH_f[ikh_w] |
166
|
|
|
alpha_l = sum(asarray([self.funK(KH_f[i], j, f_b, f_w) for j in Nf]) * asarray([self.funX(KH[i], j) for j in Nx]).T) |
167
|
|
|
alpha_t = 2 * (1 + self.rand() * task.Iters / task.nGEN) |
168
|
|
|
return self.N_max * (alpha_l + alpha_t) + W * n |
169
|
|
|
|
170
|
|
|
def induceForagingMotion(self, i, x, x_f, f, W, KH, KH_f, ikh_b, ikh_w, task): |
171
|
|
|
beta_f = 2 * (1 - task.Iters / task.nGEN) * self.funK(KH_f[i], x_f, KH_f[ikh_b], KH_f[ikh_w]) * self.funX(KH[i], x) if KH_f[ikh_b] < KH_f[i] else 0 |
172
|
|
|
beta_b = self.funK(KH_f[i], KH_f[ikh_b], KH_f[ikh_b], KH_f[ikh_w]) * self.funX(KH[i], KH[ikh_b]) |
173
|
|
|
return self.V_f * (beta_f + beta_b) + W * f |
174
|
|
|
|
175
|
|
|
def inducePhysicalDiffusion(self, task): return self.D_max * (1 - task.Iters / task.nGEN) * self.uniform(-1, 1, task.D) |
176
|
|
|
|
177
|
|
|
def deltaT(self, task): return self.C_t * sum(task.bcRange()) |
178
|
|
|
|
179
|
|
|
def crossover(self, x, xo, Cr): return [xo[i] if self.rand() < Cr else x[i] for i in range(len(x))] |
180
|
|
|
|
181
|
|
|
def mutate(self, x, x_b, Mu): |
182
|
|
|
return [x[i] if self.rand() < Mu else (x_b[i] + self.rand()) for i in range(len(x))] |
183
|
|
|
|
184
|
|
|
def getFoodLocation(self, KH, KH_f, task): |
185
|
|
|
x_food = task.repair(asarray([sum(KH[:, i] / KH_f) for i in range(task.D)]) / sum(1 / KH_f), rnd=self.Rand) |
186
|
|
|
x_food_f = task.eval(x_food) |
187
|
|
|
return x_food, x_food_f |
188
|
|
|
|
189
|
|
|
def Mu(self, xf, yf, xf_best, xf_worst): return self._Mu / (self.funK(xf, yf, xf_best, xf_worst) + 1e-31) |
190
|
|
|
|
191
|
|
|
def Cr(self, xf, yf, xf_best, xf_worst): return self._Cr * self.funK(xf, yf, xf_best, xf_worst) |
192
|
|
|
|
193
|
|
|
def initPopulation(self, task): |
194
|
|
|
r"""Initialize stating population. |
195
|
|
|
|
196
|
|
|
Args: |
197
|
|
|
task (Task): Optimization task. |
198
|
|
|
|
199
|
|
|
Returns: |
200
|
|
|
Tuple[numpy.ndarray, numpy.ndarray[float], Dict[str, Any]]: |
201
|
|
|
1. Initialized population. |
202
|
|
|
2. Initialized populations function/fitness values. |
203
|
|
|
3. Additional arguments: |
204
|
|
|
* W_n (numpy.ndarray): Weights neighborhood. |
205
|
|
|
* W_f (numpy.ndarray): Weights foraging. |
206
|
|
|
* N (numpy.ndarray): TODO |
207
|
|
|
* F (numpy.ndarray): TODO |
208
|
|
|
|
209
|
|
|
See Also: |
210
|
|
|
* :func:`NiaPy.algorithms.algorithm.Algorithm.initPopulation` |
211
|
|
|
""" |
212
|
|
|
KH, KH_f, d = Algorithm.initPopulation(self, task) |
213
|
|
|
W_n, W_f = self.initWeights(task) |
214
|
|
|
N, F = full(self.NP, .0), full(self.NP, .0) |
215
|
|
|
d.update({'W_n': W_n, 'W_f': W_f, 'N': N, 'F': F}) |
216
|
|
|
return KH, KH_f, d |
217
|
|
|
|
218
|
|
|
def runIteration(self, task, KH, KH_f, xb, fxb, W_n, W_f, N, F, **dparams): |
219
|
|
|
ikh_b, ikh_w = argmin(KH_f), argmax(KH_f) |
220
|
|
|
x_food, x_food_f = self.getFoodLocation(KH, KH_f, task) |
221
|
|
|
N = asarray([self.induceNeighborsMotion(i, N[i], W_n, KH, KH_f, ikh_b, ikh_w, task) for i in range(self.NP)]) |
222
|
|
|
F = asarray([self.induceForagingMotion(i, x_food, x_food_f, F[i], W_f, KH, KH_f, ikh_b, ikh_w, task) for i in range(self.NP)]) |
223
|
|
|
D = asarray([self.inducePhysicalDiffusion(task) for i in range(self.NP)]) |
224
|
|
|
KH_n = KH + (self.deltaT(task) * (N + F + D)) |
225
|
|
|
Cr = asarray([self.Cr(KH_f[i], KH_f[ikh_b], KH_f[ikh_b], KH_f[ikh_w]) for i in range(self.NP)]) |
226
|
|
|
KH_n = asarray([self.crossover(KH_n[i], KH[i], Cr[i]) for i in range(self.NP)]) |
227
|
|
|
Mu = asarray([self.Mu(KH_f[i], KH_f[ikh_b], KH_f[ikh_b], KH_f[ikh_w]) for i in range(self.NP)]) |
228
|
|
|
KH_n = asarray([self.mutate(KH_n[i], KH[ikh_b], Mu[i]) for i in range(self.NP)]) |
229
|
|
|
KH = apply_along_axis(task.repair, 1, KH_n, rnd=self.Rand) |
230
|
|
|
KH_f = apply_along_axis(task.eval, 1, KH) |
231
|
|
|
return KH, KH_f, {'W_n': W_n, 'W_f': W_f, 'N': N, 'F': F} |
232
|
|
|
|
233
|
|
|
class KrillHerdV4(KrillHerd): |
234
|
|
|
r"""Implementation of krill herd algorithm. |
235
|
|
|
|
236
|
|
|
Algorithm: |
237
|
|
|
Krill Herd Algorithm |
238
|
|
|
|
239
|
|
|
Date: |
240
|
|
|
2018 |
241
|
|
|
|
242
|
|
|
Authors: |
243
|
|
|
Klemen Berkovič |
244
|
|
|
|
245
|
|
|
License: |
246
|
|
|
MIT |
247
|
|
|
|
248
|
|
|
Reference URL: |
249
|
|
|
http://www.sciencedirect.com/science/article/pii/S1007570412002171 |
250
|
|
|
|
251
|
|
|
Reference paper: |
252
|
|
|
Amir Hossein Gandomi, Amir Hossein Alavi, Krill herd: A new bio-inspired optimization algorithm, Communications in Nonlinear Science and Numerical Simulation, Volume 17, Issue 12, 2012, Pages 4831-4845, ISSN 1007-5704, https://doi.org/10.1016/j.cnsns.2012.05.010. |
253
|
|
|
|
254
|
|
|
Attributes: |
255
|
|
|
Name (List[str]): List of strings representing algorithm name. |
256
|
|
|
""" |
257
|
|
|
Name = ['KrillHerdV4', 'KHv4'] |
258
|
|
|
|
259
|
|
|
@staticmethod |
260
|
|
|
def typeParameters(): |
261
|
|
|
r"""Get dictionary with functions for checking values of parameters. |
262
|
|
|
|
263
|
|
|
Returns: |
264
|
|
|
Dict[str, Callable]: |
265
|
|
|
* TODO |
266
|
|
|
|
267
|
|
|
See Also: |
268
|
|
|
* :func:NiaPy.algorithms.basic.kh.KrillHerd.typeParameters` |
269
|
|
|
""" |
270
|
|
|
d = KrillHerd.typeParameters() |
271
|
|
|
del d['Cr'] |
272
|
|
|
del d['Mu'] |
273
|
|
|
del d['epsilon'] |
274
|
|
|
return d |
275
|
|
|
|
276
|
|
|
def setParameters(self, NP=50, N_max=0.01, V_f=0.02, D_max=0.002, C_t=0.93, W_n=0.42, W_f=0.38, d_s=2.63, **ukwargs): |
277
|
|
|
r"""Set algorithm core parameters. |
278
|
|
|
|
279
|
|
|
Args: |
280
|
|
|
N_max (Optional[float]): TODO |
281
|
|
|
V_f (Optional[float]): TODO |
282
|
|
|
D_max (Optional[float]): TODO |
283
|
|
|
C_t (Optional[float]): TODO |
284
|
|
|
W_n (Optional]float]): TODO |
285
|
|
|
W_f (Optional[float]): TODO |
286
|
|
|
d_s (Optional[float]): TODO |
287
|
|
|
**ukwargs (Dict[str, Any]): Additional arguments. |
288
|
|
|
|
289
|
|
|
See Also: |
290
|
|
|
* :func:NiaPy.algorithms.basic.kh.KrillHerd.KrillHerd.setParameters` |
291
|
|
|
""" |
292
|
|
|
KrillHerd.setParameters(self, NP, N_max, V_f, D_max, C_t, W_n, W_f, d_s, 4, 0.2, 0.05, 1e-31, **ukwargs) |
293
|
|
|
|
294
|
|
|
class KrillHerdV1(KrillHerd): |
295
|
|
|
r"""Implementation of krill herd algorithm. |
296
|
|
|
|
297
|
|
|
Algorithm: |
298
|
|
|
Krill Herd Algorithm |
299
|
|
|
|
300
|
|
|
Date: |
301
|
|
|
2018 |
302
|
|
|
|
303
|
|
|
Authors: |
304
|
|
|
Klemen Berkovič |
305
|
|
|
|
306
|
|
|
License: |
307
|
|
|
MIT |
308
|
|
|
|
309
|
|
|
Reference URL: |
310
|
|
|
http://www.sciencedirect.com/science/article/pii/S1007570412002171 |
311
|
|
|
|
312
|
|
|
Reference paper: |
313
|
|
|
Amir Hossein Gandomi, Amir Hossein Alavi, Krill herd: A new bio-inspired optimization algorithm, Communications in Nonlinear Science and Numerical Simulation, Volume 17, Issue 12, 2012, Pages 4831-4845, ISSN 1007-5704, https://doi.org/10.1016/j.cnsns.2012.05.010. |
314
|
|
|
|
315
|
|
|
Attributes: |
316
|
|
|
Name (List[str]): List of strings representing algorithm name. |
317
|
|
|
|
318
|
|
|
See Also: |
319
|
|
|
* :func:NiaPy.algorithms.basic.kh.KrillHerd.KrillHerd` |
320
|
|
|
""" |
321
|
|
|
Name = ['KrillHerdV1', 'KHv1'] |
322
|
|
|
|
323
|
|
|
@staticmethod |
324
|
|
|
def typeParameters(): |
325
|
|
|
r"""Get dictionary with functions for checking values of parameters. |
326
|
|
|
|
327
|
|
|
Returns: |
328
|
|
|
Dict[str, Callable]: |
329
|
|
|
* TODO |
330
|
|
|
|
331
|
|
|
See Also: |
332
|
|
|
* :func:NiaPy.algorithms.basic.kh.KrillHerd.typeParameters` |
333
|
|
|
""" |
334
|
|
|
return KrillHerd.typeParameters() |
335
|
|
|
|
336
|
|
|
def crossover(self, x, xo, Cr): |
337
|
|
|
r"""Preform a crossover operation on individual. |
338
|
|
|
|
339
|
|
|
Args: |
340
|
|
|
x (numpy.ndarray): Current individual |
341
|
|
|
xo (numpy.ndarray): New individual |
342
|
|
|
Cr (float): Crossover probability |
343
|
|
|
|
344
|
|
|
Returns: |
345
|
|
|
numpy.ndarray: Crossoved individual |
346
|
|
|
""" |
347
|
|
|
return x |
348
|
|
|
|
349
|
|
|
def mutate(self, x, x_b, Mu): |
350
|
|
|
r"""Mutate individual. |
351
|
|
|
|
352
|
|
|
Args: |
353
|
|
|
x (numpy.ndarray): Current individual. |
354
|
|
|
x_b (numpy.ndarray): Global best individual. |
355
|
|
|
Mu (float): TODO |
356
|
|
|
|
357
|
|
|
Returns: |
358
|
|
|
numpy.ndarray: TODO |
359
|
|
|
""" |
360
|
|
|
return x |
361
|
|
|
|
362
|
|
|
class KrillHerdV2(KrillHerd): |
363
|
|
|
r"""Implementation of krill herd algorithm. |
364
|
|
|
|
365
|
|
|
Algorithm: |
366
|
|
|
Krill Herd Algorithm |
367
|
|
|
|
368
|
|
|
Date: |
369
|
|
|
2018 |
370
|
|
|
|
371
|
|
|
Authors: |
372
|
|
|
Klemen Berkovič |
373
|
|
|
|
374
|
|
|
License: |
375
|
|
|
MIT |
376
|
|
|
|
377
|
|
|
Reference URL: |
378
|
|
|
http://www.sciencedirect.com/science/article/pii/S1007570412002171 |
379
|
|
|
|
380
|
|
|
Reference paper: |
381
|
|
|
Amir Hossein Gandomi, Amir Hossein Alavi, Krill herd: A new bio-inspired optimization algorithm, Communications in Nonlinear Science and Numerical Simulation, Volume 17, Issue 12, 2012, Pages 4831-4845, ISSN 1007-5704, https://doi.org/10.1016/j.cnsns.2012.05.010. |
382
|
|
|
|
383
|
|
|
Attributes: |
384
|
|
|
Name (List[str]): List of strings representing algorithm name. |
385
|
|
|
""" |
386
|
|
|
Name = ['KrillHerdV2', 'KHv2'] |
387
|
|
|
|
388
|
|
|
@staticmethod |
389
|
|
|
def typeParameters(): |
390
|
|
|
r"""Get dictionary with functions for checking values of parameters. |
391
|
|
|
|
392
|
|
|
Returns: |
393
|
|
|
Dict[str, Callable]: |
394
|
|
|
* TODO |
395
|
|
|
|
396
|
|
|
See Also: |
397
|
|
|
* :func:NiaPy.algorithms.basic.kh.KrillHerd.typeParameters` |
398
|
|
|
""" |
399
|
|
|
d = KrillHerd.typeParameters() |
400
|
|
|
del d['Mu'] |
401
|
|
|
return d |
402
|
|
|
|
403
|
|
|
def mutate(self, x, x_b, Mu): return x |
404
|
|
|
|
405
|
|
|
class KrillHerdV3(KrillHerd): |
406
|
|
|
r"""Implementation of krill herd algorithm. |
407
|
|
|
|
408
|
|
|
Algorithm: |
409
|
|
|
Krill Herd Algorithm |
410
|
|
|
|
411
|
|
|
Date: |
412
|
|
|
2018 |
413
|
|
|
|
414
|
|
|
Authors: |
415
|
|
|
Klemen Berkovič |
416
|
|
|
|
417
|
|
|
License: |
418
|
|
|
MIT |
419
|
|
|
|
420
|
|
|
Reference URL: |
421
|
|
|
http://www.sciencedirect.com/science/article/pii/S1007570412002171 |
422
|
|
|
|
423
|
|
|
Reference paper: |
424
|
|
|
Amir Hossein Gandomi, Amir Hossein Alavi, Krill herd: A new bio-inspired optimization algorithm, Communications in Nonlinear Science and Numerical Simulation, Volume 17, Issue 12, 2012, Pages 4831-4845, ISSN 1007-5704, https://doi.org/10.1016/j.cnsns.2012.05.010. |
425
|
|
|
""" |
426
|
|
|
Name = ['KrillHerdV3', 'KHv3'] |
427
|
|
|
|
428
|
|
|
@staticmethod |
429
|
|
|
def typeParameters(): |
430
|
|
|
d = KrillHerd.typeParameters() |
431
|
|
|
del d['Cr'] |
432
|
|
|
return d |
433
|
|
|
|
434
|
|
|
def crossover(self, x, xo, Cr): return x |
435
|
|
|
|
436
|
|
|
class KrillHerdV11(KrillHerd): |
437
|
|
|
r"""Implementation of krill herd algorithm. |
438
|
|
|
|
439
|
|
|
Algorithm: |
440
|
|
|
Krill Herd Algorithm |
441
|
|
|
|
442
|
|
|
Date: |
443
|
|
|
2018 |
444
|
|
|
|
445
|
|
|
Authors: |
446
|
|
|
Klemen Berkovič |
447
|
|
|
|
448
|
|
|
License: |
449
|
|
|
MIT |
450
|
|
|
|
451
|
|
|
Reference URL: |
452
|
|
|
|
453
|
|
|
Reference paper: |
454
|
|
|
""" |
455
|
|
|
Name = ['KrillHerdV11', 'KHv11'] |
456
|
|
|
|
457
|
|
|
def ElitistSelection(self, KH, KH_f, KHo, KHo_f): |
458
|
|
|
ipb = where(KHo_f >= KH_f) |
459
|
|
|
KHo[ipb], KHo_f[ipb] = KH[ipb], KH_f[ipb] |
460
|
|
|
return KHo, KHo_f |
461
|
|
|
|
462
|
|
|
def Neighbors(self, i, KH, KH_f, iw, ib, N, W_n, task): |
463
|
|
|
Rgb, RR, Kw_Kgb = KH[ib] - KH[i], KH - KH[i], KH_f[iw] - KH_f[ib] |
464
|
|
|
R = sqrt(sum(RR * RR)) |
465
|
|
|
alpha_b = -2 * (1 + self.rand() * task.Iters / task.nGEN) * (KH_f[ib]) / Kw_Kgb / sqrt(sum(Rgb * Rgb)) * Rgb if KH_f[ib] < KH_f[i] else 0 |
466
|
|
|
alpah_n, nn, ds = 0.0, 0, mean(R) / 5 |
467
|
|
|
for n in range(self.NP): |
468
|
|
|
if R < ds and n != i: |
469
|
|
|
nn += 1 |
470
|
|
|
if nn <= 4 and KH_f[i] != KH[n]: alpah_n -= (KH(n) - KH[i]) / Kw_Kgb / R[n] * RR[n] |
471
|
|
|
return W_n * N * self.N_max * (alpha_b + alpah_n) |
472
|
|
|
|
473
|
|
|
def Foraging(self, KH, KH_f, KHo, KHo_f, W_f, F, KH_wf, KH_bf, x_food, x_food_f, task): |
474
|
|
|
Rf, Kw_Kgb = x_food - KH, KH_wf - KH_bf |
475
|
|
|
beta_f = -2 * (1 - task.Iters / task.nGEN) * (x_food_f - KH_f) / Kw_Kgb / sqrt(sum(Rf * Rf)) * Rf if x_food_f < KH_f else 0 |
476
|
|
|
Rib = KHo - KH |
477
|
|
|
beta_b = -(KHo_f - KH_f) / Kw_Kgb / sqrt(sum(Rib * Rib)) * Rib if KHo_f < KH_f else 0 |
478
|
|
|
return W_f * F + self.V_f * (beta_b + beta_f) |
479
|
|
|
|
480
|
|
|
def Cr(self, KH_f, KHb_f, KHw_f): return 0.8 + 0.2 * (KH_f - KHb_f) / (KHw_f - KHb_f) |
481
|
|
|
|
482
|
|
|
def initPopulation(self, task): |
483
|
|
|
KH, KH_f, d = Algorithm.initPopulation(self, task) |
484
|
|
|
KHo, KHo_f = full([self.NP, task.D], task.optType.value * inf), full(self.NP, task.optType.value * inf) |
485
|
|
|
N, F, Dt = full(self.NP, .0), full(self.NP, .0), mean(task.bcRange()) / 2 |
486
|
|
|
d.update({'KHo': KHo, 'KHo_f': KHo_f, 'N': N, 'F': F, 'Dt': Dt}) |
487
|
|
|
return KH, KH_f, d |
488
|
|
|
|
489
|
|
|
def runIteration(self, task, KH, KH_f, xb, fxb, KHo, KHo_f, N, F, Dt, **dparams): |
490
|
|
|
w = full(task.D, 0.1 + 0.8 * (1 - task.Iters / task.nGEN)) |
491
|
|
|
ib, iw = argmin(KH_f), argmax(KH_f) |
492
|
|
|
x_food, x_food_f = self.getFoodLocation(KH, KH_f, task) |
493
|
|
|
N = asarray([self.Neighbors(i, KH, KH_f, iw, ib, N[i], w, task) for i in range(self.NP)]) |
494
|
|
|
F = asarray([self.Foraging(KH[i], KH_f[i], KHo[i], KHo_f[i], w, F[i], KH_f[iw], KH_f[ib], x_food, x_food_f, task) for i in range(self.NP)]) |
495
|
|
|
Cr = asarray([self.Cr(KH_f[i], KH_f[ib], KH_f[iw]) for i in range(self.NP)]) |
496
|
|
|
KH_n = asarray([self.crossover(KH[self.randint(self.NP)], KH[i], Cr[i]) for i in range(self.NP)]) |
497
|
|
|
KH_n = KH + Dt * (F + N) |
498
|
|
|
KH = apply_along_axis(task.repair, 1, KH_n, self.Rand) |
499
|
|
|
KH_f = apply_along_axis(task.eval, 1, KH) |
500
|
|
|
KHo, KHo_f = self.ElitistSelection(KH, KH_f, KHo, KHo_f) |
501
|
|
|
return KH, KH_f, {'KHo': KHo, 'KHo_f': KHo_f, 'N': N, 'F': F, 'Dt': Dt} |
502
|
|
|
|
503
|
|
|
# vim: tabstop=3 noexpandtab shiftwidth=3 softtabstop=3 |
504
|
|
|
|