NiaPy.algorithms.basic.es   C
last analyzed

Complexity

Total Complexity 57

Size/Duplication

Total Lines 595
Duplicated Lines 3.03 %

Importance

Changes 0
Metric Value
eloc 170
dl 18
loc 595
rs 5.04
c 0
b 0
f 0
wmc 57

26 Methods

Rating   Name   Duplication   Size   Complexity  
A IndividualES.__init__() 0 11 1
A EvolutionStrategyMpL.typeParameters() 0 14 2
A EvolutionStrategyML.algorithmInfo() 0 11 1
A EvolutionStrategy1p1.algorithmInfo() 0 11 1
A EvolutionStrategy1p1.initPopulation() 0 15 1
A EvolutionStrategyMpL.mutateRand() 0 12 1
A CovarianceMatrixAdaptionEvolutionStrategy.typeParameters() 0 3 2
A CovarianceMatrixAdaptionEvolutionStrategy.runTask() 0 10 1
A EvolutionStrategyML.initPopulation() 0 17 1
A EvolutionStrategy1p1.setParameters() 0 14 1
A CovarianceMatrixAdaptionEvolutionStrategy.algorithmInfo() 0 11 1
A EvolutionStrategy1p1.mutate() 0 11 1
A EvolutionStrategyMpL.runIteration() 0 29 2
A EvolutionStrategyMpL.setParameters() 0 11 1
A EvolutionStrategy1p1.runIteration() 0 29 4
A EvolutionStrategyMp1.algorithmInfo() 0 11 1
A EvolutionStrategyML.runIteration() 0 24 1
A EvolutionStrategyMpL.updateRho() 0 12 5
A EvolutionStrategyML.newPop() 0 14 4
A EvolutionStrategyMpL.algorithmInfo() 0 11 1
A CovarianceMatrixAdaptionEvolutionStrategy.setParameters() 0 9 1
B EvolutionStrategy1p1.typeParameters() 18 18 6
A EvolutionStrategy1p1.updateRho() 0 14 5
A EvolutionStrategyMpL.initPopulation() 0 19 1
A EvolutionStrategyMp1.setParameters() 0 11 1
A EvolutionStrategyMpL.changeCount() 0 14 3

1 Function

Rating   Name   Duplication   Size   Complexity  
B CovarianceMaatrixAdaptionEvolutionStrategyF() 0 37 7

How to fix   Duplicated Code    Complexity   

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:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

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

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

1
# encoding=utf8
2
import logging
3
from math import ceil
4
5
from numpy import argmin, argsort, log, sum, fmax, sqrt, full, exp, eye, diag, apply_along_axis, round, any, asarray, dot, random as rand, tile, inf, where, append
6
from numpy.linalg import norm, cholesky as chol, eig, solve, lstsq
7
8
from NiaPy.algorithms.algorithm import Algorithm, Individual, defaultIndividualInit
9
from NiaPy.util.utility import objects2array
10
11
logging.basicConfig()
12
logger = logging.getLogger('NiaPy.algorithms.basic')
13
logger.setLevel('INFO')
14
15
__all__ = ['EvolutionStrategy1p1', 'EvolutionStrategyMp1', 'EvolutionStrategyMpL', 'EvolutionStrategyML', 'CovarianceMatrixAdaptionEvolutionStrategy']
16
17
class IndividualES(Individual):
18
	r"""Individual for Evolution Strategies.
19
20
	See Also:
21
		* :class:`NiaPy.algorithms.Individual`
22
	"""
23
	def __init__(self, **kwargs):
24
		r"""Initialize individual.
25
26
		Args:
27
			kwargs (Dict[str, Any]): Additional arguments.
28
29
		See Also:
30
			* :func:`NiaPy.algorithms.Individual.__init__`
31
		"""
32
		Individual.__init__(self, **kwargs)
33
		self.rho = kwargs.get('rho', 1)
34
35
class EvolutionStrategy1p1(Algorithm):
36
	r"""Implementation of (1 + 1) evolution strategy algorithm. Uses just one individual.
37
38
	Algorithm:
39
		(1 + 1) Evolution Strategy Algorithm
40
41
	Date:
42
		2018
43
44
	Authors:
45
		Klemen Berkovič
46
47
	License:
48
		MIT
49
50
	Reference URL:
51
52
	Reference paper:
53
54
	Attributes:
55
		Name (List[str]): List of strings representing algorithm names.
56
		mu (int): Number of parents.
57
		k (int): Number of iterations before checking and fixing rho.
58
		c_a (float): Search range amplification factor.
59
		c_r (float): Search range reduction factor.
60
61
	See Also:
62
		* :class:`NiaPy.algorithms.Algorithm`
63
	"""
64
	Name = ['EvolutionStrategy1p1', 'EvolutionStrategy(1+1)', 'ES(1+1)']
65
66
	@staticmethod
67
	def algorithmInfo():
68
		r"""Get algorithms information.
69
70
		Returns:
71
			str: Algorithm information.
72
73
		See Also:
74
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
75
		"""
76
		return r"""TODO"""
77
78 View Code Duplication
	@staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
79
	def typeParameters():
80
		r"""Get dictionary with functions for checking values of parameters.
81
82
		Returns:
83
			Dict[str, Callable]:
84
				* mu (Callable[[int], bool])
85
				* k (Callable[[int], bool])
86
				* c_a (Callable[[Union[float, int]], bool])
87
				* c_r (Callable[[Union[float, int]], bool])
88
				* epsilon (Callable[[float], bool])
89
		"""
90
		return {
91
			'mu': lambda x: isinstance(x, int) and x > 0,
92
			'k': lambda x: isinstance(x, int) and x > 0,
93
			'c_a': lambda x: isinstance(x, (float, int)) and x > 1,
94
			'c_r': lambda x: isinstance(x, (float, int)) and 0 < x < 1,
95
			'epsilon': lambda x: isinstance(x, float) and 0 < x < 1
96
		}
97
98
	def setParameters(self, mu=1, k=10, c_a=1.1, c_r=0.5, epsilon=1e-20, **ukwargs):
99
		r"""Set the arguments of an algorithm.
100
101
		Arguments:
102
			mu (Optional[int]): Number of parents
103
			k (Optional[int]): Number of iterations before checking and fixing rho
104
			c_a (Optional[float]): Search range amplification factor
105
			c_r (Optional[float]): Search range reduction factor
106
107
		See Also:
108
			* :func:`NiaPy.algorithms.Algorithm.setParameters`
109
		"""
110
		Algorithm.setParameters(self, NP=mu, itype=ukwargs.pop('itype', IndividualES), **ukwargs)
111
		self.mu, self.k, self.c_a, self.c_r, self.epsilon = mu, k, c_a, c_r, epsilon
112
113
	def mutate(self, x, rho):
114
		r"""Mutate individual.
115
116
		Args:
117
			x (Individual): Current individual.
118
			rho (float): Current standard deviation.
119
120
		Returns:
121
			Individual: Mutated individual.
122
		"""
123
		return x + self.normal(0, rho, len(x))
124
125
	def updateRho(self, rho, k):
126
		r"""Update standard deviation.
127
128
		Args:
129
			rho (float): Current standard deviation.
130
			k (int): Number of succesfull mutations.
131
132
		Returns:
133
			float: New standard deviation.
134
		"""
135
		phi = k / self.k
136
		if phi < 0.2: return self.c_r * rho if rho > self.epsilon else 1
137
		elif phi > 0.2: return self.c_a * rho if rho > self.epsilon else 1
138
		else: return rho
139
140
	def initPopulation(self, task):
141
		r"""Initialize starting individual.
142
143
		Args:
144
			task (Task): Optimization task.
145
146
		Returns:
147
			Tuple[Individual, float, Dict[str, Any]]:
148
				1, Initialized individual.
149
				2, Initialized individual fitness/function value.
150
				3. Additional arguments:
151
					* ki (int): Number of successful rho update.
152
		"""
153
		c, ki = IndividualES(task=task, rnd=self.Rand), 0
154
		return c, c.f, {'ki': ki}
155
156
	def runIteration(self, task, c, fpop, xb, fxb, ki, **dparams):
157
		r"""Core function of EvolutionStrategy(1+1) algorithm.
158
159
		Args:
160
			task (Task): Optimization task.
161
			pop (Individual): Current position.
162
			fpop (float): Current position function/fitness value.
163
			xb (Individual): Global best position.
164
			fxb (float): Global best function/fitness value.
165
			ki (int): Number of successful updates before rho update.
166
			**dparams (Dict[str, Any]): Additional arguments.
167
168
		Returns:
169
			Tuple[Individual, float, Individual, float, Dict[str, Any]]:
170
				1, Initialized individual.
171
				2, Initialized individual fitness/function value.
172
				3. New global best solution.
173
				4. New global best soluitons fitness/objective value.
174
				5. Additional arguments:
175
					* ki (int): Number of successful rho update.
176
		"""
177
		if task.Iters % self.k == 0: c.rho, ki = self.updateRho(c.rho, ki), 0
178
		cn = objects2array([task.repair(self.mutate(c.x, c.rho), self.Rand) for _i in range(self.mu)])
179
		cn_f = asarray([task.eval(cn[i]) for i in range(len(cn))])
180
		ib = argmin(cn_f)
181
		if cn_f[ib] < c.f:
182
			c.x, c.f, ki = cn[ib], cn_f[ib], ki + 1
183
			if cn_f[ib] < fxb: xb, fxb = self.getBest(cn[ib], cn_f[ib], xb, fxb)
184
		return c, c.f, xb, fxb, {'ki': ki}
185
186
class EvolutionStrategyMp1(EvolutionStrategy1p1):
187
	r"""Implementation of (mu + 1) evolution strategy algorithm. Algorithm creates mu mutants but into new generation goes only one individual.
188
189
	Algorithm:
190
		(:math:`\mu + 1`) Evolution Strategy Algorithm
191
192
	Date:
193
		2018
194
195
	Authors:
196
		Klemen Berkovič
197
198
	License:
199
		MIT
200
201
	Reference URL:
202
203
	Reference paper:
204
205
	Attributes:
206
		Name (List[str]): List of strings representing algorithm names.
207
208
	See Also:
209
		* :class:`NiaPy.algorithms.basic.EvolutionStrategy1p1`
210
	"""
211
	Name = ['EvolutionStrategyMp1', 'EvolutionStrategy(mu+1)', 'ES(m+1)']
212
213
	@staticmethod
214
	def algorithmInfo():
215
		r"""Get algorithms information.
216
217
		Returns:
218
			str: Algorithm information.
219
220
		See Also:
221
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
222
		"""
223
		return r"""TODO"""
224
225
	def setParameters(self, **kwargs):
226
		r"""Set core parameters of EvolutionStrategy(mu+1) algorithm.
227
228
		Args:
229
			**kwargs (Dict[str, Any]):
230
231
		See Also:
232
			* :func:`NiaPy.algorithms.basic.EvolutionStrategy1p1.setParameters`
233
		"""
234
		mu = kwargs.pop('mu', 40)
235
		EvolutionStrategy1p1.setParameters(self, mu=mu, **kwargs)
236
237
class EvolutionStrategyMpL(EvolutionStrategy1p1):
238
	r"""Implementation of (mu + lambda) evolution strategy algorithm. Mulation creates lambda individual. Lambda individual compete with mu individuals for survival, so only mu individual go to new generation.
239
240
	Algorithm:
241
		(:math:`\mu + \lambda`) Evolution Strategy Algorithm
242
243
	Date:
244
		2018
245
246
	Authors:
247
		Klemen Berkovič
248
249
	License:
250
		MIT
251
252
	Reference URL:
253
254
	Reference paper:
255
256
	Attributes:
257
		Name (List[str]): List of strings representing algorithm names
258
		lam (int): TODO
259
260
	See Also:
261
		* :class:`NiaPy.algorithms.basic.EvolutionStrategy1p1`
262
	"""
263
	Name = ['EvolutionStrategyMpL', 'EvolutionStrategy(mu+lambda)', 'ES(m+l)']
264
265
	@staticmethod
266
	def algorithmInfo():
267
		r"""Get algorithms information.
268
269
		Returns:
270
			str: Algorithm information.
271
272
		See Also:
273
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
274
		"""
275
		return r"""TODO"""
276
277
	@staticmethod
278
	def typeParameters():
279
		r"""TODO.
280
281
		Returns:
282
			Dict[str, Any]:
283
				* lam (Callable[[int], bool]): TODO.
284
285
		See Also:
286
			* :func:`NiaPy.algorithms.basic.EvolutionStrategy1p1`
287
		"""
288
		d = EvolutionStrategy1p1.typeParameters()
289
		d['lam'] = lambda x: isinstance(x, int) and x > 0
290
		return d
291
292
	def setParameters(self, lam=45, **ukwargs):
293
		r"""Set the arguments of an algorithm.
294
295
		Arguments:
296
			lam (int): Number of new individual generated by mutation.
297
298
		See Also:
299
			* :func:`NiaPy.algorithms.basic.es.EvolutionStrategy1p1.setParameters`
300
		"""
301
		EvolutionStrategy1p1.setParameters(self, InitPopFunc=defaultIndividualInit, **ukwargs)
302
		self.lam = lam
303
304
	def updateRho(self, pop, k):
305
		r"""Update standard deviation for population.
306
307
		Args:
308
			pop (numpy.ndarray[Individual]): Current population.
309
			k (int): Number of successful mutations.
310
		"""
311
		phi = k / self.k
312
		if phi < 0.2:
313
			for i in pop: i.rho = self.c_r * i.rho
314
		elif phi > 0.2:
315
			for i in pop: i.rho = self.c_a * i.rho
316
317
	def changeCount(self, c, cn):
318
		r"""Update number of successful mutations for population.
319
320
		Args:
321
			c (numpy.ndarray[Individual]): Current population.
322
			cn (numpy.ndarray[Individual]): New population.
323
324
		Returns:
325
			int: Number of successful mutations.
326
		"""
327
		k = 0
328
		for e in cn:
329
			if e not in c: k += 1
330
		return k
331
332
	def mutateRand(self, pop, task):
333
		r"""Mutate random individual form population.
334
335
		Args:
336
			pop (numpy.ndarray[Individual]): Current population.
337
			task (Task): Optimization task.
338
339
		Returns:
340
			numpy.ndarray: Random individual from population that was mutated.
341
		"""
342
		i = self.randint(self.mu)
343
		return task.repair(self.mutate(pop[i].x, pop[i].rho), rnd=self.Rand)
344
345
	def initPopulation(self, task):
346
		r"""Initialize starting population.
347
348
		Args:
349
			task (Task): Optimization task.
350
351
		Returns:
352
			Tuple[numpy.ndarray[Individual], numpy.ndarray[float], Dict[str, Any]]:
353
				1. Initialized populaiton.
354
				2. Initialized populations function/fitness values.
355
				3. Additional arguments:
356
					* ki (int): Number of successful mutations.
357
358
		See Also:
359
			* :func:`NiaPy.algorithms.algorithm.Algorithm.initPopulation`
360
		"""
361
		c, fc, d = Algorithm.initPopulation(self, task)
362
		d.update({'ki': 0})
363
		return c, fc, d
364
365
	def runIteration(self, task, c, fpop, xb, fxb, ki, **dparams):
366
		r"""Core function of EvolutionStrategyMpL algorithm.
367
368
		Args:
369
			task (Task): Optimization task.
370
			c (numpy.ndarray): Current population.
371
			fpop (numpy.ndarray): Current populations fitness/function values.
372
			xb (numpy.ndarray): Global best individual.
373
			fxb (float): Global best individuals fitness/function value.
374
			ki (int): Number of successful mutations.
375
			**dparams (Dict[str, Any]): Additional arguments.
376
377
		Returns:
378
			Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, float, Dict[str, Any]]:
379
				1. New population.
380
				2. New populations function/fitness values.
381
				3. New global best solution.
382
				4. New global best solutions fitness/objective value.
383
				5. Additional arguments:
384
					* ki (int): Number of successful mutations.
385
		"""
386
		if task.Iters % self.k == 0: _, ki = self.updateRho(c, ki), 0
387
		cn = objects2array([IndividualES(x=self.mutateRand(c, task), task=task, rnd=self.Rand) for _ in range(self.lam)])
388
		cn = append(cn, c)
389
		cn = objects2array([cn[i] for i in argsort([i.f for i in cn])[:self.mu]])
390
		ki += self.changeCount(c, cn)
391
		fcn = asarray([x.f for x in cn])
392
		xb, fxb = self.getBest(cn, fcn, xb, fxb)
393
		return cn, fcn, xb, fxb, {'ki': ki}
394
395
class EvolutionStrategyML(EvolutionStrategyMpL):
396
	r"""Implementation of (mu, lambda) evolution strategy algorithm. Algorithm is good for dynamic environments. Mu individual create lambda chields. Only best mu chields go to new generation. Mu parents are discarded.
397
398
	Algorithm:
399
		(:math:`\mu + \lambda`) Evolution Strategy Algorithm
400
401
	Date:
402
		2018
403
404
	Authors:
405
		Klemen Berkovič
406
407
	License:
408
		MIT
409
410
	Reference URL:
411
412
	Reference paper:
413
414
	Attributes:
415
		Name (List[str]): List of strings representing algorithm names
416
417
	See Also:
418
		* :class:`NiaPy.algorithm.basic.es.EvolutionStrategyMpL`
419
	"""
420
	Name = ['EvolutionStrategyML', 'EvolutionStrategy(mu,lambda)', 'ES(m,l)']
421
422
	@staticmethod
423
	def algorithmInfo():
424
		r"""Get algorithms information.
425
426
		Returns:
427
			str: Algorithm information.
428
429
		See Also:
430
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
431
		"""
432
		return r"""TODO"""
433
434
	def newPop(self, pop):
435
		r"""Return new population.
436
437
		Args:
438
			pop (numpy.ndarray): Current population.
439
440
		Returns:
441
			numpy.ndarray: New population.
442
		"""
443
		pop_s = argsort([i.f for i in pop])
444
		if self.mu < self.lam: return objects2array([pop[i] for i in pop_s[:self.mu]])
445
		npop = list()
446
		for i in range(int(ceil(float(self.mu) / self.lam))): npop.extend(pop[:self.lam if (self.mu - i * self.lam) >= self.lam else self.mu - i * self.lam])
447
		return objects2array(npop)
448
449
	def initPopulation(self, task):
450
		r"""Initialize starting population.
451
452
		Args:
453
			task (Task): Optimization task.
454
455
		Returns:
456
			Tuple[numpy.ndarray[Individual], numpy.ndarray[float], Dict[str, Any]]:
457
				1. Initialized population.
458
				2. Initialized populations fitness/function values.
459
				2. Additional arguments.
460
461
		See Also:
462
			* :func:`NiaPy.algorithm.basic.es.EvolutionStrategyMpL.initPopulation`
463
		"""
464
		c, fc, _ = EvolutionStrategyMpL.initPopulation(self, task)
465
		return c, fc, {}
466
467
	def runIteration(self, task, c, fpop, xb, fxb, **dparams):
468
		r"""Core function of EvolutionStrategyML algorithm.
469
470
		Args:
471
			task (Task): Optimization task.
472
			c (numpy.ndarray): Current population.
473
			fpop (numpy.ndarray): Current population fitness/function values.
474
			xb (numpy.ndarray): Global best individual.
475
			fxb (float): Global best individuals fitness/function value.
476
			**dparams Dict[str, Any]: Additional arguments.
477
478
		Returns:
479
			Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, float, Dict[str, Any]]:
480
				1. New population.
481
				2. New populations fitness/function values.
482
				3. New global best solution.
483
				4. New global best solutions fitness/objective value.
484
				5. Additional arguments.
485
		"""
486
		cn = objects2array([IndividualES(x=self.mutateRand(c, task), task=task, rand=self.Rand) for _ in range(self.lam)])
487
		c = self.newPop(cn)
488
		fc = asarray([x.f for x in c])
489
		xb, fxb = self.getBest(c, fc, xb, fxb)
490
		return c, fc, xb, fxb, {}
491
492
def CovarianceMaatrixAdaptionEvolutionStrategyF(task, epsilon=1e-20, rnd=rand):
493
	lam, alpha_mu, hs, sigma0 = (4 + round(3 * log(task.D))) * 10, 2, 0, 0.3 * task.bcRange()
494
	mu = int(round(lam / 2))
495
	w = log(mu + 0.5) - log(range(1, mu + 1))
496
	w = w / sum(w)
497
	mueff = 1 / sum(w ** 2)
498
	cs = (mueff + 2) / (task.D + mueff + 5)
499
	ds = 1 + cs + 2 * max(sqrt((mueff - 1) / (task.D + 1)) - 1, 0)
500
	ENN = sqrt(task.D) * (1 - 1 / (4 * task.D) + 1 / (21 * task.D ** 2))
501
	cc, c1 = (4 + mueff / task.D) / (4 + task.D + 2 * mueff / task.D), 2 / ((task.D + 1.3) ** 2 + mueff)
502
	cmu, hth = min(1 - c1, alpha_mu * (mueff - 2 + 1 / mueff) / ((task.D + 2) ** 2 + alpha_mu * mueff / 2)), (1.4 + 2 / (task.D + 1)) * ENN
503
	ps, pc, C, sigma, M = full(task.D, 0.0), full(task.D, 0.0), eye(task.D), sigma0, full(task.D, 0.0)
504
	x = rnd.uniform(task.bcLower(), task.bcUpper())
505
	x_f = task.eval(x)
506
	while not task.stopCondI():
507
		pop_step = asarray([rnd.multivariate_normal(full(task.D, 0.0), C) for _ in range(int(lam))])
508
		pop = asarray([task.repair(x + sigma * ps, rnd) for ps in pop_step])
509
		pop_f = apply_along_axis(task.eval, 1, pop)
510
		isort = argsort(pop_f)
511
		pop, pop_f, pop_step = pop[isort[:mu]], pop_f[isort[:mu]], pop_step[isort[:mu]]
512
		if pop_f[0] < x_f: x, x_f = pop[0], pop_f[0]
513
		M = sum(w * pop_step.T, axis=1)
514
		ps = solve(chol(C).conj() + epsilon, ((1 - cs) * ps + sqrt(cs * (2 - cs) * mueff) * M + epsilon).T)[0].T
515
		sigma *= exp(cs / ds * (norm(ps) / ENN - 1)) ** 0.3
516
		ifix = where(sigma == inf)
517
		if any(ifix): sigma[ifix] = sigma0
518
		if norm(ps) / sqrt(1 - (1 - cs) ** (2 * (task.Iters + 1))) < hth: hs = 1
519
		else: hs = 0
520
		delta = (1 - hs) * cc * (2 - cc)
521
		pc = (1 - cc) * pc + hs * sqrt(cc * (2 - cc) * mueff) * M
522
		C = (1 - c1 - cmu) * C + c1 * (tile(pc, [len(pc), 1]) * tile(pc.reshape([len(pc), 1]), [1, len(pc)]) + delta * C)
523
		for i in range(mu): C += cmu * w[i] * tile(pop_step[i], [len(pop_step[i]), 1]) * tile(pop_step[i].reshape([len(pop_step[i]), 1]), [1, len(pop_step[i])])
524
		E, V = eig(C)
525
		if any(E < epsilon):
526
			E = fmax(E, 0)
527
			C = lstsq(V.T, dot(V, diag(E)).T, rcond=None)[0].T
528
	return x, x_f
529
530
class CovarianceMatrixAdaptionEvolutionStrategy(Algorithm):
531
	r"""Implementation of (mu, lambda) evolution strategy algorithm. Algorithm is good for dynamic environments. Mu individual create lambda chields. Only best mu chields go to new generation. Mu parents are discarded.
532
533
	Algorithm:
534
		(:math:`\mu + \lambda`) Evolution Strategy Algorithm
535
536
	Date:
537
		2018
538
539
	Authors:
540
		Klemen Berkovič
541
542
	License:
543
		MIT
544
545
	Reference URL:
546
		https://arxiv.org/abs/1604.00772
547
548
	Reference paper:
549
		Hansen, Nikolaus. "The CMA evolution strategy: A tutorial." arXiv preprint arXiv:1604.00772 (2016).
550
551
	Attributes:
552
		Name (List[str]): List of names representing algorithm names
553
		epsilon (float): TODO
554
	"""
555
	Name = ['CovarianceMatrixAdaptionEvolutionStrategy', 'CMA-ES', 'CMAES']
556
	epsilon = 1e-20
557
558
	@staticmethod
559
	def algorithmInfo():
560
		r"""Get algorithms information.
561
562
		Returns:
563
			str: Algorithm information.
564
565
		See Also:
566
			* :func:`NiaPy.algorithms.Algorithm.algorithmInfo`
567
		"""
568
		return r"""TODO"""
569
570
	@staticmethod
571
	def typeParameters(): return {
572
			'epsilon': lambda x: isinstance(x, (float, int)) and 0 < x < 1
573
	}
574
575
	def setParameters(self, epsilon=1e-20, **ukwargs):
576
		r"""Set core parameters of CovarianceMatrixAdaptionEvolutionStrategy algorithm.
577
578
		Args:
579
			epsilon (float): Small number.
580
			**ukwargs (Dict[str, Any]): Additional arguments.
581
		"""
582
		Algorithm.setParameters(self, **ukwargs)
583
		self.epsilon = epsilon
584
585
	def runTask(self, task):
586
		r"""TODO.
587
588
		Args:
589
			task (Task): Optimization task.
590
591
		Returns:
592
			TODO.
593
		"""
594
		return CovarianceMaatrixAdaptionEvolutionStrategyF(task, self.epsilon, rnd=self.Rand)
595
596
# vim: tabstop=3 noexpandtab shiftwidth=3 softtabstop=3
597