NiaPy.algorithms.basic.gso   A
last analyzed

Complexity

Total Complexity 37

Size/Duplication

Total Lines 453
Duplicated Lines 4.86 %

Importance

Changes 0
Metric Value
eloc 108
dl 22
loc 453
rs 9.44
c 0
b 0
f 0
wmc 37

21 Methods

Rating   Name   Duplication   Size   Complexity  
B GlowwormSwarmOptimization.typeParameters() 22 22 8
A GlowwormSwarmOptimization.getParameters() 0 19 1
A GlowwormSwarmOptimization.getNeighbors() 0 15 3
A GlowwormSwarmOptimization.moveSelect() 0 15 3
A GlowwormSwarmOptimization.probabilityes() 0 14 3
A GlowwormSwarmOptimization.initPopulation() 0 20 1
A GlowwormSwarmOptimization.runIteration() 0 35 3
A GlowwormSwarmOptimization.algorithmInfo() 0 8 1
A GlowwormSwarmOptimization.calcLuciferin() 0 11 1
A GlowwormSwarmOptimization.setParameters() 0 17 1
A GlowwormSwarmOptimization.rangeUpdate() 0 12 1
A GlowwormSwarmOptimizationV3.rangeUpdate() 0 12 2
A GlowwormSwarmOptimizationV1.calcLuciferin() 0 11 1
A GlowwormSwarmOptimizationV3.algorithmInfo() 0 8 1
A GlowwormSwarmOptimizationV2.rangeUpdate() 0 12 1
A GlowwormSwarmOptimizationV1.rangeUpdate() 0 12 1
A GlowwormSwarmOptimizationV2.algorithmInfo() 0 8 1
A GlowwormSwarmOptimizationV3.setParameters() 0 12 1
A GlowwormSwarmOptimizationV1.setParameters() 0 7 1
A GlowwormSwarmOptimizationV1.algorithmInfo() 0 8 1
A GlowwormSwarmOptimizationV2.setParameters() 0 12 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
# encoding=utf8
2
import logging
3
4
from scipy.spatial.distance import euclidean
5
from numpy import full, apply_along_axis, copy, sum, fmax, pi, where
6
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__ = ['GlowwormSwarmOptimization', 'GlowwormSwarmOptimizationV1', 'GlowwormSwarmOptimizationV2', 'GlowwormSwarmOptimizationV3']
14
15
class GlowwormSwarmOptimization(Algorithm):
16
	r"""Implementation of glowworm swarm optimization.
17
18
	Algorithm:
19
		Glowworm Swarm Optimization Algorithm
20
21
	Date:
22
		2018
23
24
	Authors:
25
		Klemen Berkovič
26
27
	License:
28
		MIT
29
30
	Reference URL:
31
		https://www.springer.com/gp/book/9783319515946
32
33
	Reference paper:
34
		Kaipa, Krishnanand N., and Debasish Ghose. Glowworm swarm optimization: theory, algorithms, and applications. Vol. 698. Springer, 2017.
35
36
	Attributes:
37
		Name (List[str]): List of strings represeinting algorithm name.
38
		l0 (float): Initial luciferin quantity for each glowworm.
39
		nt (float): --
40
		rs (float): Maximum sensing range.
41
		rho (float): Luciferin decay constant.
42
		gamma (float): Luciferin enhancement constant.
43
		beta (float): --
44
		s (float): --
45
		Distance (Callable[[numpy.ndarray, numpy.ndarray], float]]): Measure distance between two individuals.
46
47
	See Also:
48
		* :class:`NiaPy.algorithms.algorithm.Algorithm`
49
	"""
50
	Name = ['GlowwormSwarmOptimization', 'GSO']
51
52
	@staticmethod
53
	def algorithmInfo():
54
		r"""Get basic information of algorithm.
55
56
		Returns:
57
			str: Basic information.
58
		"""
59
		return r"""Kaipa, Krishnanand N., and Debasish Ghose. Glowworm swarm optimization: theory, algorithms, and applications. Vol. 698. Springer, 2017."""
60
61 View Code Duplication
	@staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
62
	def typeParameters():
63
		r"""Get dictionary with functions for checking values of parameters.
64
65
		Returns:
66
			Dict[str, Callable]:
67
				* n (Callable[[int], bool])
68
				* l0 (Callable[[Union[float, int]], bool])
69
				* nt (Callable[[Union[float, int]], bool])
70
				* rho (Callable[[Union[float, int]], bool])
71
				* gamma (Callable[[float], bool])
72
				* beta (Callable[[float], bool])
73
				* s (Callable[[float], bool])
74
		"""
75
		return {
76
			'n': lambda x: isinstance(x, int) and x > 0,
77
			'l0': lambda x: isinstance(x, (float, int)) and x > 0,
78
			'nt': lambda x: isinstance(x, (float, int)) and x > 0,
79
			'rho': lambda x: isinstance(x, float) and 0 < x < 1,
80
			'gamma': lambda x: isinstance(x, float) and 0 < x < 1,
81
			'beta': lambda x: isinstance(x, float) and x > 0,
82
			's': lambda x: isinstance(x, float) and x > 0
83
		}
84
85
	def setParameters(self, n=25, l0=5, nt=5, rho=0.4, gamma=0.6, beta=0.08, s=0.03, Distance=euclidean, **ukwargs):
86
		r"""Set the arguments of an algorithm.
87
88
		Arguments:
89
			n (Optional[int]): Number of glowworms in population.
90
			l0 (Optional[float]): Initial luciferin quantity for each glowworm.
91
			nt (Optional[float]): --
92
			rs (Optional]float]): Maximum sensing range.
93
			rho (Optional[float]): Luciferin decay constant.
94
			gamma (Optional[float]): Luciferin enhancement constant.
95
			beta (Optional[float]): --
96
			s (Optional[float]): --
97
			Distance (Optional[Callable[[numpy.ndarray, numpy.ndarray], float]]]): Measure distance between two individuals.
98
		"""
99
		ukwargs.pop('NP', None)
100
		Algorithm.setParameters(self, NP=n, **ukwargs)
101
		self.l0, self.nt, self.rho, self.gamma, self.beta, self.s, self.Distance = l0, nt, rho, gamma, beta, s, Distance
102
103
	def getParameters(self):
104
		r"""Get algorithms parameters values.
105
106
		Returns:
107
			Dict[str, Any]: TODO.
108
		"""
109
		d = Algorithm.getParameters(self)
110
		d.pop('NP', None)
111
		d.update({
112
			'n': self.NP,
113
			'l0': self.l0,
114
			'nt': self.nt,
115
			'rho': self.rho,
116
			'gamma': self.gamma,
117
			'beta': self.beta,
118
			's': self.s,
119
			'Distance': self.Distance
120
		})
121
		return d
122
123
	def getNeighbors(self, i, r, GS, L):
124
		r"""Get neighbours of glowworm.
125
126
		Args:
127
			i (int): Index of glowworm.
128
			r (float): Neighborhood distance.
129
			GS (numpy.ndarray):
130
			L (numpy.ndarray[float]): Luciferin value of glowworm.
131
132
		Returns:
133
			numpy.ndarray[int]: Indexes of neighborhood glowworms.
134
		"""
135
		N = full(self.NP, 0)
136
		for j, gw in enumerate(GS): N[j] = 1 if i != j and self.Distance(GS[i], gw) <= r and L[i] >= L[j] else 0
137
		return N
138
139
	def probabilityes(self, i, N, L):
140
		r"""Calculate probabilities for glowworm to movement.
141
142
		Args:
143
			i (int): Index of glowworm to search for probable movement.
144
			N (numpy.ndarray[float]):
145
			L (numpy.ndarray[float]):
146
147
		Returns:
148
			numpy.ndarray[float]: Probabilities for each glowworm in swarm.
149
		"""
150
		d, P = sum(L[where(N == 1)] - L[i]), full(self.NP, .0)
151
		for j in range(self.NP): P[i] = ((L[j] - L[i]) / d) if N[j] == 1 else 0
152
		return P
153
154
	def moveSelect(self, pb, i):
155
		r"""TODO.
156
157
		Args:
158
			pb:
159
			i:
160
161
		Returns:
162
163
		"""
164
		r, b_l, b_u = self.rand(), 0, 0
165
		for j in range(self.NP):
166
			b_l, b_u = b_u, b_u + pb[i]
167
			if b_l < r < b_u: return j
168
		return self.randint(self.NP)
169
170
	def calcLuciferin(self, L, GS_f):
171
		r"""TODO.
172
173
		Args:
174
			L:
175
			GS_f:
176
177
		Returns:
178
179
		"""
180
		return (1 - self.rho) * L + self.gamma * GS_f
181
182
	def rangeUpdate(self, R, N, rs):
183
		r"""TODO.
184
185
		Args:
186
			R:
187
			N:
188
			rs:
189
190
		Returns:
191
192
		"""
193
		return R + self.beta * (self.nt - sum(N))
194
195
	def initPopulation(self, task):
196
		r"""Initialize population.
197
198
		Args:
199
			task (Task): Optimization task.
200
201
		Returns:
202
			Tuple[numpy.ndarray, numpy.ndarray[float], Dict[str, Any]]:
203
				1. Initialized population of glowwarms.
204
				2. Initialized populations function/fitness values.
205
				3. Additional arguments:
206
					* L (numpy.ndarray): TODO.
207
					* R (numpy.ndarray): TODO.
208
					* rs (numpy.ndarray): TODO.
209
		"""
210
		GS, GS_f, d = Algorithm.initPopulation(self, task)
211
		rs = euclidean(full(task.D, 0), task.bRange)
212
		L, R = full(self.NP, self.l0), full(self.NP, rs)
213
		d.update({'L': L, 'R': R, 'rs': rs})
214
		return GS, GS_f, d
215
216
	def runIteration(self, task, GS, GS_f, xb, fxb, L, R, rs, **dparams):
217
		r"""Core function of GlowwormSwarmOptimization algorithm.
218
219
		Args:
220
			task (Task): Optimization taks.
221
			GS (numpy.ndarray): Current population.
222
			GS_f (numpy.ndarray): Current populations fitness/function values.
223
			xb (numpy.ndarray): Global best individual.
224
			fxb (float): Global best individuals function/fitness value.
225
			L (numpy.ndarray):
226
			R (numpy.ndarray):
227
			rs (numpy.ndarray):
228
			**dparams Dict[str, Any]: Additional arguments.
229
230
		Returns:
231
			Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, float, Dict[str, Any]]:
232
				1. Initialized population of glowwarms.
233
				2. Initialized populations function/fitness values.
234
				3. New global best solution
235
				4. New global best sloutions fitness/objective value.
236
				5. Additional arguments:
237
					* L (numpy.ndarray): TODO.
238
					* R (numpy.ndarray): TODO.
239
					* rs (numpy.ndarray): TODO.
240
		"""
241
		GSo, Ro = copy(GS), copy(R)
242
		L = self.calcLuciferin(L, GS_f)
243
		N = [self.getNeighbors(i, Ro[i], GSo, L) for i in range(self.NP)]
244
		P = [self.probabilityes(i, N[i], L) for i in range(self.NP)]
245
		j = [self.moveSelect(P[i], i) for i in range(self.NP)]
246
		for i in range(self.NP): GS[i] = task.repair(GSo[i] + self.s * ((GSo[j[i]] - GSo[i]) / (self.Distance(GSo[j[i]], GSo[i]) + 1e-31)), rnd=self.Rand)
247
		for i in range(self.NP): R[i] = max(0, min(rs, self.rangeUpdate(Ro[i], N[i], rs)))
248
		GS_f = apply_along_axis(task.eval, 1, GS)
249
		xb, fxb = self.getBest(GS, GS_f, xb, fxb)
250
		return GS, GS_f, xb, fxb, {'L': L, 'R': R, 'rs': rs}
251
252
class GlowwormSwarmOptimizationV1(GlowwormSwarmOptimization):
253
	r"""Implementation of glowwarm swarm optimization.
254
255
	Algorithm:
256
		Glowwarm Swarm Optimization Algorithm
257
258
	Date:
259
		2018
260
261
	Authors:
262
		Klemen Berkovič
263
264
	License:
265
		MIT
266
267
	Reference URL:
268
		https://www.springer.com/gp/book/9783319515946
269
270
	Reference paper:
271
		Kaipa, Krishnanand N., and Debasish Ghose. Glowworm swarm optimization: theory, algorithms, and applications. Vol. 698. Springer, 2017.
272
273
	Attributes:
274
		Name (List[str]): List of strings representing algorithm names.
275
		alpha (float): --
276
277
	See Also:
278
		* :class:`NiaPy.algorithms.basic.GlowwormSwarmOptimization`
279
	"""
280
	Name = ['GlowwormSwarmOptimizationV1', 'GSOv1']
281
282
	@staticmethod
283
	def algorithmInfo():
284
		r"""Get basic information of algorithm.
285
286
		Returns:
287
			str: Basic information.
288
		"""
289
		return r"""Kaipa, Krishnanand N., and Debasish Ghose. Glowworm swarm optimization: theory, algorithms, and applications. Vol. 698. Springer, 2017."""
290
291
	def setParameters(self, **kwargs):
292
		r"""Set default parameters of the algorithm.
293
294
		Args:
295
			**kwargs (dict): Additional arguments.
296
		"""
297
		GlowwormSwarmOptimization.setParameters(self, **kwargs)
298
299
	def calcLuciferin(self, L, GS_f):
300
		r"""TODO.
301
302
		Args:
303
			L:
304
			GS_f:
305
306
		Returns:
307
308
		"""
309
		return fmax(0, (1 - self.rho) * L + self.gamma * GS_f)
310
311
	def rangeUpdate(self, R, N, rs):
312
		r"""TODO.
313
314
		Args:
315
			R:
316
			N:
317
			rs:
318
319
		Returns:
320
321
		"""
322
		return rs / (1 + self.beta * (sum(N) / (pi * rs ** 2)))
323
324
class GlowwormSwarmOptimizationV2(GlowwormSwarmOptimization):
325
	r"""Implementation of glowwarm swarm optimization.
326
327
	Algorithm:
328
		Glowwarm Swarm Optimization Algorithm
329
330
	Date:
331
		2018
332
333
	Authors:
334
		Klemen Berkovič
335
336
	License:
337
		MIT
338
339
	Reference URL:
340
		https://www.springer.com/gp/book/9783319515946
341
342
	Reference paper:
343
		Kaipa, Krishnanand N., and Debasish Ghose. Glowworm swarm optimization: theory, algorithms, and applications. Vol. 698. Springer, 2017.
344
345
	Attributes:
346
		Name (List[str]): List of strings representing algorithm names.
347
		alpha (float): --
348
349
	See Also:
350
		* :class:`NiaPy.algorithms.basic.GlowwormSwarmOptimization`
351
	"""
352
	Name = ['GlowwormSwarmOptimizationV2', 'GSOv2']
353
354
	@staticmethod
355
	def algorithmInfo():
356
		r"""Get basic information of algorithm.
357
358
		Returns:
359
			str: Basic information.
360
		"""
361
		return r"""Kaipa, Krishnanand N., and Debasish Ghose. Glowworm swarm optimization: theory, algorithms, and applications. Vol. 698. Springer, 2017."""
362
363
	def setParameters(self, alpha=0.2, **kwargs):
364
		r"""Set core parameters for GlowwormSwarmOptimizationV2 algorithm.
365
366
		Args:
367
			alpha (Optional[float]): --
368
			**kwargs (Dict[str, Any]): Additional arguments.
369
370
		See Also:
371
			* :func:`NiaPy.algorithms.basic.GlowwormSwarmOptimization.setParameters`
372
		"""
373
		GlowwormSwarmOptimization.setParameters(self, **kwargs)
374
		self.alpha = alpha
375
376
	def rangeUpdate(self, P, N, rs):
377
		r"""TODO.
378
379
		Args:
380
			P:
381
			N:
382
			rs:
383
384
		Returns:
385
			float: TODO
386
		"""
387
		return self.alpha + (rs - self.alpha) / (1 + self.beta * sum(N))
388
389
class GlowwormSwarmOptimizationV3(GlowwormSwarmOptimization):
390
	r"""Implementation of glowwarm swarm optimization.
391
392
	Algorithm:
393
		Glowwarm Swarm Optimization Algorithm
394
395
	Date:
396
		2018
397
398
	Authors:
399
		Klemen Berkovič
400
401
	License:
402
		MIT
403
404
	Reference URL:
405
		https://www.springer.com/gp/book/9783319515946
406
407
	Reference paper:
408
		Kaipa, Krishnanand N., and Debasish Ghose. Glowworm swarm optimization: theory, algorithms, and applications. Vol. 698. Springer, 2017.
409
410
	Attributes:
411
		Name (List[str]): List of strings representing algorithm names.
412
		beta1 (float): --
413
414
	See Also:
415
		* :class:`NiaPy.algorithms.basic.GlowwormSwarmOptimization`
416
	"""
417
	Name = ['GlowwormSwarmOptimizationV3', 'GSOv3']
418
419
	@staticmethod
420
	def algorithmInfo():
421
		r"""Get basic information of algorithm.
422
423
		Returns:
424
			str: Basic information.
425
		"""
426
		return r"""Kaipa, Krishnanand N., and Debasish Ghose. Glowworm swarm optimization: theory, algorithms, and applications. Vol. 698. Springer, 2017."""
427
428
	def setParameters(self, beta1=0.2, **kwargs):
429
		r"""Set core parameters for GlowwormSwarmOptimizationV3 algorithm.
430
431
		Args:
432
			beta1 (Optional[float]): --
433
			**kwargs (Dict[str, Any]): Additional arguments.
434
435
		See Also:
436
			* :func:`NiaPy.algorithms.basic.GlowwormSwarmOptimization.setParameters`
437
		"""
438
		GlowwormSwarmOptimization.setParameters(self, **kwargs)
439
		self.beta1 = beta1
440
441
	def rangeUpdate(self, R, N, rs):
442
		r"""TODO.
443
444
		Args:
445
			R:
446
			N:
447
			rs:
448
449
		Returns:
450
451
		"""
452
		return R + (self.beta * sum(N)) if sum(N) < self.nt else (-self.beta1 * sum(N))
453
454
# vim: tabstop=3 noexpandtab shiftwidth=3 softtabstop=3
455