KrillHerd.induceNeighborsMotion()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 21
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nop 9
dl 0
loc 21
rs 10
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
# encoding=utf8
2
import logging
3
from scipy.spatial.distance import euclidean as ed
4
from numpy import apply_along_axis, argmin, argmax, sum, full, inf, asarray, mean, where, sqrt
5
from NiaPy.util import fullArray
6
from NiaPy.algorithms.algorithm import Algorithm
7
8
logging.basicConfig()
9
logger = logging.getLogger('NiaPy.algorithms.basic')
10
logger.setLevel('INFO')
11
12
__all__ = ['KrillHerdV1', 'KrillHerdV2', 'KrillHerdV3', 'KrillHerdV4', 'KrillHerdV11']
13
14
class KrillHerd(Algorithm):
15
	r"""Implementation of krill herd algorithm.
16
17
	Algorithm:
18
		Krill Herd Algorithm
19
20
	Date:
21
		2018
22
23
	Authors:
24
		Klemen Berkovič
25
26
	License:
27
		MIT
28
29
	Reference URL:
30
		http://www.sciencedirect.com/science/article/pii/S1007570412002171
31
32
	Reference paper:
33
		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.
34
35
	Attributes:
36
		Name (List[str]): List of strings representing algorithm names.
37
		NP (int): Number of krill herds in population.
38
		N_max (float): Maximum induced speed.
39
		V_f (float): Foraging speed.
40
		D_max (float): Maximum diffusion speed.
41
		C_t (float): Constant :math:`\in [0, 2]`
42
		W_n (Union[int, float, numpy.ndarray]): Interta weights of the motion induced from neighbors :math:`\in [0, 1]`.
43
		W_f (Union[int, float, numpy.ndarray]): Interta weights of the motion induced from foraging :math`\in [0, 1]`.
44
		d_s (float): Maximum euclidean distance for neighbors.
45
		nn (int): Maximum neighbors for neighbors effect.
46
		Cr (float): Crossover probability.
47
		Mu (float): Mutation probability.
48
		epsilon (float): Small numbers for division.
49
50
	See Also:
51
		* :class:`NiaPy.algorithms.algorithm.Algorithm`
52
	"""
53
	Name = ['KrillHerd', 'KH']
54
55
	@staticmethod
56
	def algorithmInfo():
57
		r"""Get basic information of algorithm.
58
59
		Returns:
60
			str: Basic information of algorithm.
61
62
		See Also:
63
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
64
		"""
65
		return r"""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."""
66
67
	@staticmethod
68
	def typeParameters():
69
		r"""Get dictionary with functions for checking values of parameters.
70
71
		Returns:
72
			Dict[str, Callable]:
73
				* N_max (Callable[[Union[int, float]], bool])
74
				* V_f (Callable[[Union[int, float]], bool])
75
				* D_max (Callable[[Union[int, float]], bool])
76
				* C_t (Callable[[Union[int, float]], bool])
77
				* W_n (Callable[[Union[int, float]], bool])
78
				* W_f (Callable[[Union[int, float]], bool])
79
				* d_s (Callable[[Union[int, float]], boool])
80
				* nn (Callable[[int], bool])
81
				* Cr (Callable[[float], bool])
82
				* Mu (Callable[[float], bool])
83
				* epsilon (Callable[[float], bool])
84
85
		See Also:
86
			* :func:`NiaPy.algorithms.algorithm.Algorithm`
87
		"""
88
		d = Algorithm.typeParameters()
89
		d.update({
90
			'N_max': lambda x: isinstance(x, (int, float)) and x > 0,
91
			'V_f': lambda x: isinstance(x, (int, float)) and x > 0,
92
			'D_max': lambda x: isinstance(x, (int, float)) and x > 0,
93
			'C_t': lambda x: isinstance(x, (int, float)) and x > 0,
94
			'W_n': lambda x: isinstance(x, (int, float)) and x > 0,
95
			'W_f': lambda x: isinstance(x, (int, float)) and x > 0,
96
			'd_s': lambda x: isinstance(x, (int, float)) and x > 0,
97
			'nn': lambda x: isinstance(x, int) and x > 0,
98
			'Cr': lambda x: isinstance(x, float) and 0 <= x <= 1,
99
			'Mu': lambda x: isinstance(x, float) and 0 <= x <= 1,
100
			'epsilon': lambda x: isinstance(x, float) and 0 < x < 1
101
		})
102
		return d
103
104
	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):
105
		r"""Set the arguments of an algorithm.
106
107
		Arguments:
108
			NP (Optional[int]): Number of krill herds in population.
109
			N_max (Optional[float]): Maximum induced speed.
110
			V_f (Optional[float]): Foraging speed.
111
			D_max (Optional[float]): Maximum diffusion speed.
112
			C_t (Optional[float]): Constant $\in [0, 2]$.
113
			W_n (Optional[Union[int, float, numpy.ndarray]]): Intera weights of the motion induced from neighbors :math:`\in [0, 1]`.
114
			W_f (Optional[Union[int, float, numpy.ndarray]]): Intera weights of the motion induced from foraging :math:`\in [0, 1]`.
115
			d_s (Optional[float]): Maximum euclidean distance for neighbors.
116
			nn (Optional[int]): Maximum neighbors for neighbors effect.
117
			Cr (Optional[float]): Crossover probability.
118
			Mu (Optional[float]): Mutation probability.
119
			epsilon (Optional[float]): Small numbers for division.
120
121
		See Also:
122
			* :func:`NiaPy.algorithms.algorithm.Algorithm.setParameters`
123
		"""
124
		Algorithm.setParameters(self, NP=NP, **ukwargs)
125
		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
126
127
	def getParameters(self):
128
		r"""Get parameter values for the algorithm.
129
130
		Returns:
131
			Dict[str, Any]: TODO.
132
		"""
133
		d = Algorithm.getParameters(self)
134
		d.update({
135
			'N_max': self.N_max,
136
			'V_f': self.V_f,
137
			'D_max': self.D_max,
138
			'C_t': self.C_t,
139
			'W_n': self.W_n,
140
			'W_f': self.W_f,
141
			'd_s': self.d_s,
142
			'nn': self.nn,
143
			'Cr': self.Cr,
144
			'Mu': self.Mu,
145
			'epsilon': self.epsilon
146
		})
147
		return d
148
149
	def initWeights(self, task):
150
		r"""Initialize weights.
151
152
		Args:
153
			task (Task): Optimization task.
154
155
		Returns:
156
			Tuple[numpy.ndarray, numpy.ndarray]:
157
				1. Weights for neighborhood.
158
				2. Weights for foraging.
159
		"""
160
		return fullArray(self.W_n, task.D), fullArray(self.W_f, task.D)
161
162
	def sensRange(self, ki, KH):
163
		r"""Calculate sense range for selected individual.
164
165
		Args:
166
			ki (int): Selected individual.
167
			KH (numpy.ndarray): Krill heard population.
168
169
		Returns:
170
			float: Sense range for krill.
171
		"""
172
		return sum([ed(KH[ki], KH[i]) for i in range(self.NP)]) / (self.nn * self.NP)
173
174
	def getNeighbours(self, i, ids, KH):
175
		r"""Get neighbours.
176
177
		Args:
178
			i (int): Individual looking for neighbours.
179
			ids (float): Maximal distance for being a neighbour.
180
			KH (numpy.ndarray): Current population.
181
182
		Returns:
183
			numpy.ndarray: Neighbours of krill heard.
184
		"""
185
		N = list()
186
		for j in range(self.NP):
187
			if j != i and ids > ed(KH[i], KH[j]): N.append(j)
188
		if not N: N.append(self.randint(self.NP))
189
		return asarray(N)
190
191
	def funX(self, x, y):
192
		r"""Get x values.
193
194
		Args:
195
			x (numpy.ndarray): First krill/individual.
196
			y (numpy.ndarray): Second krill/individual.
197
198
		Returns:
199
			numpy.ndarray: --
200
		"""
201
		return ((y - x) + self.epsilon) / (ed(y, x) + self.epsilon)
202
203
	def funK(self, x, y, b, w):
204
		r"""Get k values.
205
206
		Args:
207
			x (numpy.ndarray): First krill/individual.
208
			y (numpy.ndarray): Second krill/individual.
209
			b (numpy.ndarray): Best krill/individual.
210
			w (numpy.ndarray): Worst krill/individual.
211
212
		Returns:
213
			numpy.ndarray: --
214
		"""
215
		return ((x - y) + self.epsilon) / ((w - b) + self.epsilon)
216
217
	def induceNeighborsMotion(self, i, n, W, KH, KH_f, ikh_b, ikh_w, task):
218
		r"""Induced neighbours motion operator.
219
220
		Args:
221
			i (int): Index of individual being applied with operator.
222
			n:
223
			W (numpy.ndarray[float]): Wights for this operator.
224
			KH (numpy.ndarray): Current heard/population.
225
			KH_f (numpy.ndarray[float]): Current populations/heard function/fitness values.
226
			ikh_b (int): Current best krill in heard/population.
227
			ikh_w (int): Current worst krill in heard/population.
228
			task (Task): Optimization task.
229
230
		Returns:
231
			numpy.ndarray: Moved krill.
232
		"""
233
		Ni = self.getNeighbours(i, self.sensRange(i, KH), KH)
234
		Nx, Nf, f_b, f_w = KH[Ni], KH_f[Ni], KH_f[ikh_b], KH_f[ikh_w]
235
		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)
236
		alpha_t = 2 * (1 + self.rand() * task.Iters / task.nGEN)
237
		return self.N_max * (alpha_l + alpha_t) + W * n
238
239
	def induceForagingMotion(self, i, x, x_f, f, W, KH, KH_f, ikh_b, ikh_w, task):
240
		r"""Induced foraging motion operator.
241
242
		Args:
243
			i (int): Index of current krill being operated.
244
			x (numpy.ndarray): Position of food.
245
			x_f (float): Fitness/function values of food.
246
			f:
247
			W (numpy.ndarray[float]): Weights for this operator.
248
			KH (numpy.ndarray):  Current population/heard.
249
			KH_f (numpy.ndarray[float]): Current heard/populations function/fitness values.
250
			ikh_b (int): Index of current best krill in heard.
251
			ikh_w (int): Index of current worst krill in heard.
252
			task (Task): Optimization task.
253
254
		Returns:
255
			numpy.ndarray: Moved krill.
256
		"""
257
		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
258
		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])
259
		return self.V_f * (beta_f + beta_b) + W * f
260
261
	def inducePhysicalDiffusion(self, task):
262
		r"""Induced physical diffusion operator.
263
264
		Args:
265
			task (Task): Optimization task.
266
267
		Returns:
268
			numpy.ndarray:
269
		"""
270
		return self.D_max * (1 - task.Iters / task.nGEN) * self.uniform(-1, 1, task.D)
271
272
	def deltaT(self, task):
273
		r"""Get new delta for all dimensions.
274
275
		Args:
276
			task (Task): Optimization task.
277
278
		Returns:
279
			numpy.ndarray: --
280
		"""
281
		return self.C_t * sum(task.bRange)
282
283
	def crossover(self, x, xo, Cr):
284
		r"""Crossover operator.
285
286
		Args:
287
			x (numpy.ndarray): Krill/individual being applied with operator.
288
			xo (numpy.ndarray): Krill/individual being used in conjunction within operator.
289
			Cr (float): Crossover probability.
290
291
		Returns:
292
			numpy.ndarray: Crossoverd krill/individual.
293
		"""
294
		return [xo[i] if self.rand() < Cr else x[i] for i in range(len(x))]
295
296
	def mutate(self, x, x_b, Mu):
297
		r"""Mutate operator.
298
299
		Args:
300
			x (numpy.ndarray): Individual being mutated.
301
			x_b (numpy.ndarray): Global best individual.
302
			Mu (float): Probability of mutations.
303
304
		Returns:
305
			numpy.ndarray: Mutated krill.
306
		"""
307
		return [x[i] if self.rand() < Mu else (x_b[i] + self.rand()) for i in range(len(x))]
308
309
	def getFoodLocation(self, KH, KH_f, task):
310
		r"""Get food location for krill heard.
311
312
		Args:
313
			KH (numpy.ndarray): Current heard/population.
314
			KH_f (numpy.ndarray[float]): Current heard/populations function/fitness values.
315
			task (Task): Optimization task.
316
317
		Returns:
318
			Tuple[numpy.ndarray, float]:
319
				1. Location of food.
320
				2. Foods function/fitness value.
321
		"""
322
		x_food = task.repair(asarray([sum(KH[:, i] / KH_f) for i in range(task.D)]) / sum(1 / KH_f), rnd=self.Rand)
323
		x_food_f = task.eval(x_food)
324
		return x_food, x_food_f
325
326
	def Mu(self, xf, yf, xf_best, xf_worst):
327
		r"""Get mutation probability.
328
329
		Args:
330
			xf (float):
331
			yf (float):
332
			xf_best (float):
333
			xf_worst (float):
334
335
		Returns:
336
			float: New mutation probability.
337
		"""
338
		return self._Mu / (self.funK(xf, yf, xf_best, xf_worst) + 1e-31)
339
340
	def Cr(self, xf, yf, xf_best, xf_worst):
341
		r"""Get crossover probability.
342
343
		Args:
344
			xf (float):
345
			yf (float):
346
			xf_best (float):
347
			xf_worst (flaot):
348
349
		Returns:
350
			float: New crossover probability.
351
		"""
352
		return self._Cr * self.funK(xf, yf, xf_best, xf_worst)
353
354
	def initPopulation(self, task):
355
		r"""Initialize stating population.
356
357
		Args:
358
			task (Task): Optimization task.
359
360
		Returns:
361
			Tuple[numpy.ndarray, numpy.ndarray, Dict[str, Any]]:
362
				1. Initialized population.
363
				2. Initialized populations function/fitness values.
364
				3. Additional arguments:
365
					* W_n (numpy.ndarray): Weights neighborhood.
366
					* W_f (numpy.ndarray): Weights foraging.
367
					* N (numpy.ndarray): TODO
368
					* F (numpy.ndarray): TODO
369
370
		See Also:
371
			* :func:`NiaPy.algorithms.algorithm.Algorithm.initPopulation`
372
		"""
373
		KH, KH_f, d = Algorithm.initPopulation(self, task)
374
		W_n, W_f = self.initWeights(task)
375
		N, F = full(self.NP, .0), full(self.NP, .0)
376
		d.update({'W_n': W_n, 'W_f': W_f, 'N': N, 'F': F})
377
		return KH, KH_f, d
378
379
	def runIteration(self, task, KH, KH_f, xb, fxb, W_n, W_f, N, F, **dparams):
380
		r"""Core function of KrillHerd algorithm.
381
382
		Args:
383
			task (Task): Optimization task.
384
			KH (numpy.ndarray): Current heard/population.
385
			KH_f (numpy.ndarray[float]): Current heard/populations function/fitness values.
386
			xb (numpy.ndarray): Global best individual.
387
			fxb (float): Global best individuals function fitness values.
388
			W_n (numpy.ndarray):
389
			W_f (numpy.ndarray):
390
			N ():
391
			F ():
392
			**dparams (Dict[str, Any]): Additional arguments.
393
394
		Returns:
395
			Tuple [numpy.ndarray, numpy.ndarray, numpy.ndarray, float Dict[str, Any]]:
396
				1. New herd/population
397
				2. New herd/populations function/fitness values.
398
				3. New global best solution.
399
				4. New global best solutoins fitness/objective value.
400
				5. Additional arguments:
401
					* W_n (numpy.ndarray): --
402
					* W_f (numpy.ndarray): --
403
					* N (numpy.ndarray): --
404
					* F (numpy.ndarray): --
405
		"""
406
		ikh_b, ikh_w = argmin(KH_f), argmax(KH_f)
407
		x_food, x_food_f = self.getFoodLocation(KH, KH_f, task)
408
		if x_food_f < fxb: xb, fxb = x_food, x_food_f  # noqa: F841
409
		N = asarray([self.induceNeighborsMotion(i, N[i], W_n, KH, KH_f, ikh_b, ikh_w, task) for i in range(self.NP)])
410
		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)])
411
		D = asarray([self.inducePhysicalDiffusion(task) for i in range(self.NP)])
412
		KH_n = KH + (self.deltaT(task) * (N + F + D))
413
		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)])
414
		KH_n = asarray([self.crossover(KH_n[i], KH[i], Cr[i]) for i in range(self.NP)])
415
		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)])
416
		KH_n = asarray([self.mutate(KH_n[i], KH[ikh_b], Mu[i]) for i in range(self.NP)])
417
		KH = apply_along_axis(task.repair, 1, KH_n, rnd=self.Rand)
418
		KH_f = apply_along_axis(task.eval, 1, KH)
419
		xb, fxb = self.getBest(KH, KH_f, xb, fxb)
420
		return KH, KH_f, xb, fxb, {'W_n': W_n, 'W_f': W_f, 'N': N, 'F': F}
421
422
class KrillHerdV4(KrillHerd):
423
	r"""Implementation of krill herd algorithm.
424
425
	Algorithm:
426
		Krill Herd Algorithm
427
428
	Date:
429
		2018
430
431
	Authors:
432
		Klemen Berkovič
433
434
	License:
435
		MIT
436
437
	Reference URL:
438
		http://www.sciencedirect.com/science/article/pii/S1007570412002171
439
440
	Reference paper:
441
		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.
442
443
	Attributes:
444
		Name (List[str]): List of strings representing algorithm name.
445
	"""
446
	Name = ['KrillHerdV4', 'KHv4']
447
448
	@staticmethod
449
	def algorithmInfo():
450
		r"""Get basic information of algorithm.
451
452
		Returns:
453
			str: Basic information of algorithm.
454
455
		See Also:
456
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
457
		"""
458
		return r"""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."""
459
460
	@staticmethod
461
	def typeParameters():
462
		r"""Get dictionary with functions for checking values of parameters.
463
464
		Returns:
465
			Dict[str, Callable]: Dictionary with testing functions for parameters.
466
467
		See Also:
468
			* :func:NiaPy.algorithms.basic.kh.KrillHerd.typeParameters`
469
		"""
470
		d = KrillHerd.typeParameters()
471
		d.pop('Cr', None)
472
		d.pop('Mu', None)
473
		d.pop('epsilon', None)
474
		return d
475
476
	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):
477
		r"""Set algorithm core parameters.
478
479
		Args:
480
			NP (int): Number of kills in herd.
481
			N_max (Optional[float]): TODO
482
			V_f (Optional[float]): TODO
483
			D_max (Optional[float]): TODO
484
			C_t (Optional[float]): TODO
485
			W_n (Optional[Union[int, float, numpy.ndarray, list]]): Weights for neighborhood.
486
			W_f (Optional[Union[int, float, numpy.ndarray, list]]): Weights for foraging.
487
			d_s (Optional[float]): TODO
488
			**ukwargs (Dict[str, Any]): Additional arguments.
489
490
		See Also:
491
			* :func:NiaPy.algorithms.basic.kh.KrillHerd.KrillHerd.setParameters`
492
		"""
493
		KrillHerd.setParameters(self, NP=NP, N_max=N_max, V_f=V_f, D_max=D_max, C_t=C_t, W_n=W_n, W_f=W_f, d_s=d_s, nn=4, Cr=0.2, Mu=0.05, epsilon=1e-31, **ukwargs)
494
495
class KrillHerdV1(KrillHerd):
496
	r"""Implementation of krill herd algorithm.
497
498
	Algorithm:
499
		Krill Herd Algorithm
500
501
	Date:
502
		2018
503
504
	Authors:
505
		Klemen Berkovič
506
507
	License:
508
		MIT
509
510
	Reference URL:
511
		http://www.sciencedirect.com/science/article/pii/S1007570412002171
512
513
	Reference paper:
514
		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.
515
516
	Attributes:
517
		Name (List[str]): List of strings representing algorithm name.
518
519
	See Also:
520
		* :func:NiaPy.algorithms.basic.kh.KrillHerd.KrillHerd`
521
	"""
522
	Name = ['KrillHerdV1', 'KHv1']
523
524
	@staticmethod
525
	def algorithmInfo():
526
		r"""Get basic information of algorithm.
527
528
		Returns:
529
			str: Basic information of algorithm.
530
531
		See Also:
532
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
533
		"""
534
		return r"""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."""
535
536
	@staticmethod
537
	def typeParameters():
538
		r"""Get dictionary with functions for checking values of parameters.
539
540
		Returns:
541
			Dict[str, Callable]: Dictionary with testing functions for parameters.
542
543
		See Also:
544
			* :func:NiaPy.algorithms.basic.kh.KrillHerd.typeParameters`
545
		"""
546
		return KrillHerd.typeParameters()
547
548
	def crossover(self, x, xo, Cr):
549
		r"""Preform a crossover operation on individual.
550
551
		Args:
552
			x (numpy.ndarray): Current individual.
553
			xo (numpy.ndarray): New individual.
554
			Cr (float): Crossover probability.
555
556
		Returns:
557
			numpy.ndarray: Crossover individual.
558
		"""
559
		return x
560
561
	def mutate(self, x, x_b, Mu):
562
		r"""Mutate individual.
563
564
		Args:
565
			x (numpy.ndarray): Current individual.
566
			x_b (numpy.ndarray): Global best individual.
567
			Mu (float): Mutation probability.
568
569
		Returns:
570
			numpy.ndarray: Mutated krill.
571
		"""
572
		return x
573
574
class KrillHerdV2(KrillHerd):
575
	r"""Implementation of krill herd algorithm.
576
577
	Algorithm:
578
		Krill Herd Algorithm
579
580
	Date:
581
		2018
582
583
	Authors:
584
		Klemen Berkovič
585
586
	License:
587
		MIT
588
589
	Reference URL:
590
		http://www.sciencedirect.com/science/article/pii/S1007570412002171
591
592
	Reference paper:
593
		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.
594
595
	Attributes:
596
		Name (List[str]): List of strings representing algorithm name.
597
	"""
598
	Name = ['KrillHerdV2', 'KHv2']
599
600
	@staticmethod
601
	def algorithmInfo():
602
		r"""Get basic information of algorithm.
603
604
		Returns:
605
			str: Basic information of algorithm.
606
607
		See Also:
608
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
609
		"""
610
		return r"""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."""
611
612
	@staticmethod
613
	def typeParameters():
614
		r"""Get dictionary with functions for checking values of parameters.
615
616
		Returns:
617
			Dict[str, Callable]: Dictionary with testing functions for algorithms parameters.
618
619
		See Also:
620
			* :func:NiaPy.algorithms.basic.kh.KrillHerd.typeParameters`
621
		"""
622
		d = KrillHerd.typeParameters()
623
		d.pop('Mu', None)
624
		return d
625
626
	def mutate(self, x, x_b, Mu):
627
		r"""Mutate individual.
628
629
		Args:
630
			x (numpy.ndarray): Individual to mutate.
631
			x_b (numpy.ndarray): Global best individual.
632
			Mu (float): Mutation probability.
633
634
		Returns:
635
			numpy.ndarray: Mutated individual.
636
		"""
637
		return x
638
639
class KrillHerdV3(KrillHerd):
640
	r"""Implementation of krill herd algorithm.
641
642
	Algorithm:
643
		Krill Herd Algorithm
644
645
	Date:
646
		2018
647
648
	Authors:
649
		Klemen Berkovič
650
651
	License:
652
		MIT
653
654
	Reference URL:
655
		http://www.sciencedirect.com/science/article/pii/S1007570412002171
656
657
	Reference paper:
658
		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.
659
	"""
660
	Name = ['KrillHerdV3', 'KHv3']
661
662
	@staticmethod
663
	def algorithmInfo():
664
		r"""Get basic information of algorithm.
665
666
		Returns:
667
			str: Basic information of algorithm.
668
669
		See Also:
670
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
671
		"""
672
		return r"""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."""
673
674
	@staticmethod
675
	def typeParameters():
676
		r"""Get dictionary with functions for checking values of parameters.
677
678
		Returns:
679
			Dict[str, Callable]: Dictionary with testing functions for algorithms parameters.
680
681
		See Also:
682
			* :func:NiaPy.algorithms.basic.kh.KrillHerd.typeParameters`
683
		"""
684
		d = KrillHerd.typeParameters()
685
		d.pop('Cr', None)
686
		return d
687
688
	def crossover(self, x, xo, Cr):
689
		r"""Crossover operator.
690
691
		Args:
692
			x (numpy.ndarray): Krill/individual being applied with operator.
693
			xo (numpy.ndarray): Krill/individual being used in operator.
694
			Cr (float): Crossover probability.
695
696
		Returns:
697
			numpy.ndarray: Crossover krill/individual.
698
		"""
699
		return x
700
701
class KrillHerdV11(KrillHerd):
702
	r"""Implementation of krill herd algorithm.
703
704
	Algorithm:
705
		Krill Herd Algorithm
706
707
	Date:
708
		2018
709
710
	Authors:
711
		Klemen Berkovič
712
713
	License:
714
		MIT
715
716
	Reference URL:
717
718
	Reference paper:
719
	"""
720
	Name = ['KrillHerdV11', 'KHv11']
721
722
	def ElitistSelection(self, KH, KH_f, KHo, KHo_f):
723
		r"""Select krills/individuals that are better than odl krills.
724
725
		Args:
726
			KH (numpy.ndarray): Current herd/population.
727
			KH_f (numpy.ndarray[float]): Current herd/populations function/fitness values
728
			KHo (numpy.ndarray): New herd/population.
729
			KHo_f (numpy.ndarray[float]): New herd/populations function/fitness vales.
730
731
		Returns:
732
			Tuple[numpy.ndarray, numpy.numpy[float]]:
733
				1. New herd/population.
734
				2. New herd/populations function/fitness values.
735
		"""
736
		ipb = where(KHo_f >= KH_f)
737
		KHo[ipb], KHo_f[ipb] = KH[ipb], KH_f[ipb]
738
		return KHo, KHo_f
739
740
	def Neighbors(self, i, KH, KH_f, iw, ib, N, W_n, task):
741
		r"""Neighbors operator.
742
743
		Args:
744
			i (int): Index of krill being applied with operator.
745
			KH (numpy.ndarray): Current herd/population.
746
			KH_f (numpy.ndarray[float]): Current herd/populations function/fitness values.
747
			iw (int): Index of worst krill/individual.
748
			ib (int): Index of best krill/individual.
749
			N (): --
750
			W_n (numpy.ndarray): Weights for neighbors operator.
751
			task (Task): Optimization task.
752
753
		Returns:
754
			numpy.ndarray: --
755
		"""
756
		Rgb, RR, Kw_Kgb = KH[ib] - KH[i], KH - KH[i], KH_f[iw] - KH_f[ib]
757
		R = sqrt(sum(RR * RR))
758
		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
759
		alpah_n, nn, ds = 0.0, 0, mean(R) / 5
760
		for n in range(self.NP):
761
			if R < ds and n != i:
762
				nn += 1
763
				if nn <= 4 and KH_f[i] != KH[n]: alpah_n -= (KH(n) - KH[i]) / Kw_Kgb / R[n] * RR[n]
764
		return W_n * N * self.N_max * (alpha_b + alpah_n)
765
766
	def Foraging(self, KH, KH_f, KHo, KHo_f, W_f, F, KH_wf, KH_bf, x_food, x_food_f, task):
767
		r"""Foraging operator.
768
769
		Args:
770
			KH (numpy.ndarray): Current heard/population.
771
			KH_f (numpy.ndarray[float]): Current herd/populations function/fitness values.
772
			KHo (numpy.ndarray): New heard/population.
773
			KHo_f (numpy.ndarray[float]): New heard/population function/fitness values.
774
			W_f (numpy.ndarray): Weights for foraging.
775
			F (): --
776
			KH_wf (numpy.ndarray): Worst krill in herd/population.
777
			KH_bf (numpy.ndarray): Best krill in herd/population.
778
			x_food (numpy.ndarray): Foods position.
779
			x_food_f (float): Foods function/fitness value.
780
			task (Task): Optimization task.
781
782
		Returns:
783
			numpy.ndarray: --
784
		"""
785
		Rf, Kw_Kgb = x_food - KH, KH_wf - KH_bf
786
		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
787
		Rib = KHo - KH
788
		beta_b = -(KHo_f - KH_f) / Kw_Kgb / sqrt(sum(Rib * Rib)) * Rib if KHo_f < KH_f else 0
789
		return W_f * F + self.V_f * (beta_b + beta_f)
790
791
	def Cr(self, KH_f, KHb_f, KHw_f):
792
		r"""Calculate crossover probability.
793
794
		Args:
795
			KH_f (float): Krill/individuals function/fitness value.
796
			KHb_f (float): Best krill/individual function/fitness value.
797
			KHw_f (float): Worst krill/individual function/fitness value.
798
799
		Returns:
800
			float: Crossover probability.
801
		"""
802
		return 0.8 + 0.2 * (KH_f - KHb_f) / (KHw_f - KHb_f)
803
804
	def initPopulation(self, task):
805
		r"""Initialize firt herd/population.
806
807
		Args:
808
			task (Task): Optimization task.
809
810
		Returns:
811
			Tuple[numpy.ndarray, numpy.ndarray[float], Dict[str, Any]]:
812
				1. Initialized herd/population.
813
				2. Initialized herd/populations function/fitness values.
814
				3. Additional arguments:
815
					* KHo (): --
816
					* KHo_f (): --
817
					* N (): --
818
					* F (): --
819
					* Dt (): --
820
821
		See Also:
822
			* :func:`NiaPy.algorithms.Algorithm.initPopulation`
823
		"""
824
		KH, KH_f, d = Algorithm.initPopulation(self, task)
825
		KHo, KHo_f = full([self.NP, task.D], task.optType.value * inf), full(self.NP, task.optType.value * inf)
826
		N, F, Dt = full(self.NP, .0), full(self.NP, .0), mean(task.bcRange()) / 2
827
		d.update({'KHo': KHo, 'KHo_f': KHo_f, 'N': N, 'F': F, 'Dt': Dt})
828
		return KH, KH_f, d
829
830
	def runIteration(self, task, KH, KH_f, xb, fxb, KHo, KHo_f, N, F, Dt, **dparams):
831
		r"""Core function of KrillHerdV11 algorithm.
832
833
		Args:
834
			task (Task): Optimization task.
835
			KH (numpy.ndarray): Current herd/population.
836
			KH_f (numpy.ndarray[float]): Current herd/populations function/fitness values.
837
			xb (numpy.ndarray): Global best krill.
838
			fxb (float): Global best krill function/fitness value.
839
			KHo ():
840
			KHo_f ():
841
			N ():
842
			F ():
843
			Dt ():
844
			**dparams (Dict[str, Any]): Additional arguments.
845
846
		Returns:
847
			Tuple[numpy.ndarray, numpy.ndarray[float], Dict[str, Any]]:
848
				1. New herd/population.
849
				2. New herd/populations function/fitness values.
850
				3. Additional arguments:
851
852
		"""
853
		w = full(task.D, 0.1 + 0.8 * (1 - task.Iters / task.nGEN))
854
		ib, iw = argmin(KH_f), argmax(KH_f)
855
		x_food, x_food_f = self.getFoodLocation(KH, KH_f, task)
856
		xb, fxb = self.getBest(x_food, x_food_f, xb, fxb)
857
		N = asarray([self.Neighbors(i, KH, KH_f, iw, ib, N[i], w, task) for i in range(self.NP)])
858
		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)])
859
		Cr = asarray([self.Cr(KH_f[i], KH_f[ib], KH_f[iw]) for i in range(self.NP)])
860
		KH_n = asarray([self.crossover(KH[self.randint(self.NP)], KH[i], Cr[i]) for i in range(self.NP)])
861
		KH_n = KH + Dt * (F + N)
862
		KH = apply_along_axis(task.repair, 1, KH_n, self.Rand)
863
		KH_f = apply_along_axis(task.eval, 1, KH)
864
		KHo, KHo_f = self.ElitistSelection(KH, KH_f, KHo, KHo_f)
865
		xb, fxb = self.getBest(KH, KH_f, xb, fxb)
866
		return KH, KH_f, xb, fxb, {'KHo': KHo, 'KHo_f': KHo_f, 'N': N, 'F': F, 'Dt': Dt}
867
868
# vim: tabstop=3 noexpandtab shiftwidth=3 softtabstop=3
869