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

MutatedParticleSwarmOptimization.getParameters()   A

Complexity

Conditions 1

Size

Total Lines 13
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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