NiaPy.algorithms.basic.kh   F
last analyzed

Complexity

Total Complexity 66

Size/Duplication

Total Lines 867
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 207
dl 0
loc 867
rs 3.12
c 0
b 0
f 0
wmc 66

39 Methods

Rating   Name   Duplication   Size   Complexity  
A KrillHerd.getNeighbours() 0 16 5
A KrillHerd.sensRange() 0 11 1
A KrillHerd.algorithmInfo() 0 11 1
A KrillHerdV11.Foraging() 0 24 3
A KrillHerd.getFoodLocation() 0 16 1
A KrillHerdV4.typeParameters() 0 15 1
A KrillHerd.induceForagingMotion() 0 21 2
A KrillHerdV1.typeParameters() 0 11 1
A KrillHerdV11.initPopulation() 0 25 1
A KrillHerdV11.Cr() 0 12 1
A KrillHerdV3.algorithmInfo() 0 11 1
A KrillHerdV2.typeParameters() 0 13 1
A KrillHerdV3.typeParameters() 0 13 1
A KrillHerd.getParameters() 0 21 1
A KrillHerd.funX() 0 11 1
A KrillHerdV4.setParameters() 0 18 1
A KrillHerdV2.mutate() 0 12 1
A KrillHerd.inducePhysicalDiffusion() 0 10 1
A KrillHerd.deltaT() 0 10 1
A KrillHerdV11.runIteration() 0 37 1
A KrillHerd.runIteration() 0 42 2
A KrillHerdV1.algorithmInfo() 0 11 1
A KrillHerd.setParameters() 0 22 1
A KrillHerdV2.algorithmInfo() 0 11 1
A KrillHerdV11.ElitistSelection() 0 17 1
A KrillHerd.funK() 0 13 1
B KrillHerdV11.Neighbors() 0 25 7
A KrillHerdV1.mutate() 0 12 1
A KrillHerdV1.crossover() 0 12 1
A KrillHerd.initPopulation() 0 24 1
A KrillHerd.Cr() 0 13 1
A KrillHerd.induceNeighborsMotion() 0 21 1
D KrillHerd.typeParameters() 0 36 12
A KrillHerd.crossover() 0 12 2
A KrillHerdV4.algorithmInfo() 0 11 1
A KrillHerd.mutate() 0 12 2
A KrillHerdV3.crossover() 0 12 1
A KrillHerd.initWeights() 0 12 1
A KrillHerd.Mu() 0 13 1

How to fix   Complexity   

Complexity

Complex classes like NiaPy.algorithms.basic.kh often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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