Completed
Push — master ( cc7745...279fb5 )
by Grega
19s queued 17s
created

KrillHerd.getParameters()   A

Complexity

Conditions 1

Size

Total Lines 21
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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