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

MutatedCenterParticleSwarmOptimization.algorithmInfo()   A

Complexity

Conditions 1

Size

Total Lines 11
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nop 0
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
# encoding=utf8
2
# pylint: disable=mixed-indentation, multiple-statements, arguments-differ, unbalanced-tuple-unpacking, expression-not-assigned, line-too-long, unused-argument, no-self-use, too-many-lines, no-member, consider-using-enumerate, bad-continuation
3
import logging
4
5
import numpy as np
6
7
from NiaPy.algorithms.algorithm import Algorithm
8
from NiaPy.util import fullArray
9
from NiaPy.util.utility import reflectRepair
10
11
logging.basicConfig()
12
logger = logging.getLogger('NiaPy.algorithms.basic')
13
logger.setLevel('INFO')
14
15
__all__ = ['ParticleSwarmAlgorithm', 'ParticleSwarmOptimization', 'OppositionVelocityClampingParticleSwarmOptimization', 'CenterParticleSwarmOptimization', 'MutatedParticleSwarmOptimization', 'MutatedCenterParticleSwarmOptimization', 'MutatedCenterUnifiedParticleSwarmOptimization', 'ComprehensiveLearningParticleSwarmOptimizer']
16
17
class ParticleSwarmAlgorithm(Algorithm):
18
	r"""Implementation of Particle Swarm Optimization algorithm.
19
20
	Algorithm:
21
		Particle Swarm Optimization algorithm
22
23
	Date:
24
		2018
25
26
	Authors:
27
		Lucija Brezočnik, Grega Vrbančič, Iztok Fister Jr. and Klemen Berkovič
28
29
	License:
30
		MIT
31
32
	Reference paper:
33
		TODO: Find the right paper
34
35
	Attributes:
36
		Name (List[str]): List of strings representing algorithm names
37
		C1 (float): Cognitive component.
38
		C2 (float): Social component.
39
		w (Union[float, numpy.ndarray[float]]): Inertial weight.
40
		vMin (Union[float, numpy.ndarray[float]]): Minimal velocity.
41
		vMax (Union[float, numpy.ndarray[float]]): Maximal velocity.
42
		Repair (Callable[[numpy.ndarray, numpy.ndarray, numpy.ndarray, mtrnd.RandomState], numpy.ndarray]): Repair method for velocity.
43
44
	See Also:
45
		* :class:`NiaPy.algorithms.Algorithm`
46
	"""
47
	Name = ['WeightedVelocityClampingParticleSwarmAlgorithm', 'WVCPSO']
48
49
	@staticmethod
50
	def algorithmInfo():
51
		r"""Get basic information of algorithm.
52
53
		Returns:
54
			str: Basic information of algorithm.
55
56
		See Also:
57
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
58
		"""
59
		return r"""TODO find one"""
60
61
	@staticmethod
62
	def typeParameters():
63
		r"""Get dictionary with functions for checking values of parameters.
64
65
		Returns:
66
			Dict[str, Callable[[Union[int, float]], bool]]:
67
			* NP (Callable[[int], bool])
68
			* C1 (Callable[[Union[int, float]], bool])
69
			* C2 (Callable[[Union[int, float]], bool])
70
			* w (Callable[[float], bool])
71
			* vMin (Callable[[Union[int, float]], bool])
72
			* vMax (Callable[[Union[int, float], bool])
73
		"""
74
		d = Algorithm.typeParameters()
75
		d.update({
76
			'C1': lambda x: isinstance(x, (int, float)) and x >= 0,
77
			'C2': lambda x: isinstance(x, (int, float)) and x >= 0,
78
			'w': lambda x: isinstance(x, float) and x >= 0,
79
			'vMin': lambda x: isinstance(x, (int, float)),
80
			'vMax': lambda x: isinstance(x, (int, float))
81
		})
82
		return d
83
84
	def setParameters(self, NP=25, C1=2.0, C2=2.0, w=0.7, vMin=-1.5, vMax=1.5, Repair=reflectRepair, **ukwargs):
85
		r"""Set Particle Swarm Algorithm main parameters.
86
87
		Args:
88
			NP (int): Population size
89
			C1 (float): Cognitive component.
90
			C2 (float): Social component.
91
			w (Union[float, numpy.ndarray]): Inertial weight.
92
			vMin (Union[float, numpy.ndarray]): Minimal velocity.
93
			vMax (Union[float, numpy.ndarray]): Maximal velocity.
94
			Repair (Callable[[np.ndarray, np.ndarray, np.ndarray, dict], np.ndarray]): Repair method for velocity.
95
			**ukwargs: Additional arguments
96
97
		See Also:
98
			* :func:`NiaPy.algorithms.Algorithm.setParameters`
99
		"""
100
		Algorithm.setParameters(self, NP=NP, **ukwargs)
101
		self.C1, self.C2, self.w, self.vMin, self.vMax, self.Repair = C1, C2, w, vMin, vMax, Repair
102
103
	def getParameters(self):
104
		r"""Get value of parametrs for this instance of algorithm.
105
106
		Returns:
107
			Dict[str, Union[int, float, np.ndarray]]: Dictionari which has parameters maped to values.
108
109
		See Also:
110
			* :func:`NiaPy.algorithms.Algorithm.getParameters`
111
		"""
112
		d = Algorithm.getParameters(self)
113
		d.update({
114
			'C1': self.C1,
115
			'C2': self.C2,
116
			'w': self.w,
117
			'vMin': self.vMin,
118
			'vMax': self.vMax
119
		})
120
		return d
121
122
	def init(self, task):
123
		r"""Initialize dynamic arguments of Particle Swarm Optimization algorithm.
124
125
		Args:
126
			task (Task): Optimization task.
127
128
		Returns:
129
			Dict[str, Union[float, np.ndarray]]:
130
				* w (numpy.ndarray): Inertial weight.
131
				* vMin (numpy.ndarray): Mininal velocity.
132
				* vMax (numpy.ndarray): Maximal velocity.
133
				* V (numpy.ndarray): Initial velocity of particle.
134
		"""
135
		return {
136
			'w': fullArray(self.w, task.D),
137
			'vMin': fullArray(self.vMin, task.D),
138
			'vMax': fullArray(self.vMax, task.D),
139
			'V': np.full([self.NP, task.D], 0.0)
140
		}
141
142
	def initPopulation(self, task):
143
		r"""Initialize population and dynamic arguments of the Particle Swarm Optimization algorithm.
144
145
		Args:
146
			task: Optimization task.
147
148
		Returns:
149
			Tuple[np.ndarray, np.ndarray, dict]:
150
			1. Initial population.
151
			2. Initial population fitness/function values.
152
			3. Additional arguments:
153
				* popb (numpy.ndarray): particles best population.
154
				* fpopb (numpy.ndarray[float]): particles best positions function/fitness value.
155
				* w (numpy.ndarray): Inertial weight.
156
				* vMin (numpy.ndarray): Minimal velocity.
157
				* vMax (numpy.ndarray): Maximal velocity.
158
				* V (numpy.ndarray): Initial velocity of particle.
159
160
		See Also:
161
			* :func:`NiaPy.algorithms.Algorithm.initPopulation`
162
		"""
163
		pop, fpop, d = Algorithm.initPopulation(self, task)
164
		d.update(self.init(task))
165
		d.update({'popb': pop.copy(), 'fpopb': fpop.copy()})
166
		return pop, fpop, d
167
168 View Code Duplication
	def updateVelocity(self, V, p, pb, gb, w, vMin, vMax, task, **kwargs):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
169
		r"""Update particle velocity.
170
171
		Args:
172
			V (numpy.ndarray): Current velocity of particle.
173
			p (numpy.ndarray): Current position of particle.
174
			pb (numpy.ndarray): Personal best position of particle.
175
			gb (numpy.ndarray): Global best position of particle.
176
			w (numpy.ndarray): Weights for velocity adjustment.
177
			vMin (numpy.ndarray): Minimal velocity allowed.
178
			vMax (numpy.ndarray): Maximal velocity allowed.
179
			task (Task): Optimization task.
180
			kwargs: Additional arguments.
181
182
		Returns:
183
			numpy.ndarray: Updated velocity of particle.
184
		"""
185
		return self.Repair(w * V + self.C1 * self.rand(task.D) * (pb - p) + self.C2 * self.rand(task.D) * (gb - p), vMin, vMax)
186
187
	def runIteration(self, task, pop, fpop, xb, fxb, popb, fpopb, w, vMin, vMax, V, **dparams):
188
		r"""Core function of Particle Swarm Optimization algorithm.
189
190
		Args:
191
			task (Task): Optimization task.
192
			pop (numpy.ndarray): Current populations.
193
			fpop (numpy.ndarray): Current population fitness/function values.
194
			xb (numpy.ndarray): Current best particle.
195
			fxb (float): Current best particle fitness/function value.
196
			popb (numpy.ndarray): Particles best position.
197
			fpopb (numpy.ndarray): Particles best positions fitness/function values.
198
			w (numpy.ndarray): Inertial weights.
199
			vMin (numpy.ndarray): Minimal velocity.
200
			vMax (numpy.ndarray): Maximal velocity.
201
			V (numpy.ndarray): Velocity of particles.
202
			**dparams: Additional function arguments.
203
204
		Returns:
205
			Tuple[np.ndarray, np.ndarray, np.ndarray, float, dict]:
206
			1. New population.
207
			2. New population fitness/function values.
208
			3. New global best position.
209
			4. New global best positions function/fitness value.
210
			5. Additional arguments:
211
				* popb (numpy.ndarray): Particles best population.
212
				* fpopb (numpy.ndarray[float]): Particles best positions function/fitness value.
213
				* w (numpy.ndarray): Inertial weight.
214
				* vMin (numpy.ndarray): Minimal velocity.
215
				* vMax (numpy.ndarray): Maximal velocity.
216
				* V (numpy.ndarray): Initial velocity of particle.
217
218
		See Also:
219
			* :class:`NiaPy.algorithms.algorithm.runIteration`
220
		"""
221
		for i in range(len(pop)):
222
			V[i] = self.updateVelocity(V[i], pop[i], popb[i], xb, w, vMin, vMax, task)
223
			pop[i] = task.repair(pop[i] + V[i], rnd=self.Rand)
224
			fpop[i] = task.eval(pop[i])
225
			if fpop[i] < fpopb[i]:
226
				popb[i], fpopb[i] = pop[i].copy(), fpop[i]
227
				if fpop[i] < fxb: xb, fxb = pop[i].copy(), fpop[i]
228
		return pop, fpop, xb, fxb, {'popb': popb, 'fpopb': fpopb, 'w': w, 'vMin': vMin, 'vMax': vMax, 'V': V}
229
230
class ParticleSwarmOptimization(ParticleSwarmAlgorithm):
231
	r"""Implementation of Particle Swarm Optimization algorithm.
232
233
	Algorithm:
234
		Particle Swarm Optimization algorithm
235
236
	Date:
237
		2018
238
239
	Authors:
240
		Lucija Brezočnik, Grega Vrbančič, Iztok Fister Jr. and Klemen Berkovič
241
242
	License:
243
		MIT
244
245
	Reference paper:
246
		Kennedy, J. and Eberhart, R. "Particle Swarm Optimization". Proceedings of IEEE International Conference on Neural Networks. IV. pp. 1942--1948, 1995.
247
248
	Attributes:
249
		Name (List[str]): List of strings representing algorithm names
250
		C1 (float): Cognitive component.
251
		C2 (float): Social component.
252
		Repair (Callable[[numpy.ndarray, numpy.ndarray, numpy.ndarray, mtrnd.RandomState], numpy.ndarray]): Repair method for velocity.
253
254
	See Also:
255
		* :class:`NiaPy.algorithms.basic.WeightedVelocityClampingParticleSwarmAlgorithm`
256
	"""
257
	Name = ['ParticleSwarmAlgorithm', 'PSO']
258
259
	@staticmethod
260
	def algorithmInfo():
261
		r"""Get basic information of algorithm.
262
263
		Returns:
264
			str: Basic information of algorithm.
265
266
		See Also:
267
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
268
		"""
269
		return r"""Kennedy, J. and Eberhart, R. "Particle Swarm Optimization". Proceedings of IEEE International Conference on Neural Networks. IV. pp. 1942--1948, 1995."""
270
271
	@staticmethod
272
	def typeParameters():
273
		r"""Get dictionary with functions for checking values of parameters.
274
275
		Returns:
276
			Dict[str, Callable[[Union[int, float]], bool]]:
277
			* NP: Population size.
278
			* C1: Cognitive component.
279
			* C2: Social component.
280
		"""
281
		d = ParticleSwarmAlgorithm.typeParameters()
282
		d.pop('w', None), d.pop('vMin', None), d.pop('vMax', None)
283
		return d
284
285
	def setParameters(self, **ukwargs):
286
		r"""Set core parameters of algorithm.
287
288
		Args:
289
			**ukwargs (Dict[str, Any]): Additional parameters.
290
291
		See Also:
292
			* :func:`NiaPy.algorithms.basic.WeightedVelocityClampingParticleSwarmAlgorithm.setParameters`
293
		"""
294
		ukwargs.pop('w', None), ukwargs.pop('vMin', None), ukwargs.pop('vMax', None)
295
		ParticleSwarmAlgorithm.setParameters(self, w=1, vMin=-np.inf, vMax=np.inf, **ukwargs)
296
297
	def getParameters(self):
298
		r"""Get value of parametrs for this instance of algorithm.
299
300
		Returns:
301
			Dict[str, Union[int, float, np.ndarray]]: Dictionari which has parameters maped to values.
302
303
		See Also:
304
			* :func:`NiaPy.algorithms.basic.ParticleSwarmAlgorithm.getParameters`
305
		"""
306
		d = ParticleSwarmAlgorithm.getParameters(self)
307
		d.pop('w', None), d.pop('vMin', None), d.pop('vMax', None)
308
		return d
309
310
class OppositionVelocityClampingParticleSwarmOptimization(ParticleSwarmAlgorithm):
311
	r"""Implementation of Opposition-Based Particle Swarm Optimization with Velocity Clamping.
312
313
	Algorithm:
314
		Opposition-Based Particle Swarm Optimization with Velocity Clamping
315
316
	Date:
317
		2019
318
319
	Authors:
320
		Klemen Berkovič
321
322
	License:
323
		MIT
324
325
	Reference paper:
326
		Shahzad, Farrukh, et al. "Opposition-based particle swarm optimization with velocity clamping (OVCPSO)." Advances in Computational Intelligence. Springer, Berlin, Heidelberg, 2009. 339-348
327
328
	Attributes:
329
		p0: Probability of opposite learning phase.
330
		w_min: Minimum inertial weight.
331
		w_max: Maximum inertial weight.
332
		sigma: Velocity scaling factor.
333
334
	See Also:
335
		* :class:`NiaPy.algorithms.basic.ParticleSwarmAlgorithm`
336
	"""
337
	Name = ['OppositionVelocityClampingParticleSwarmOptimization', 'OVCPSO']
338
339
	@staticmethod
340
	def algorithmInfo():
341
		r"""Get basic information of algorithm.
342
343
		Returns:
344
			str: Basic information of algorithm.
345
346
		See Also:
347
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
348
		"""
349
		return r"""Shahzad, Farrukh, et al. "Opposition-based particle swarm optimization with velocity clamping (OVCPSO)." Advances in Computational Intelligence. Springer, Berlin, Heidelberg, 2009. 339-348"""
350
351
	def setParameters(self, p0=.3, w_min=.4, w_max=.9, sigma=.1, C1=1.49612, C2=1.49612, **kwargs):
352
		r"""Set core algorithm parameters.
353
354
		Args:
355
			p0 (float): Probability of running Opposite learning.
356
			w_min (numpy.ndarray): Minimal value of weights.
357
			w_max (numpy.ndarray): Maximum value of weights.
358
			sigma (numpy.ndarray): Velocity range factor.
359
			**kwargs: Additional arguments.
360
361
		See Also:
362
			* :func:`NiaPy.algorithm.basic.ParticleSwarmAlgorithm.setParameters`
363
		"""
364
		kwargs.pop('w', None)
365
		ParticleSwarmAlgorithm.setParameters(self, w=w_max, C1=C1, C2=C2, **kwargs)
366
		self.p0, self.w_min, self.w_max, self.sigma = p0, w_min, w_max, sigma
367
368
	def getParameters(self):
369
		r"""Get value of parametrs for this instance of algorithm.
370
371
		Returns:
372
			Dict[str, Union[int, float, np.ndarray]]: Dictionari which has parameters maped to values.
373
374
		See Also:
375
			* :func:`NiaPy.algorithms.basic.ParticleSwarmAlgorithm.getParameters`
376
		"""
377
		d = ParticleSwarmAlgorithm.getParameters(self)
378
		d.pop('vMin', None), d.pop('vMax', None)
379
		d.update({
380
			'p0': self.p0, 'w_min': self.w_min, 'w_max': self.w_max, 'sigma': self.sigma
381
		})
382
		return d
383
384
	def oppositeLearning(self, S_l, S_h, pop, fpop, task):
385
		r"""Run opposite learning phase.
386
387
		Args:
388
			S_l (numpy.ndarray): Lower limit of opposite particles.
389
			S_h (numpy.ndarray): Upper limit of opposite particles.
390
			pop (numpy.ndarray): Current populations positions.
391
			fpop (numpy.ndarray): Current populations functions/fitness values.
392
			task (Task): Optimization task.
393
394
		Returns:
395
			Tuple[np.ndarray, np.ndarray, np.ndarray, float]:
396
			1. New particles position
397
			2. New particles function/fitness values
398
			3. New best position of opposite learning phase
399
			4. new best function/fitness value of opposite learning phase
400
		"""
401
		S_r = S_l + S_h
402
		S = np.asarray([S_r - e for e in pop])
403
		S_f = np.asarray([task.eval(e) for e in S])
404
		S, S_f = np.concatenate([pop, S]), np.concatenate([fpop, S_f])
405
		sinds = np.argsort(S_f)
406
		return S[sinds[:len(pop)]], S_f[sinds[:len(pop)]], S[sinds[0]], S_f[sinds[0]]
407
408
	def initPopulation(self, task):
409
		r"""Init starting population and dynamic parameters.
410
411
		Args:
412
			task (Task): Optimization task.
413
414
		Returns:
415
			Tuple[np.ndarray, np.ndarray, dict]:
416
			1. Initialized population.
417
			2. Initialized populations function/fitness values.
418
			3. Additional arguments:
419
				* popb (numpy.ndarray): particles best population.
420
				* fpopb (numpy.ndarray[float]): particles best positions function/fitness value.
421
				* vMin (numpy.ndarray): Minimal velocity.
422
				* vMax (numpy.ndarray): Maximal velocity.
423
				* V (numpy.ndarray): Initial velocity of particle.
424
				* S_u (numpy.ndarray): Upper bound for opposite learning.
425
				* S_l (numpy.ndarray): Lower bound for opposite learning.
426
		"""
427
		pop, fpop, d = ParticleSwarmAlgorithm.initPopulation(self, task)
428
		S_l, S_h = task.Lower, task.Upper
429
		pop, fpop, _, _ = self.oppositeLearning(S_l, S_h, pop, fpop, task)
430
		pb_inds = np.where(fpop < d['fpopb'])
431
		d['popb'][pb_inds], d['fpopb'][pb_inds] = pop[pb_inds], fpop[pb_inds]
432
		d['vMin'], d['vMax'] = self.sigma * (task.Upper - task.Lower), self.sigma * (task.Lower - task.Upper)
433
		d.update({'S_l': S_l, 'S_h': S_h})
434
		return pop, fpop, d
435
436
	def runIteration(self, task, pop, fpop, xb, fxb, popb, fpopb, vMin, vMax, V, S_l, S_h, **dparams):
437
		r"""Core function of Opposite-based Particle Swarm Optimization with velocity clamping algorithm.
438
439
		Args:
440
			task (Task): Optimization task.
441
			pop (numpy.ndarray): Current population.
442
			fpop (numpy.ndarray): Current populations function/fitness values.
443
			xb (numpy.ndarray): Current global best position.
444
			fxb (float): Current global best positions function/fitness value.
445
			popb (numpy.ndarray): Personal best position.
446
			fpopb (numpy.ndarray): Personal best positions function/fitness values.
447
			vMin (numpy.ndarray): Minimal allowed velocity.
448
			vMax (numpy.ndarray): Maximal allowed velocity.
449
			V (numpy.ndarray): Populations velocity.
450
			S_l (numpy.ndarray): Lower bound of opposite learning.
451
			S_h (numpy.ndarray): Upper bound of opposite learning.
452
			**dparams: Additional arguments.
453
454
		Returns:
455
			Tuple[np.ndarray, np.ndarray, np.ndarray, float, dict]:
456
			1. New population.
457
			2. New populations function/fitness values.
458
			3. New global best position.
459
			4. New global best positions function/fitness value.
460
			5. Additional arguments:
461
				* popb: particles best population.
462
				* fpopb: particles best positions function/fitness value.
463
				* vMin: Minimal velocity.
464
				* vMax: Maximal velocity.
465
				* V: Initial velocity of particle.
466
				* S_u: Upper bound for opposite learning.
467
				* S_l: Lower bound for opposite learning.
468
		"""
469
		if self.rand() < self.p0:
470
			pop, fpop, nb, fnb = self.oppositeLearning(S_l, S_h, pop, fpop, task)
471
			pb_inds = np.where(fpop < fpopb)
472
			popb[pb_inds], fpopb[pb_inds] = pop[pb_inds], fpop[pb_inds]
473
			if fnb < fxb: xb, fxb = nb.copy(), fnb
474
		else:
475
			w = self.w_max - ((self.w_max - self.w_min) / task.nGEN) * task.Iters
476
			for i in range(len(pop)):
477
				V[i] = self.updateVelocity(V[i], pop[i], popb[i], xb, w, vMin, vMax, task)
478
				pop[i] = task.repair(pop[i] + V[i], rnd=self.Rand)
479
				fpop[i] = task.eval(pop[i])
480
				if fpop[i] < fpopb[i]:
481
					popb[i], fpopb[i] = pop[i].copy(), fpop[i]
482
					if fpop[i] < fxb: xb, fxb = pop[i].copy(), fpop[i]
483
			vMin, vMax = self.sigma * np.min(pop, axis=0), self.sigma * np.max(pop, axis=0)
484
		return pop, fpop, xb, fxb, {'popb': popb, 'fpopb': fpopb, 'vMin': vMin, 'vMax': vMax, 'V': V, 'S_l': S_l, 'S_h': S_h}
485
486
class CenterParticleSwarmOptimization(ParticleSwarmAlgorithm):
487
	r"""Implementation of Center Particle Swarm Optimization.
488
489
	Algorithm:
490
		Center Particle Swarm Optimization
491
492
	Date:
493
		2019
494
495
	Authors:
496
		Klemen Berkovič
497
498
	License:
499
		MIT
500
501
	Reference paper:
502
		H.-C. Tsai, Predicting strengths of concrete-type specimens using hybrid multilayer perceptrons with center-Unified particle swarm optimization, Adv. Eng. Softw. 37 (2010) 1104–1112.
503
504
	See Also:
505
		* :class:`NiaPy.algorithms.basic.WeightedVelocityClampingParticleSwarmAlgorithm`
506
	"""
507
	Name = ['CenterParticleSwarmOptimization', 'CPSO']
508
509
	@staticmethod
510
	def algorithmInfo():
511
		r"""Get basic information of algorithm.
512
513
		Returns:
514
			str: Basic information of algorithm.
515
516
		See Also:
517
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
518
		"""
519
		return r"""H.-C. Tsai, Predicting strengths of concrete-type specimens using hybrid multilayer perceptrons with center-Unified particle swarm optimization, Adv. Eng. Softw. 37 (2010) 1104–1112."""
520
521
	def setParameters(self, **kwargs):
522
		r"""Set core algorithm parameters.
523
524
		Args:
525
			**kwargs: Additional arguments.
526
527
		See Also:
528
			:func:`NiaPy.algorithm.basic.WeightedVelocityClampingParticleSwarmAlgorithm.setParameters`
529
		"""
530
		kwargs.pop('vMin', None), kwargs.pop('vMax', None)
531
		ParticleSwarmAlgorithm.setParameters(self, vMin=-np.inf, vMax=np.inf, **kwargs)
532
533
	def getParameters(self):
534
		r"""Get value of parametrs for this instance of algorithm.
535
536
		Returns:
537
			Dict[str, Union[int, float, np.ndarray]]: Dictionari which has parameters maped to values.
538
539
		See Also:
540
			* :func:`NiaPy.algorithms.basic.ParticleSwarmAlgorithm.getParameters`
541
		"""
542
		d = ParticleSwarmAlgorithm.getParameters(self)
543
		d.pop('vMin', None), d.pop('vMax', None)
544
		return d
545
546
	def runIteration(self, task, pop, fpop, xb, fxb, **dparams):
547
		r"""Core function of algorithm.
548
549
		Args:
550
			task (Task): Optimization task.
551
			pop (numpy.ndarray): Current population of particles.
552
			fpop (numpy.ndarray): Current particles function/fitness values.
553
			xb (numpy.ndarray): Current global best particle.
554
			fxb (numpy.ndarray): Current global best particles function/fitness value.
555
			**dparams: Additional arguments.
556
557
		Returns:
558
			Tuple[np.ndarray, np.ndarray, np.ndarray, float, dict]:
559
			1. New population of particles.
560
			2. New populations function/fitness values.
561
			3. New global best particle.
562
			4. New global best particle function/fitness value.
563
			5. Additional arguments.
564
565
		See Also:
566
			* :func:`NiaPy.algorithm.basic.WeightedVelocityClampingParticleSwarmAlgorithm.runIteration`
567
		"""
568
		pop, fpop, xb, fxb, d = ParticleSwarmAlgorithm.runIteration(self, task, pop, fpop, xb, fxb, **dparams)
569
		c = np.sum(pop, axis=0) / len(pop)
570
		fc = task.eval(c)
571
		if fc <= fxb: xb, fxb = c, fc
572
		return pop, fpop, xb, fxb, d
573
574
class MutatedParticleSwarmOptimization(ParticleSwarmAlgorithm):
575
	r"""Implementation of Mutated Particle Swarm Optimization.
576
577
	Algorithm:
578
		Mutated Particle Swarm Optimization
579
580
	Date:
581
		2019
582
583
	Authors:
584
		Klemen Berkovič
585
586
	License:
587
		MIT
588
589
	Reference paper:
590
		H. Wang, C. Li, Y. Liu, S. Zeng, A hybrid particle swarm algorithm with cauchy mutation, Proceedings of the 2007 IEEE Swarm Intelligence Symposium (2007) 356–360.
591
592
	Attributes:
593
		nmutt (int): Number of mutations of global best particle.
594
595
	See Also:
596
		* :class:`NiaPy.algorithms.basic.WeightedVelocityClampingParticleSwarmAlgorithm`
597
	"""
598
	Name = ['MutatedParticleSwarmOptimization', 'MPSO']
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"""H. Wang, C. Li, Y. Liu, S. Zeng, A hybrid particle swarm algorithm with cauchy mutation, Proceedings of the 2007 IEEE Swarm Intelligence Symposium (2007) 356–360."""
611
612
	def setParameters(self, nmutt=10, **kwargs):
613
		r"""Set core algorithm parameters.
614
615
		Args:
616
			nmutt (int): Number of mutations of global best particle.
617
			**kwargs: Additional arguments.
618
619
		See Also:
620
			:func:`NiaPy.algorithm.basic.WeightedVelocityClampingParticleSwarmAlgorithm.setParameters`
621
		"""
622
		kwargs.pop('vMin', None), kwargs.pop('vMax', None)
623
		ParticleSwarmAlgorithm.setParameters(self, vMin=-np.inf, vMax=np.inf, **kwargs)
624
		self.nmutt = nmutt
625
626
	def getParameters(self):
627
		r"""Get value of parametrs for this instance of algorithm.
628
629
		Returns:
630
			Dict[str, Union[int, float, np.ndarray]]: Dictionari which has parameters maped to values.
631
632
		See Also:
633
			* :func:`NiaPy.algorithms.basic.ParticleSwarmAlgorithm.getParameters`
634
		"""
635
		d = ParticleSwarmAlgorithm.getParameters(self)
636
		d.pop('vMin', None), d.pop('vMax', None)
637
		d.update({'nmutt': self.nmutt})
638
		return d
639
640 View Code Duplication
	def runIteration(self, task, pop, fpop, xb, fxb, **dparams):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
641
		r"""Core function of algorithm.
642
643
		Args:
644
			task (Task): Optimization task.
645
			pop (numpy.ndarray): Current population of particles.
646
			fpop (numpy.ndarray): Current particles function/fitness values.
647
			xb (numpy.ndarray): Current global best particle.
648
			fxb (float): Current global best particles function/fitness value.
649
			**dparams: Additional arguments.
650
651
		Returns:
652
			Tuple[np.ndarray, np.ndarray, np.ndarray, float, dict]:
653
			1. New population of particles.
654
			2. New populations function/fitness values.
655
			3. New global best particle.
656
			4. New global best particle function/fitness value.
657
			5. Additional arguments.
658
659
		See Also:
660
			* :func:`NiaPy.algorithm.basic.WeightedVelocityClampingParticleSwarmAlgorithm.runIteration`
661
		"""
662
		pop, fpop, xb, fxb, d = ParticleSwarmAlgorithm.runIteration(self, task, pop, fpop, xb, fxb, **dparams)
663
		v = d['V']
664
		v_a = (np.sum(v, axis=0) / len(v))
665
		v_a = v_a / np.max(np.abs(v_a))
666
		for _ in range(self.nmutt):
667
			g = task.repair(xb + v_a * self.uniform(task.Lower, task.Upper), self.Rand)
668
			fg = task.eval(g)
669
			if fg <= fxb: xb, fxb = g, fg
670
		return pop, fpop, xb, fxb, d
671
672
class MutatedCenterParticleSwarmOptimization(CenterParticleSwarmOptimization):
673
	r"""Implementation of Mutated Particle Swarm Optimization.
674
675
	Algorithm:
676
		Mutated Center Particle Swarm Optimization
677
678
	Date:
679
		2019
680
681
	Authors:
682
		Klemen Berkovič
683
684
	License:
685
		MIT
686
687
	Reference paper:
688
		TODO find one
689
690
	Attributes:
691
		nmutt (int): Number of mutations of global best particle.
692
693
	See Also:
694
		* :class:`NiaPy.algorithms.basic.CenterParticleSwarmOptimization`
695
	"""
696
	Name = ['MutatedCenterParticleSwarmOptimization', 'MCPSO']
697
698
	@staticmethod
699
	def algorithmInfo():
700
		r"""Get basic information of algorithm.
701
702
		Returns:
703
			str: Basic information of algorithm.
704
705
		See Also:
706
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
707
		"""
708
		return r"""TODO find one"""
709
710
	def setParameters(self, nmutt=10, **kwargs):
711
		r"""Set core algorithm parameters.
712
713
		Args:
714
			nmutt (int): Number of mutations of global best particle.
715
			**kwargs: Additional arguments.
716
717
		See Also:
718
			:func:`NiaPy.algorithm.basic.CenterParticleSwarmOptimization.setParameters`
719
		"""
720
		kwargs.pop('vMin', None), kwargs.pop('vMax', None)
721
		ParticleSwarmAlgorithm.setParameters(self, vMin=-np.inf, vMax=np.inf, **kwargs)
722
		self.nmutt = nmutt
723
724
	def getParameters(self):
725
		r"""Get value of parametrs for this instance of algorithm.
726
727
		Returns:
728
			Dict[str, Union[int, float, np.ndarray]]: Dictionari which has parameters maped to values.
729
730
		See Also:
731
			* :func:`NiaPy.algorithms.basic.CenterParticleSwarmOptimization.getParameters`
732
		"""
733
		d = CenterParticleSwarmOptimization.getParameters(self)
734
		d.update({'nmutt': self.nmutt})
735
		return d
736
737 View Code Duplication
	def runIteration(self, task, pop, fpop, xb, fxb, **dparams):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
738
		r"""Core function of algorithm.
739
740
		Args:
741
			task (Task): Optimization task.
742
			pop (numpy.ndarray): Current population of particles.
743
			fpop (numpy.ndarray): Current particles function/fitness values.
744
			xb (numpy.ndarray): Current global best particle.
745
			fxb (float: Current global best particles function/fitness value.
746
			**dparams: Additional arguments.
747
748
		Returns:
749
			Tuple[np.ndarray, np.ndarray, np.ndarray, float, dict]:
750
			1. New population of particles.
751
			2. New populations function/fitness values.
752
			3. New global best particle.
753
			4. New global best particle function/fitness value.
754
			5. Additional arguments.
755
756
		See Also:
757
			* :func:`NiaPy.algorithm.basic.WeightedVelocityClampingParticleSwarmAlgorithm.runIteration`
758
		"""
759
		pop, fpop, xb, fxb, d = CenterParticleSwarmOptimization.runIteration(self, task, pop, fpop, xb, fxb, **dparams)
760
		v = d['V']
761
		v_a = (np.sum(v, axis=0) / len(v))
762
		v_a = v_a / np.max(np.abs(v_a))
763
		for _ in range(self.nmutt):
764
			g = task.repair(xb + v_a * self.uniform(task.Lower, task.Upper), self.Rand)
765
			fg = task.eval(g)
766
			if fg <= fxb: xb, fxb = g, fg
767
		return pop, fpop, xb, fxb, d
768
769
class MutatedCenterUnifiedParticleSwarmOptimization(MutatedCenterParticleSwarmOptimization):
770
	r"""Implementation of Mutated Particle Swarm Optimization.
771
772
	Algorithm:
773
		Mutated Center Unified Particle Swarm Optimization
774
775
	Date:
776
		2019
777
778
	Authors:
779
		Klemen Berkovič
780
781
	License:
782
		MIT
783
784
	Reference paper:
785
		Tsai, Hsing-Chih. "Unified particle swarm delivers high efficiency to particle swarm optimization." Applied Soft Computing 55 (2017): 371-383.
786
787
	Attributes:
788
		nmutt (int): Number of mutations of global best particle.
789
790
	See Also:
791
		* :class:`NiaPy.algorithms.basic.CenterParticleSwarmOptimization`
792
	"""
793
	Name = ['MutatedCenterUnifiedParticleSwarmOptimization', 'MCUPSO']
794
795
	@staticmethod
796
	def algorithmInfo():
797
		r"""Get basic information of algorithm.
798
799
		Returns:
800
			str: Basic information of algorithm.
801
802
		See Also:
803
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
804
		"""
805
		return r"""Tsai, Hsing-Chih. "Unified particle swarm delivers high efficiency to particle swarm optimization." Applied Soft Computing 55 (2017): 371-383."""
806
807
	def setParameters(self, **kwargs):
808
		r"""Set core algorithm parameters.
809
810
		Args:
811
			**kwargs: Additional arguments.
812
813
		See Also:
814
			:func:`NiaPy.algorithm.basic.MutatedCenterParticleSwarmOptimization.setParameters`
815
		"""
816
		kwargs.pop('vMin', None), kwargs.pop('vMax', None)
817
		MutatedCenterParticleSwarmOptimization.setParameters(self, vMin=-np.inf, vMax=np.inf, **kwargs)
818
819 View Code Duplication
	def updateVelocity(self, V, p, pb, gb, w, vMin, vMax, task, **kwargs):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
820
		r"""Update particle velocity.
821
822
		Args:
823
			V (numpy.ndarray): Current velocity of particle.
824
			p (numpy.ndarray): Current position of particle.
825
			pb (numpy.ndarray): Personal best position of particle.
826
			gb (numpy.ndarray): Global best position of particle.
827
			w (numpy.ndarray): Weights for velocity adjustment.
828
			vMin (numpy.ndarray): Minimal velocity allowed.
829
			vMax (numpy.ndarray): Maxmimal velocity allowed.
830
			task (Task): Optimization task.
831
			kwargs: Additional arguments.
832
833
		Returns:
834
			numpy.ndarray: Updated velocity of particle.
835
		"""
836
		r3 = self.rand(task.D)
837
		return self.Repair(w * V + self.C1 * self.rand(task.D) * (pb - p) * r3 + self.C2 * self.rand(task.D) * (gb - p) * (1 - r3), vMin, vMax)
838
839
class ComprehensiveLearningParticleSwarmOptimizer(ParticleSwarmAlgorithm):
840
	r"""Implementation of Mutated Particle Swarm Optimization.
841
842
	Algorithm:
843
		Comprehensive Learning Particle Swarm Optimizer
844
845
	Date:
846
		2019
847
848
	Authors:
849
		Klemen Berkovič
850
851
	License:
852
		MIT
853
854
	Reference paper:
855
		J. J. Liang, A. K. Qin, P. N. Suganthan and S. Baskar, "Comprehensive learning particle swarm optimizer for global optimization of multimodal functions," in IEEE Transactions on Evolutionary Computation, vol. 10, no. 3, pp. 281-295, June 2006. doi: 10.1109/TEVC.2005.857610
856
857
	Reference URL:
858
		http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=1637688&isnumber=34326
859
860
	Attributes:
861
		w0 (float): Inertia weight.
862
		w1 (float): Inertia weight.
863
		C (float): Velocity constant.
864
		m (int): Refresh rate.
865
866
	See Also:
867
		* :class:`NiaPy.algorithms.basic.ParticleSwarmAlgorithm`
868
	"""
869
	Name = ['ComprehensiveLearningParticleSwarmOptimizer', 'CLPSO']
870
871
	@staticmethod
872
	def algorithmInfo():
873
		r"""Get basic information of algorithm.
874
875
		Returns:
876
			str: Basic information of algorithm.
877
878
		See Also:
879
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
880
		"""
881
		return r"""J. J. Liang, A. K. Qin, P. N. Suganthan and S. Baskar, "Comprehensive learning particle swarm optimizer for global optimization of multimodal functions," in IEEE Transactions on Evolutionary Computation, vol. 10, no. 3, pp. 281-295, June 2006. doi: 10.1109/TEVC.2005.857610	"""
882
883
	def setParameters(self, m=10, w0=.9, w1=.4, C=1.49445, **ukwargs):
884
		r"""Set Particle Swarm Algorithm main parameters.
885
886
		Args:
887
			w0 (int): Inertia weight.
888
			w1 (float): Inertia weight.
889
			C (float): Velocity constant.
890
			m (float): Refresh rate.
891
			**ukwargs: Additional arguments
892
893
		See Also:
894
			* :func:`NiaPy.algorithms.basic.ParticleSwarmAlgorithm.setParameters`
895
		"""
896
		ParticleSwarmAlgorithm.setParameters(self, **ukwargs)
897
		self.m, self.w0, self.w1, self.C = m, w0, w1, C
898
899
	def getParameters(self):
900
		r"""Get value of parametrs for this instance of algorithm.
901
902
		Returns:
903
			Dict[str, Union[int, float, np.ndarray]]: Dictionari which has parameters maped to values.
904
905
		See Also:
906
			* :func:`NiaPy.algorithms.basic.ParticleSwarmAlgorithm.getParameters`
907
		"""
908
		d = ParticleSwarmAlgorithm.getParameters(self)
909
		d.update({
910
			'm': self.m, 'w0': self.w0, 'w1': self.w1, 'C': self.C
911
		})
912
		return d
913
914
	def init(self, task):
915
		r"""Initialize dynamic arguments of Particle Swarm Optimization algorithm.
916
917
		Args:
918
			task (Task): Optimization task.
919
920
		Returns:
921
			Dict[str, np.ndarray]:
922
			* vMin: Mininal velocity.
923
			* vMax: Maximal velocity.
924
			* V: Initial velocity of particle.
925
			* flag: Refresh gap counter.
926
		"""
927
		return {'vMin': fullArray(self.vMin, task.D), 'vMax': fullArray(self.vMax, task.D), 'V': np.full([self.NP, task.D], 0.0), 'flag': np.full(self.NP, 0), 'Pc': np.asarray([.05 + .45 * (np.exp(10 * (i - 1) / (self.NP - 1)) - 1) / (np.exp(10) - 1) for i in range(self.NP)])}
928
929
	def generatePbestCL(self, i, Pc, pbs, fpbs):
930
		r"""Generate new personal best position for learning.
931
932
		Args:
933
			i (int): Current particle.
934
			Pc (float): Learning probability.
935
			pbs (numpy.ndarray): Personal best positions for population.
936
			fpbs (numpy.ndarray): Personal best positions function/fitness values for persolan best position.
937
938
		Returns:
939
			numpy.ndarray: Personal best for learning.
940
		"""
941
		pbest = []
942
		for j in range(len(pbs[i])):
943
			if self.rand() > Pc: pbest.append(pbs[i, j])
944
			else:
945
				r1, r2 = int(self.rand() * len(pbs)), int(self.rand() * len(pbs))
946
				if fpbs[r1] < fpbs[r2]: pbest.append(pbs[r1, j])
947
				else: pbest.append(pbs[r2, j])
948
		return np.asarray(pbest)
949
950
	def updateVelocityCL(self, V, p, pb, w, vMin, vMax, task, **kwargs):
951
		r"""Update particle velocity.
952
953
		Args:
954
			V (numpy.ndarray): Current velocity of particle.
955
			p (numpy.ndarray): Current position of particle.
956
			pb (numpy.ndarray): Personal best position of particle.
957
			w (numpy.ndarray): Weights for velocity adjustment.
958
			vMin (numpy.ndarray): Minimal velocity allowed.
959
			vMax (numpy.ndarray): Maxmimal velocity allowed.
960
			task (Task): Optimization task.
961
			kwargs: Additional arguments.
962
963
		Returns:
964
			numpy.ndarray: Updated velocity of particle.
965
		"""
966
		return self.Repair(w * V + self.C * self.rand(task.D) * (pb - p), vMin, vMax)
967
968
	def runIteration(self, task, pop, fpop, xb, fxb, popb, fpopb, vMin, vMax, V, flag, Pc, **dparams):
969
		r"""Core function of algorithm.
970
971
		Args:
972
			task (Task): Optimization task.
973
			pop (numpy.ndarray): Current populations.
974
			fpop (numpy.ndarray): Current population fitness/function values.
975
			xb (numpy.ndarray): Current best particle.
976
			fxb (float): Current best particle fitness/function value.
977
			popb (numpy.ndarray): Particles best position.
978
			fpopb (numpy.ndarray): Particles best positions fitness/function values.
979
			vMin (numpy.ndarray): Minimal velocity.
980
			vMax (numpy.ndarray): Maximal velocity.
981
			V (numpy.ndarray): Velocity of particles.
982
			flag (numpy.ndarray): Refresh rate counter.
983
			Pc (numpy.ndarray): Learning rate.
984
			**dparams (Dict[str, Any]): Additional function arguments.
985
986
		Returns:
987
			Tuple[np.ndarray, np.ndarray, np.ndarray, dict]:
988
			1. New population.
989
			2. New population fitness/function values.
990
			3. New global best position.
991
			4. New global best positions function/fitness value.
992
			5. Additional arguments:
993
				* popb: Particles best population.
994
				* fpopb: Particles best positions function/fitness value.
995
				* vMin: Minimal velocity.
996
				* vMax: Maximal velocity.
997
				* V: Initial velocity of particle.
998
				* flag: Refresh gap counter.
999
				* Pc: Learning rate.
1000
1001
		See Also:
1002
			* :class:`NiaPy.algorithms.basic.ParticleSwarmAlgorithm.runIteration`
1003
		"""
1004
		w = self.w0 * (self.w0 - self.w1) * task.Iters / task.nGEN
1005
		for i in range(len(pop)):
1006
			if flag[i] >= self.m:
1007
				V[i] = self.updateVelocity(V[i], pop[i], popb[i], xb, 1, vMin, vMax, task)
1008
				pop[i] = task.repair(pop[i] + V[i], rnd=self.Rand)
1009
				fpop[i] = task.eval(pop[i])
1010
				if fpop[i] < fpopb[i]:
1011
					popb[i], fpopb[i] = pop[i].copy(), fpop[i]
1012
					if fpop[i] < fxb: xb, fxb = pop[i].copy(), fpop[i]
1013
				flag[i] = 0
1014
			pbest = self.generatePbestCL(i, Pc[i], popb, fpopb)
1015
			V[i] = self.updateVelocityCL(V[i], pop[i], pbest, w, vMin, vMax, task)
1016
			pop[i] = pop[i] + V[i]
1017
			if not ((pop[i] < task.Lower).any() or (pop[i] > task.Upper).any()):
1018
				fpop[i] = task.eval(pop[i])
1019
				if fpop[i] < fpopb[i]:
1020
					popb[i], fpopb[i] = pop[i].copy(), fpop[i]
1021
					if fpop[i] < fxb: xb, fxb = pop[i].copy(), fpop[i]
1022
		return pop, fpop, xb, fxb, {'popb': popb, 'fpopb': fpopb, 'vMin': vMin, 'vMax': vMax, 'V': V, 'flag': flag, 'Pc': Pc}
1023
1024
# vim: tabstop=3 noexpandtab shiftwidth=3 softtabstop=3
1025