Passed
Pull Request — master (#233)
by
unknown
01:19
created

KrillHerd.setParameters()   A

Complexity

Conditions 1

Size

Total Lines 22
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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