Total Complexity | 86 |
Total Lines | 952 |
Duplicated Lines | 25.95 % |
Changes | 0 |
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:
Complex classes like NiaPy.algorithms.basic.de 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 | # pylint: disable=mixed-indentation, multiple-statements, line-too-long, unused-argument, no-self-use, no-self-use, attribute-defined-outside-init, logging-not-lazy, len-as-condition, singleton-comparison, arguments-differ, bad-continuation, dangerous-default-value, keyword-arg-before-vararg |
||
3 | import logging |
||
4 | from numpy import random as rand, argmin, argmax, mean, cos, asarray, append |
||
5 | from scipy.spatial.distance import euclidean |
||
6 | |||
7 | from NiaPy.algorithms.algorithm import Algorithm, Individual, defaultIndividualInit |
||
8 | from NiaPy.util.utility import objects2array |
||
9 | |||
10 | __all__ = ['DifferentialEvolution', 'DynNpDifferentialEvolution', 'AgingNpDifferentialEvolution', 'CrowdingDifferentialEvolution', 'MultiStrategyDifferentialEvolution', 'DynNpMultiStrategyDifferentialEvolution', 'AgingNpMultiMutationDifferentialEvolution', 'AgingIndividual', 'CrossRand1', 'CrossBest2', 'CrossBest1', 'CrossBest2', 'CrossCurr2Rand1', 'CrossCurr2Best1', 'multiMutations'] |
||
11 | |||
12 | logging.basicConfig() |
||
13 | logger = logging.getLogger('NiaPy.algorithms.basic') |
||
14 | logger.setLevel('INFO') |
||
15 | |||
16 | View Code Duplication | def CrossRand1(pop, ic, x_b, f, cr, rnd=rand, *args): |
|
|
|||
17 | r"""Mutation strategy with crossover. |
||
18 | |||
19 | Mutation strategy uses three different random individuals from population to perform mutation. |
||
20 | |||
21 | Mutation: |
||
22 | Name: DE/rand/1 |
||
23 | |||
24 | :math:`\mathbf{x}_{r_1, G} + F \cdot (\mathbf{x}_{r_2, G} - \mathbf{x}_{r_3, G}` |
||
25 | where :math:`r_1, r_2, r_3` are random indexes representing current population individuals. |
||
26 | |||
27 | Crossover: |
||
28 | Name: Binomial crossover |
||
29 | |||
30 | :math:`\mathbf{x}_{i, G+1} = \begin{cases} \mathbf{u}_{i, G+1}, & \text{if $f(\mathbf{u}_{i, G+1}) \leq f(\mathbf{x}_{i, G})$}, \\ \mathbf{x}_{i, G}, & \text{otherwise}. \end{cases}` |
||
31 | |||
32 | Args: |
||
33 | pop (numpy.ndarray[Individual]): Current population. |
||
34 | ic (int): Index of individual being mutated. |
||
35 | x_b (Individual): Current global best individual. |
||
36 | f (float): Scale factor. |
||
37 | cr (float): Crossover probability. |
||
38 | rnd (mtrand.RandomState): Random generator. |
||
39 | *args (list): Additional arguments. |
||
40 | |||
41 | Returns: |
||
42 | numpy.ndarray: Mutated and mixed individual. |
||
43 | """ |
||
44 | j = rnd.randint(len(pop[ic])) |
||
45 | p = [1 / (len(pop) - 1.0) if i != ic else 0 for i in range(len(pop))] if len(pop) > 3 else None |
||
46 | r = rnd.choice(len(pop), 3, replace=not len(pop) >= 3, p=p) |
||
47 | x = [pop[r[0]][i] + f * (pop[r[1]][i] - pop[r[2]][i]) if rnd.rand() < cr or i == j else pop[ic][i] for i in range(len(pop[ic]))] |
||
48 | return asarray(x) |
||
49 | |||
50 | View Code Duplication | def CrossBest1(pop, ic, x_b, f, cr, rnd=rand, *args): |
|
51 | r"""Mutation strategy with crossover. |
||
52 | |||
53 | Mutation strategy uses two different random individuals from population and global best individual. |
||
54 | |||
55 | Mutation: |
||
56 | Name: de/best/1 |
||
57 | |||
58 | :math:`\mathbf{v}_{i, G} = \mathbf{x}_{best, G} + F \cdot (\mathbf{x}_{r_1, G} - \mathbf{x}_{r_2, G})` |
||
59 | where :math:`r_1, r_2` are random indexes representing current population individuals. |
||
60 | |||
61 | Crossover: |
||
62 | Name: Binomial crossover |
||
63 | |||
64 | :math:`\mathbf{x}_{i, G+1} = \begin{cases} \mathbf{u}_{i, G+1}, & \text{if $f(\mathbf{u}_{i, G+1}) \leq f(\mathbf{x}_{i, G})$}, \\ \mathbf{x}_{i, G}, & \text{otherwise}. \end{cases}` |
||
65 | |||
66 | args: |
||
67 | pop (numpy.ndarray[Individual]): Current population. |
||
68 | ic (int): Index of individual being mutated. |
||
69 | x_b (Individual): Current global best individual. |
||
70 | f (float): Scale factor. |
||
71 | cr (float): Crossover probability. |
||
72 | rnd (mtrand.RandomState): Random generator. |
||
73 | *args (list): Additional arguments. |
||
74 | |||
75 | returns: |
||
76 | numpy.ndarray: Mutated and mixed individual. |
||
77 | """ |
||
78 | j = rnd.randint(len(pop[ic])) |
||
79 | p = [1 / (len(pop) - 1.0) if i != ic else 0 for i in range(len(pop))] if len(pop) > 2 else None |
||
80 | r = rnd.choice(len(pop), 2, replace=not len(pop) >= 2, p=p) |
||
81 | x = [x_b[i] + f * (pop[r[0]][i] - pop[r[1]][i]) if rnd.rand() < cr or i == j else pop[ic][i] for i in range(len(pop[ic]))] |
||
82 | return asarray(x) |
||
83 | |||
84 | View Code Duplication | def CrossRand2(pop, ic, x_b, f, cr, rnd=rand, *args): |
|
85 | r"""Mutation strategy with crossover. |
||
86 | |||
87 | Mutation strategy uses five different random individuals from population. |
||
88 | |||
89 | Mutation: |
||
90 | Name: de/best/1 |
||
91 | |||
92 | :math:`\mathbf{v}_{i, G} = \mathbf{x}_{r_1, G} + F \cdot (\mathbf{x}_{r_2, G} - \mathbf{x}_{r_3, G}) + F \cdot (\mathbf{x}_{r_4, G} - \mathbf{x}_{r_5, G})` |
||
93 | where :math:`r_1, r_2, r_3, r_4, r_5` are random indexes representing current population individuals. |
||
94 | |||
95 | Crossover: |
||
96 | Name: Binomial crossover |
||
97 | |||
98 | :math:`\mathbf{x}_{i, G+1} = \begin{cases} \mathbf{u}_{i, G+1}, & \text{if $f(\mathbf{u}_{i, G+1}) \leq f(\mathbf{x}_{i, G})$}, \\ \mathbf{x}_{i, G}, & \text{otherwise}. \end{cases}` |
||
99 | |||
100 | Args: |
||
101 | pop (numpy.ndarray[Individual]): Current population. |
||
102 | ic (int): Index of individual being mutated. |
||
103 | x_b (Individual): Current global best individual. |
||
104 | f (float): Scale factor. |
||
105 | cr (float): Crossover probability. |
||
106 | rnd (mtrand.RandomState): Random generator. |
||
107 | *args (list): Additional arguments. |
||
108 | |||
109 | Returns: |
||
110 | numpy.ndarray: mutated and mixed individual. |
||
111 | """ |
||
112 | j = rnd.randint(len(pop[ic])) |
||
113 | p = [1 / (len(pop) - 1.0) if i != ic else 0 for i in range(len(pop))] if len(pop) > 5 else None |
||
114 | r = rnd.choice(len(pop), 5, replace=not len(pop) >= 5, p=p) |
||
115 | x = [pop[r[0]][i] + f * (pop[r[1]][i] - pop[r[2]][i]) + f * (pop[r[3]][i] - pop[r[4]][i]) if rnd.rand() < cr or i == j else pop[ic][i] for i in range(len(pop[ic]))] |
||
116 | return asarray(x) |
||
117 | |||
118 | View Code Duplication | def CrossBest2(pop, ic, x_b, f, cr, rnd=rand, *args): |
|
119 | r"""Mutation strategy with crossover. |
||
120 | |||
121 | Mutation: |
||
122 | Name: de/best/2 |
||
123 | |||
124 | :math:`\mathbf{v}_{i, G} = \mathbf{x}_{best, G} + F \cdot (\mathbf{x}_{r_1, G} - \mathbf{x}_{r_2, G}) + F \cdot (\mathbf{x}_{r_3, G} - \mathbf{x}_{r_4, G})` |
||
125 | where :math:`r_1, r_2, r_3, r_4` are random indexes representing current population individuals. |
||
126 | |||
127 | Crossover: |
||
128 | Name: Binomial crossover |
||
129 | |||
130 | :math:`\mathbf{x}_{i, G+1} = \begin{cases} \mathbf{u}_{i, G+1}, & \text{if $f(\mathbf{u}_{i, G+1}) \leq f(\mathbf{x}_{i, G})$}, \\ \mathbf{x}_{i, G}, & \text{otherwise}. \end{cases}` |
||
131 | |||
132 | Args: |
||
133 | pop (numpy.ndarray[Individual]): Current population. |
||
134 | ic (int): Index of individual being mutated. |
||
135 | x_b (Individual): Current global best individual. |
||
136 | f (float): Scale factor. |
||
137 | cr (float): Crossover probability. |
||
138 | rnd (mtrand.RandomState): Random generator. |
||
139 | *args (list): Additional arguments. |
||
140 | |||
141 | Returns: |
||
142 | numpy.ndarray: mutated and mixed individual. |
||
143 | """ |
||
144 | j = rnd.randint(len(pop[ic])) |
||
145 | p = [1 / (len(pop) - 1.0) if i != ic else 0 for i in range(len(pop))] if len(pop) > 4 else None |
||
146 | r = rnd.choice(len(pop), 4, replace=not len(pop) >= 4, p=p) |
||
147 | x = [x_b[i] + f * (pop[r[0]][i] - pop[r[1]][i]) + f * (pop[r[2]][i] - pop[r[3]][i]) if rnd.rand() < cr or i == j else pop[ic][i] for i in range(len(pop[ic]))] |
||
148 | return asarray(x) |
||
149 | |||
150 | View Code Duplication | def CrossCurr2Rand1(pop, ic, x_b, f, cr, rnd=rand, *args): |
|
151 | r"""Mutation strategy with crossover. |
||
152 | |||
153 | Mutation: |
||
154 | Name: de/curr2rand/1 |
||
155 | |||
156 | :math:`\mathbf{v}_{i, G} = \mathbf{x}_{i, G} + F \cdot (\mathbf{x}_{r_1, G} - \mathbf{x}_{r_2, G}) + F \cdot (\mathbf{x}_{r_3, G} - \mathbf{x}_{r_4, G})` |
||
157 | where :math:`r_1, r_2, r_3, r_4` are random indexes representing current population individuals |
||
158 | |||
159 | Crossover: |
||
160 | Name: Binomial crossover |
||
161 | |||
162 | :math:`\mathbf{x}_{i, G+1} = \begin{cases} \mathbf{u}_{i, G+1}, & \text{if $f(\mathbf{u}_{i, G+1}) \leq f(\mathbf{x}_{i, G})$}, \\ \mathbf{x}_{i, G}, & \text{otherwise}. \end{cases}` |
||
163 | |||
164 | Args: |
||
165 | pop (numpy.ndarray[Individual]): Current population. |
||
166 | ic (int): Index of individual being mutated. |
||
167 | x_b (Individual): Current global best individual. |
||
168 | f (float): Scale factor. |
||
169 | cr (float): Crossover probability. |
||
170 | rnd (mtrand.RandomState): Random generator. |
||
171 | *args (list): Additional arguments. |
||
172 | |||
173 | Returns: |
||
174 | numpy.ndarray: mutated and mixed individual. |
||
175 | """ |
||
176 | j = rnd.randint(len(pop[ic])) |
||
177 | p = [1 / (len(pop) - 1.0) if i != ic else 0 for i in range(len(pop))] if len(pop) > 4 else None |
||
178 | r = rnd.choice(len(pop), 4, replace=not len(pop) >= 4, p=p) |
||
179 | x = [pop[ic][i] + f * (pop[r[0]][i] - pop[r[1]][i]) + f * (pop[r[2]][i] - pop[r[3]][i]) if rnd.rand() < cr or i == j else pop[ic][i] for i in range(len(pop[ic]))] |
||
180 | return asarray(x) |
||
181 | |||
182 | def CrossCurr2Best1(pop, ic, x_b, f, cr, rnd=rand, **kwargs): |
||
183 | r"""Mutation strategy with crossover. |
||
184 | |||
185 | Mutation: |
||
186 | Name: de/curr-to-best/1 |
||
187 | |||
188 | :math:`\mathbf{v}_{i, G} = \mathbf{x}_{i, G} + F \cdot (\mathbf{x}_{r_1, G} - \mathbf{x}_{r_2, G}) + F \cdot (\mathbf{x}_{r_3, G} - \mathbf{x}_{r_4, G})` |
||
189 | where :math:`r_1, r_2, r_3, r_4` are random indexes representing current population individuals |
||
190 | |||
191 | Crossover: |
||
192 | Name: Binomial crossover |
||
193 | |||
194 | :math:`\mathbf{x}_{i, G+1} = \begin{cases} \mathbf{u}_{i, G+1}, & \text{if $f(\mathbf{u}_{i, G+1}) \leq f(\mathbf{x}_{i, G})$}, \\ \mathbf{x}_{i, G}, & \text{otherwise}. \end{cases}` |
||
195 | |||
196 | Args: |
||
197 | pop (numpy.ndarray[Individual]): Current population. |
||
198 | ic (int): Index of individual being mutated. |
||
199 | x_b (Individual): Current global best individual. |
||
200 | f (float): Scale factor. |
||
201 | cr (float): Crossover probability. |
||
202 | rnd (mtrand.RandomState): Random generator. |
||
203 | *args (list): Additional arguments. |
||
204 | |||
205 | Returns: |
||
206 | numpy.ndarray: mutated and mixed individual. |
||
207 | """ |
||
208 | j = rnd.randint(len(pop[ic])) |
||
209 | p = [1 / (len(pop) - 1.0) if i != ic else 0 for i in range(len(pop))] if len(pop) > 3 else None |
||
210 | r = rnd.choice(len(pop), 3, replace=not len(pop) >= 3, p=p) |
||
211 | x = [pop[ic][i] + f * (x_b[i] - pop[r[0]][i]) + f * (pop[r[1]][i] - pop[r[2]][i]) if rnd.rand() < cr or i == j else pop[ic][i] for i in range(len(pop[ic]))] |
||
212 | return asarray(x) |
||
213 | |||
214 | class DifferentialEvolution(Algorithm): |
||
215 | r"""Implementation of Differential evolution algorithm. |
||
216 | |||
217 | Algorithm: |
||
218 | Differential evolution algorithm |
||
219 | |||
220 | Date: |
||
221 | 2018 |
||
222 | |||
223 | Author: |
||
224 | Uros Mlakar and Klemen Berkovič |
||
225 | |||
226 | License: |
||
227 | MIT |
||
228 | |||
229 | Reference paper: |
||
230 | Storn, Rainer, and Kenneth Price. "Differential evolution - a simple and efficient heuristic for global optimization over continuous spaces." Journal of global optimization 11.4 (1997): 341-359. |
||
231 | |||
232 | Attributes: |
||
233 | Name (List[str]): List of string of names for algorithm. |
||
234 | F (float): Scale factor. |
||
235 | CR (float): Crossover probability. |
||
236 | CrossMutt (Callable[numpy.ndarray, int, numpy.ndarray, float, float, mtrand.RandomState, Dict[str, Any]]): crossover and mutation strategy. |
||
237 | |||
238 | See Also: |
||
239 | * :class:`NiaPy.algorithms.Algorithm` |
||
240 | """ |
||
241 | Name = ['DifferentialEvolution', 'DE'] |
||
242 | |||
243 | @staticmethod |
||
244 | def typeParameters(): |
||
245 | r"""Get dictionary with functions for checking values of parameters. |
||
246 | |||
247 | Returns: |
||
248 | Dict[str, Callable]: |
||
249 | * F (Callable[[Union[float, int]], bool]): Check for correct value of parameter. |
||
250 | * CR (Callable[[float], bool]): Check for correct value of parameter. |
||
251 | |||
252 | See Also: |
||
253 | * :func:`NiaPy.algorithms.Algorithm.typeParameters` |
||
254 | """ |
||
255 | d = Algorithm.typeParameters() |
||
256 | d.update({ |
||
257 | 'F': lambda x: isinstance(x, (float, int)) and 0 < x <= 2, |
||
258 | 'CR': lambda x: isinstance(x, float) and 0 <= x <= 1 |
||
259 | }) |
||
260 | return d |
||
261 | |||
262 | def setParameters(self, NP=50, F=1, CR=0.8, CrossMutt=CrossRand1, **ukwargs): |
||
263 | r"""Set the algorithm parameters. |
||
264 | |||
265 | Arguments: |
||
266 | NP (Optional[int]): Population size. |
||
267 | F (Optional[float]): Scaling factor. |
||
268 | CR (Optional[float]): Crossover rate. |
||
269 | CrossMutt (Optional[Callable[[numpy.ndarray, int, numpy.ndarray, float, float, mtrand.RandomState, list], numpy.ndarray]]): Crossover and mutation strategy. |
||
270 | ukwargs (Dict[str, Any]): Additional arguments. |
||
271 | |||
272 | See Also: |
||
273 | * :func:`NiaPy.algorithms.Algorithm.setParameters` |
||
274 | """ |
||
275 | Algorithm.setParameters(self, NP=NP, InitPopFunc=ukwargs.pop('InitPopFunc', defaultIndividualInit), itype=ukwargs.pop('itype', Individual), **ukwargs) |
||
276 | self.F, self.CR, self.CrossMutt = F, CR, CrossMutt |
||
277 | if ukwargs: logger.info('Unused arguments: %s' % (ukwargs)) |
||
278 | |||
279 | def evolve(self, pop, xb, task, **kwargs): |
||
280 | r"""Evolve population. |
||
281 | |||
282 | Args: |
||
283 | pop (numpy.ndarray[Individual]): Current population. |
||
284 | xb (Individual): Current best individual. |
||
285 | task (Task): Optimization task. |
||
286 | **kwargs (Dict[str, Any]): Additional arguments. |
||
287 | |||
288 | Returns: |
||
289 | numpy.ndarray[Individual]: New evolved populations. |
||
290 | """ |
||
291 | return objects2array([self.itype(x=self.CrossMutt(pop, i, xb, self.F, self.CR, self.Rand), task=task, rnd=self.Rand, e=True) for i in range(len(pop))]) |
||
292 | |||
293 | def selection(self, pop, npop, **kwargs): |
||
294 | r"""Operator for selection. |
||
295 | |||
296 | Args: |
||
297 | pop (numpy.ndarray[Individual]): Current population. |
||
298 | npop (numpy.ndarray[Individual]): New Population. |
||
299 | **kwargs (Dict[str, Any]): Additional arguments. |
||
300 | |||
301 | Returns: |
||
302 | numpy.ndarray[Individual]: New selected individuals. |
||
303 | """ |
||
304 | return objects2array([e if e.f < pop[i].f else pop[i] for i, e in enumerate(npop)]) |
||
305 | |||
306 | def postSelection(self, pop, task, xb=None, **kwargs): |
||
307 | r"""Apply additional operation after selection. |
||
308 | |||
309 | Args: |
||
310 | pop (numpy.ndarray[Individual]): Current population. |
||
311 | task (Task): Optimization task. |
||
312 | xb (Optional[Individual]): Global best solution. |
||
313 | **kwargs (Dict[str, Any]): Additional arguments. |
||
314 | |||
315 | Returns: |
||
316 | numpy.ndarray[Individual]: New population. |
||
317 | """ |
||
318 | return pop |
||
319 | |||
320 | def runIteration(self, task, pop, fpop, xb, fxb, **dparams): |
||
321 | r"""Core function of Differential Evolution algorithm. |
||
322 | |||
323 | Args: |
||
324 | task (Task): Optimization task. |
||
325 | pop (numpy.ndarray[Initialized]): Current population. |
||
326 | fpop (numpy.ndarray[float]): Current populations fitness/function values. |
||
327 | xb (Individual): Current best individual. |
||
328 | fxb (float): Current best individual function/fitness value. |
||
329 | **dparams (Dict[str, Any]): Additional arguments. |
||
330 | |||
331 | Returns: |
||
332 | Tuple[numpy.ndarray[Individual], numpy.ndarray[float], Dict[str, Any]]: |
||
333 | 1. New population. |
||
334 | 2. New population fitness/function values. |
||
335 | 3. Additional arguments. |
||
336 | |||
337 | See Also: |
||
338 | * :func:`NiaPy.algorithms.basic.DifferentialEvolution.evolve` |
||
339 | * :func:`NiaPy.algorithms.basic.DifferentialEvolution.selection` |
||
340 | * :func:`NiaPy.algorithms.basic.DifferentialEvolution.postSelection` |
||
341 | """ |
||
342 | npop = self.evolve(pop, xb, task) |
||
343 | pop = self.selection(pop, npop) |
||
344 | pop = self.postSelection(pop, task, xb=xb) |
||
345 | return pop, asarray([x.f for x in pop]), {} |
||
346 | |||
347 | class CrowdingDifferentialEvolution(DifferentialEvolution): |
||
348 | r"""Implementation of Differential evolution algorithm with multiple mutation strateys. |
||
349 | |||
350 | Algorithm: |
||
351 | Implementation of Differential evolution algorithm with multiple mutation strateys |
||
352 | |||
353 | Date: |
||
354 | 2018 |
||
355 | |||
356 | Author: |
||
357 | Klemen Berkovič |
||
358 | |||
359 | License: |
||
360 | MIT |
||
361 | |||
362 | Attributes: |
||
363 | Name (List[str]): List of strings representing algorithm name. |
||
364 | CrowPop (float): Proportion of range for cowding. |
||
365 | |||
366 | See Also: |
||
367 | * :class:`NiaPy.algorithms.basic.DifferentialEvolution` |
||
368 | """ |
||
369 | Name = ['CrowdingDifferentialEvolution', 'CDE'] |
||
370 | |||
371 | def __init__(self, **kwargs): |
||
372 | r"""Init CrowdingDifferentialEvolution algorithm. |
||
373 | |||
374 | Args: |
||
375 | **kwargs (Dict[str, Any]): Additional arguments. |
||
376 | |||
377 | See Also: |
||
378 | * :func:`NiaPy.algorithms.basic.DifferentialEvolution.__init__` |
||
379 | """ |
||
380 | DifferentialEvolution.__init__(self, **kwargs) |
||
381 | |||
382 | def setParameters(self, CrowPop=0.1, **ukwargs): |
||
383 | r"""Set core parameters of algorithm. |
||
384 | |||
385 | Args: |
||
386 | CrowPop (Optional[float]): Crowding distance. |
||
387 | **ukwargs: Additional arguments. |
||
388 | |||
389 | See Also: |
||
390 | * :func:`NiaPy.algorithms.basic.DifferentialEvolution.setParameters` |
||
391 | """ |
||
392 | DifferentialEvolution.setParameters(self, **ukwargs) |
||
393 | self.CrowPop = CrowPop |
||
394 | |||
395 | def selection(self, pop, npop): |
||
396 | r"""Operator for selection of individuals. |
||
397 | |||
398 | Args: |
||
399 | pop (numpy.ndarray[Individual]): Current population. |
||
400 | npop (numpy.ndarray[Individual]): New population. |
||
401 | |||
402 | Returns: |
||
403 | numpy.ndarray[Individual]: New population. |
||
404 | """ |
||
405 | P = [] |
||
406 | for e in npop: |
||
407 | i = argmin([euclidean(e, f) for f in pop]) |
||
408 | P.append(pop[i] if pop[i].f < e.f else e) |
||
409 | return asarray(P) |
||
410 | |||
411 | View Code Duplication | class DynNpDifferentialEvolution(DifferentialEvolution): |
|
412 | r"""Implementation of Dynamic poulation size Differential evolution algorithm. |
||
413 | |||
414 | Algorithm: |
||
415 | Dynamic poulation size Differential evolution algorithm |
||
416 | |||
417 | Date: |
||
418 | 2018 |
||
419 | |||
420 | Author: |
||
421 | Klemen Berkovič |
||
422 | |||
423 | License: |
||
424 | MIT |
||
425 | |||
426 | Attributes: |
||
427 | Name (List[str]): List of strings representing algorithm names. |
||
428 | pmax (int): TODO |
||
429 | rp (int): TODO |
||
430 | |||
431 | See Also: |
||
432 | * :class:`NiaPy.algorithms.basic.DifferentialEvolution` |
||
433 | """ |
||
434 | Name = ['DynNpDifferentialEvolution', 'dynNpDE'] |
||
435 | |||
436 | @staticmethod |
||
437 | def typeParameters(): |
||
438 | r"""Get dictionary with functions for checking values of parameters. |
||
439 | |||
440 | Returns: |
||
441 | Dict[str, Callable]: |
||
442 | * rp (Callable[[Union[float, int]], bool]): TODO |
||
443 | * pmax (Callable[[int], bool]): TODO |
||
444 | |||
445 | See Also: |
||
446 | * :func:`NiaPy.algorithms.basic.DifferentialEvolution.typeParameters` |
||
447 | """ |
||
448 | r = DifferentialEvolution.typeParameters() |
||
449 | r['rp'] = lambda x: isinstance(x, (float, int)) and x > 0 |
||
450 | r['pmax'] = lambda x: isinstance(x, int) and x > 0 |
||
451 | return r |
||
452 | |||
453 | def setParameters(self, pmax=50, rp=3, **ukwargs): |
||
454 | r"""Set the algorithm parameters. |
||
455 | |||
456 | Arguments: |
||
457 | pmax (Optional[int]): TODO |
||
458 | rp (Optional[int]): TODO |
||
459 | |||
460 | See Also: |
||
461 | * :func:`NiaPy.algorithms.basic.DifferentialEvolution.setParameters` |
||
462 | """ |
||
463 | DifferentialEvolution.setParameters(self, **ukwargs) |
||
464 | self.pmax, self.rp = pmax, rp |
||
465 | if ukwargs: logger.info('Unused arguments: %s' % (ukwargs)) |
||
466 | |||
467 | def postSelection(self, pop, task, **kwargs): |
||
468 | r"""Post selection operator. |
||
469 | |||
470 | In this algorithm the post selection operator decrements the population at specific iterations/generations. |
||
471 | |||
472 | Args: |
||
473 | pop (numpy.ndarray[Individual]): Current population. |
||
474 | task (Task): Optimization task. |
||
475 | kwargs (Dict[str, Any]): Additional arguments. |
||
476 | |||
477 | Returns: |
||
478 | numpy.ndarray[Individual]: Changed current population. |
||
479 | """ |
||
480 | Gr = task.nFES // (self.pmax * len(pop)) + self.rp |
||
481 | nNP = len(pop) // 2 |
||
482 | if task.Iters == Gr and len(pop) > 3: pop = objects2array([pop[i] if pop[i].f < pop[i + nNP].f else pop[i + nNP] for i in range(nNP)]) |
||
483 | return pop |
||
484 | |||
485 | def proportional(Lt_min, Lt_max, mu, x_f, avg, *args): |
||
486 | r"""Proportional calculation of age of individual. |
||
487 | |||
488 | Args: |
||
489 | Lt_min (int): Minimal life time. |
||
490 | Lt_max (int): Maximal life time. |
||
491 | mu (float): TODO |
||
492 | x_f (float): Individuals function/fitness value. |
||
493 | avg (float): Average fitness/function value of current population. |
||
494 | *args (list): Additional arguments. |
||
495 | |||
496 | Returns: |
||
497 | int: Age of individual. |
||
498 | """ |
||
499 | return min(Lt_min + mu * avg / x_f, Lt_max) |
||
500 | |||
501 | def linear(Lt_min, Lt_max, mu, x_f, avg, x_gw, x_gb, *args): |
||
502 | r"""Linear calculation of age of individual. |
||
503 | |||
504 | Args: |
||
505 | Lt_min (int): Minimal life time. |
||
506 | Lt_max (int): Maximal life time. |
||
507 | mu (float): TODO |
||
508 | x_f (float): Individual function/fitness value. |
||
509 | avg (float): Average fitness/function value. |
||
510 | x_gw (float): Global worst fitness/function value. |
||
511 | x_gb (float): Global best fitness/function value. |
||
512 | *args (list): Additional arguments. |
||
513 | |||
514 | Returns: |
||
515 | int: Age of individual. |
||
516 | """ |
||
517 | return Lt_min + 2 * mu * (x_f - x_gw) / (x_gb - x_gw) |
||
518 | |||
519 | def bilinear(Lt_min, Lt_max, mu, x_f, avg, x_gw, x_gb, *args): |
||
520 | r"""Bilinear calculation of age of individual. |
||
521 | |||
522 | Args: |
||
523 | Lt_min (int): Minimal life time. |
||
524 | Lt_max (int): Maximal life time. |
||
525 | mu (float): TODO |
||
526 | x_f (float): Individual function/fitness value. |
||
527 | avg (float): Average fitness/function value. |
||
528 | x_gw (float): Global worst fitness/function value. |
||
529 | x_gb (float): Global best fitness/function value. |
||
530 | *args (list): Additional arguments. |
||
531 | |||
532 | Returns: |
||
533 | int: Age of individual. |
||
534 | """ |
||
535 | if avg < x_f: return Lt_min + mu * (x_f - x_gw) / (x_gb - x_gw) |
||
536 | return 0.5 * (Lt_min + Lt_max) + mu * (x_f - avg) / (x_gb - avg) |
||
537 | |||
538 | class AgingIndividual(Individual): |
||
539 | r"""Individual with aging. |
||
540 | |||
541 | Attributes: |
||
542 | age (int): Age of individual. |
||
543 | |||
544 | See Also: |
||
545 | * :class:`NiaPy.algorithms.Individual` |
||
546 | """ |
||
547 | age = 0 |
||
548 | |||
549 | def __init__(self, **kwargs): |
||
550 | r"""Init Aging Individual. |
||
551 | |||
552 | Args: |
||
553 | **kwargs (Dict[str, Any]): Additional arguments sent to parent. |
||
554 | |||
555 | See Also: |
||
556 | * :func:`NiaPy.algorithms.Individual.__init__` |
||
557 | """ |
||
558 | Individual.__init__(self, **kwargs) |
||
559 | self.age = 0 |
||
560 | |||
561 | class AgingNpDifferentialEvolution(DifferentialEvolution): |
||
562 | r"""Implementation of Differential evolution algorithm with aging individuals. |
||
563 | |||
564 | Algorithm: |
||
565 | Differential evolution algorithm with dynamic population size that is defined by the quality of population |
||
566 | |||
567 | Date: |
||
568 | 2018 |
||
569 | |||
570 | Author: |
||
571 | Klemen Berkovič |
||
572 | |||
573 | License: |
||
574 | MIT |
||
575 | |||
576 | Attributes: |
||
577 | Name (List[str]): list of strings representing algorithm names. |
||
578 | Lt_min (int): minimal age of individual. |
||
579 | Lt_max (int): maximal age of individual. |
||
580 | delta_np (float): TODO |
||
581 | omega (float): TODO |
||
582 | mu (int): Mean of individual max and min age. |
||
583 | age (Callable[[int, int, float, float, float, float, float], int]): Function for calculation of age for individual. |
||
584 | |||
585 | See Also: |
||
586 | * :class:`NiaPy.algorithms.basic.DifferentialEvolution` |
||
587 | """ |
||
588 | Name = ['AgingNpDifferentialEvolution', 'ANpDE'] |
||
589 | |||
590 | @staticmethod |
||
591 | def typeParameters(): |
||
592 | r"""Get dictionary with functions for checking values of parameters. |
||
593 | |||
594 | Returns: |
||
595 | Dict[str, Callable]: |
||
596 | * Lt_min (Callable[[int], bool]): TODO |
||
597 | * Lt_max (Callable[[int], bool]): TODO |
||
598 | * delta_np (Callable[[float], bool]): TODO |
||
599 | * omega (Callable[[float], bool]): TODO |
||
600 | |||
601 | See Also: |
||
602 | * :func:`NiaPy.algorithms.basic.DifferentialEvolution.typeParameters` |
||
603 | """ |
||
604 | r = DifferentialEvolution.typeParameters() |
||
605 | r.update({ |
||
606 | 'Lt_min': lambda x: isinstance(x, int) and x >= 0, |
||
607 | 'Lt_max': lambda x: isinstance(x, int) and x >= 0, |
||
608 | 'delta_np': lambda x: isinstance(x, float) and 0 <= x <= 1, |
||
609 | 'omega': lambda x: isinstance(x, float) and x >= 0 |
||
610 | }) |
||
611 | return r |
||
612 | |||
613 | def setParameters(self, Lt_min=0, Lt_max=12, delta_np=0.3, omega=0.3, age=proportional, CrossMutt=CrossBest1, **ukwargs): |
||
614 | r"""Set the algorithm parameters. |
||
615 | |||
616 | Arguments: |
||
617 | Lt_min (Optional[int]): Minimu life time. |
||
618 | Lt_max (Optional[int]): Maximum life time. |
||
619 | age (Optional[Callable[[int, int, float, float, float, float, float], int]]): Function for calculation of age for individual. |
||
620 | |||
621 | See Also: |
||
622 | * :func:`NiaPy.algorithms.basic.DifferentialEvolution.setParameters` |
||
623 | """ |
||
624 | DifferentialEvolution.setParameters(self, itype=AgingIndividual, **ukwargs) |
||
625 | self.Lt_min, self.Lt_max, self.age, self.delta_np, self.omega = Lt_min, Lt_max, age, delta_np, omega |
||
626 | self.mu = abs(self.Lt_max - self.Lt_min) / 2 |
||
627 | if ukwargs: logger.info('Unused arguments: %s' % (ukwargs)) |
||
628 | |||
629 | def deltaPopE(self, t): |
||
630 | r"""Calculate how many individuals are going to dye. |
||
631 | |||
632 | Args: |
||
633 | t (float): TODO |
||
634 | |||
635 | Returns: |
||
636 | float: Number of individuals to dye. |
||
637 | """ |
||
638 | return self.delta_np * abs(cos(t)) |
||
639 | |||
640 | def deltaPopC(self, t): |
||
641 | r"""Calculate how many individuals are going to be created. |
||
642 | |||
643 | Args: |
||
644 | t (float): TODO |
||
645 | |||
646 | Returns: |
||
647 | float: TODO |
||
648 | """ |
||
649 | return self.delta_np * abs(cos(t + 78)) |
||
650 | |||
651 | def aging(self, task, pop): |
||
652 | r"""Apply aging to individuals. |
||
653 | |||
654 | Args: |
||
655 | task (Task): Optimization task. |
||
656 | pop (numpy.ndarray[Individual]): Current population. |
||
657 | |||
658 | Returns: |
||
659 | numpy.ndarray[Individual]: New population. |
||
660 | """ |
||
661 | fpop = asarray([x.f for x in pop]) |
||
662 | x_b, x_w = pop[argmin(fpop)], pop[argmax(fpop)] |
||
663 | avg, npop = mean(fpop), [] |
||
664 | for x in pop: |
||
665 | x.age += 1 |
||
666 | Lt = round(self.age(self.Lt_min, self.Lt_max, self.mu, x.f, avg, x_w, x_b)) |
||
667 | if x.age <= Lt: npop.append(x) |
||
668 | if len(npop) != 0: npop = objects2array([self.itype(task=task, rnd=self.Rand, e=True) for _i in range(len(pop))]) |
||
669 | return npop |
||
670 | |||
671 | def popIncrement(self, pop, task): |
||
672 | r"""Increment population. |
||
673 | |||
674 | Args: |
||
675 | pop (numpy.ndarray[Individual]): Current population. |
||
676 | task (Task): Optimization task. |
||
677 | |||
678 | Returns: |
||
679 | numpy.ndarray[Individual]: Increased population. |
||
680 | """ |
||
681 | deltapop = int(round(max(1, self.NP * self.deltaPopE(task.Iters)))) |
||
682 | return objects2array([self.itype(task=task, rnd=self.Rand, e=True) for _ in range(deltapop)]) |
||
683 | |||
684 | def popDecrement(self, pop, task): |
||
685 | r"""Decrement population. |
||
686 | |||
687 | Args: |
||
688 | pop (numpy.ndarray): Current population. |
||
689 | task (Task): Optimization task. |
||
690 | |||
691 | Returns: |
||
692 | numpy.ndarray[Individual]: Decreased population. |
||
693 | """ |
||
694 | deltapop = int(round(max(1, self.NP * self.deltaPopC(task.Iters)))) |
||
695 | if len(pop) - deltapop <= 0: return pop |
||
696 | ni = self.Rand.choice(len(pop), deltapop, replace=False) |
||
697 | npop = [] |
||
698 | for i, e in enumerate(pop): |
||
699 | if i not in ni: npop.append(e) |
||
700 | elif self.rand() >= self.omega: npop.append(e) |
||
701 | return objects2array(npop) |
||
702 | |||
703 | def runIteration(self, task, pop, fpop, xb, fxb, **dparams): |
||
704 | r"""Core function of AgingNpDifferentialEvolution algorithm. |
||
705 | |||
706 | Args: |
||
707 | task (Task): Optimization task |
||
708 | pop (numpy.ndarray[Individual]): Current population |
||
709 | fpop (numpy.ndarray[float]): Current populations function/fitness values |
||
710 | xb (Individual): Current best individual |
||
711 | fxb (float): Current best individual function/fitness value |
||
712 | **dparams (Dict[str, Any]): Additional parameters |
||
713 | |||
714 | Returns: |
||
715 | Tuple[numpy.ndarray[Individual], numpy.ndarray[float], Dict[str, Any]]: |
||
716 | 1. New population |
||
717 | 2. New population fitness/function values |
||
718 | 3. Additional parameters |
||
719 | """ |
||
720 | npop = self.evolve(pop, xb, task) |
||
721 | npop = self.selection(pop, npop) |
||
722 | npop = append(npop, self.popIncrement(pop, task)) |
||
723 | pop = self.aging(task, npop) |
||
724 | if len(pop) > self.NP: pop = self.popDecrement(pop, task) |
||
725 | return pop, [x.f for x in pop], {} |
||
726 | |||
727 | def multiMutations(pop, i, xb, F, CR, rnd, task, itype, strategies, **kwargs): |
||
728 | r"""Mutation strategy that takes more than one strategy and applys them to individual. |
||
729 | |||
730 | Args: |
||
731 | pop (numpy.ndarray[Individual]): Current population. |
||
732 | i (int): Index of current individual. |
||
733 | xb (Individual): Current best individual. |
||
734 | F (float): Scale factor. |
||
735 | CR (float): Crossover probability. |
||
736 | rnd (mtrand.RandomState): Random generator. |
||
737 | task (Task): Optimization task. |
||
738 | IndividualType (Individual): Individual type used in algorithm. |
||
739 | strategies (Iterable[Callable[[numpy.ndarray[Individual], int, Individual, float, float, mtrand.RandomState], numpy.ndarray[Individual]]]): List of mutation strategies. |
||
740 | **kwargs (Dict[str, Any]): Additional arguments. |
||
741 | |||
742 | Returns: |
||
743 | Individual: Best individual from applyed mutations strategies. |
||
744 | """ |
||
745 | L = [itype(x=strategy(pop, i, xb, F, CR, rnd=rnd), task=task, e=True, rnd=rnd) for strategy in strategies] |
||
746 | return L[argmin([x.f for x in L])] |
||
747 | |||
748 | class MultiStrategyDifferentialEvolution(DifferentialEvolution): |
||
749 | r"""Implementation of Differential evolution algorithm with multiple mutation strateys. |
||
750 | |||
751 | Algorithm: |
||
752 | Implementation of Differential evolution algorithm with multiple mutation strateys |
||
753 | |||
754 | Date: |
||
755 | 2018 |
||
756 | |||
757 | Author: |
||
758 | Klemen Berkovič |
||
759 | |||
760 | License: |
||
761 | MIT |
||
762 | |||
763 | Attributes: |
||
764 | Name (List[str]): List of strings representing algorithm names. |
||
765 | strategies (Iterable[Callable[[numpy.ndarray[Individual], int, Individual, float, float, mtrand.RandomState], numpy.ndarray[Individual]]]): List of mutation strategies. |
||
766 | CrossMutt (Callable[[numpy.ndarray[Individual], int, Individual, float, float, Task, Individual, Iterable[Callable[[numpy.ndarray, int, numpy.ndarray, float, float, mtrand.RandomState, Dict[str, Any]], Individual]]], Individual]): Multi crossover and mutation combiner function. |
||
767 | |||
768 | See Also: |
||
769 | * :class:`NiaPy.algorithms.basic.DifferentialEvolution` |
||
770 | """ |
||
771 | Name = ['MultiStrategyDifferentialEvolution', 'MsDE'] |
||
772 | |||
773 | @staticmethod |
||
774 | def typeParameters(): |
||
775 | r"""Get dictionary with functions for checking values of parameters. |
||
776 | |||
777 | Returns: |
||
778 | Dict[str, Callable]: |
||
779 | * CrossMutt (Callable[[Callable, bool]): TODO |
||
780 | |||
781 | See Also: |
||
782 | * :func:`NiaPy.algorithms.basic.DifferentialEvolution.typeParameters` |
||
783 | """ |
||
784 | r = DifferentialEvolution.typeParameters() |
||
785 | r.pop('CrossMutt', None) |
||
786 | # TODO add constraint method for selection of stratgy methos |
||
787 | return r |
||
788 | |||
789 | def setParameters(self, strategies=(CrossRand1, CrossBest1, CrossCurr2Best1, CrossRand2), **ukwargs): |
||
790 | r"""Set the arguments of the algorithm. |
||
791 | |||
792 | Arguments: |
||
793 | strategies (Optional[Iterable[Callable[[numpy.ndarray[Individual], int, Individual, float, float, mtrand.RandomState], numpy.ndarray[Individual]]]]): List of mutation strategyis. |
||
794 | CrossMutt (Optional[Callable[[numpy.ndarray[Individual], int, Individual, float, float, Task, Individual, Iterable[Callable[[numpy.ndarray, int, numpy.ndarray, float, float, mtrand.RandomState, Dict[str, Any]], Individual]]], Individual]]): Multi crossover and mutation combiner function. |
||
795 | |||
796 | See Also: |
||
797 | * :func:`NiaPy.algorithms.basic.DifferentialEvolution.setParameters` |
||
798 | """ |
||
799 | DifferentialEvolution.setParameters(self, CrossMutt=multiMutations, **ukwargs) |
||
800 | self.strategies = strategies |
||
801 | |||
802 | View Code Duplication | def evolve(self, pop, xb, task, **kwargs): |
|
803 | r"""Evolve population with the help multiple mutation strategies. |
||
804 | |||
805 | Args: |
||
806 | pop (numpy.ndarray[Individual]): Current population. |
||
807 | xb (Individual): Current best individual. |
||
808 | task (Task): Optimization task. |
||
809 | **kwargs (Dict[str, Any]): Additional arguments. |
||
810 | |||
811 | Returns: |
||
812 | numpy.ndarray[Individual]: New population of individuals. |
||
813 | """ |
||
814 | return objects2array([self.CrossMutt(pop, i, xb, self.F, self.CR, self.Rand, task, self.itype, self.strategies) for i in range(len(pop))]) |
||
815 | |||
816 | class DynNpMultiStrategyDifferentialEvolution(MultiStrategyDifferentialEvolution, DynNpDifferentialEvolution): |
||
817 | r"""Implementation of Dynamic population size Differential evolution algorithm with dynamic population size that is defined by the quality of population. |
||
818 | |||
819 | Algorithm: |
||
820 | Dynamic population size Differential evolution algorithm with dynamic population size that is defined by the quality of population |
||
821 | |||
822 | Date: |
||
823 | 2018 |
||
824 | |||
825 | Author: |
||
826 | Klemen Berkovič |
||
827 | |||
828 | License: |
||
829 | MIT |
||
830 | |||
831 | Attributes: |
||
832 | Name (List[str]): List of strings representing algorithm name. |
||
833 | |||
834 | See Also: |
||
835 | * :class:`NiaPy.algorithms.basic.MultiStrategyDifferentialEvolution` |
||
836 | * :class:`NiaPy.algorithms.basic.DynNpDifferentialEvolution` |
||
837 | """ |
||
838 | Name = ['DynNpMultiStrategyDifferentialEvolution', 'dynNpMsDE'] |
||
839 | |||
840 | @staticmethod |
||
841 | def typeParameters(): |
||
842 | r"""Get dictionary with functions for checking values of parameters. |
||
843 | |||
844 | Returns: |
||
845 | Dict[str, Callable]: |
||
846 | * rp (Callable[[Union[float, int]], bool]): TODO |
||
847 | * pmax (Callable[[int], bool]): TODO |
||
848 | |||
849 | See Also: |
||
850 | * :func:`NiaPy.algorithms.basic.MultiStrategyDifferentialEvolution.typeParameters` |
||
851 | """ |
||
852 | r = MultiStrategyDifferentialEvolution.typeParameters() |
||
853 | r['rp'] = lambda x: isinstance(x, (float, int)) and x > 0 |
||
854 | r['pmax'] = lambda x: isinstance(x, int) and x > 0 |
||
855 | return r |
||
856 | |||
857 | def setParameters(self, **ukwargs): |
||
858 | r"""Set the arguments of the algorithm. |
||
859 | |||
860 | Args: |
||
861 | ukwargs (Dict[str, Any]): Additional arguments. |
||
862 | |||
863 | See Also: |
||
864 | * :func:`NiaPy.algorithms.basic.MultiStrategyDifferentialEvolution.setParameters` |
||
865 | * :func:`NiaPy.algorithms.basic.DynNpDifferentialEvolution.setParameters` |
||
866 | """ |
||
867 | DynNpDifferentialEvolution.setParameters(self, **ukwargs) |
||
868 | MultiStrategyDifferentialEvolution.setParameters(self, **ukwargs) |
||
869 | |||
870 | def postSelection(self, pop, task, **kwargs): |
||
871 | r"""Post selection operator. |
||
872 | |||
873 | Args: |
||
874 | pop (numpy.ndarray[Individual]): Current population. |
||
875 | task (Task): Optimization task. |
||
876 | **kwargs (Dict[str, Any]): Additional arguments. |
||
877 | |||
878 | Returns: |
||
879 | numpy.ndarray: New population. |
||
880 | |||
881 | See Also: |
||
882 | * :func:`NiaPy.algorithms.basic.DynNpDifferentialEvolution.postSelection` |
||
883 | """ |
||
884 | return DynNpDifferentialEvolution.postSelection(self, pop, task) |
||
885 | |||
886 | class AgingNpMultiMutationDifferentialEvolution(AgingNpDifferentialEvolution, MultiStrategyDifferentialEvolution): |
||
887 | r"""Implementation of Differential evolution algorithm with aging individuals. |
||
888 | |||
889 | Algorithm: |
||
890 | Differential evolution algorithm with dynamic population size that is defined by the quality of population |
||
891 | |||
892 | Date: |
||
893 | 2018 |
||
894 | |||
895 | Author: |
||
896 | Klemen Berkovič |
||
897 | |||
898 | License: |
||
899 | MIT |
||
900 | |||
901 | Attributes: |
||
902 | Name (List[str]): List of strings representing algorithm names |
||
903 | |||
904 | See Also: |
||
905 | * :class:`NiaPy.algorithms.basic.AgingNpDifferentialEvolution` |
||
906 | * :class:`NiaPy.algorithms.basic.MultiStrategyDifferentialEvolution` |
||
907 | """ |
||
908 | Name = ['AgingNpMultiMutationDifferentialEvolution', 'ANpMSDE'] |
||
909 | |||
910 | @staticmethod |
||
911 | def typeParameters(): |
||
912 | r"""Get dictionary with functions for checking values of parameters. |
||
913 | |||
914 | Returns: |
||
915 | Dict[str, Callable]: |
||
916 | * rp (Callable[[Union[float, int]], bool]): TODO |
||
917 | * pmax (Callable[[int], bool]): TODO |
||
918 | |||
919 | See Also: |
||
920 | * :func:`NiaPy.algorithms.basic.MultiStrategyDifferentialEvolution.typeParameters` |
||
921 | """ |
||
922 | r = AgingNpDifferentialEvolution.typeParameters() |
||
923 | # TODO add other parameters to data check list |
||
924 | return r |
||
925 | |||
926 | def setParameters(self, **ukwargs): |
||
927 | r"""Set core parameter arguments. |
||
928 | |||
929 | Args: |
||
930 | **ukwargs (Dict[str, Any]): Additional arguments. |
||
931 | |||
932 | See Also: |
||
933 | * :func:`NiaPy.algorithms.basic.AgingNpDifferentialEvolution.setParameters` |
||
934 | * :func:`NiaPy.algorithms.basic.MultiStrategyDifferentialEvolution.setParameters` |
||
935 | """ |
||
936 | AgingNpDifferentialEvolution.setParameters(self, **ukwargs) |
||
937 | MultiStrategyDifferentialEvolution.setParameters(self, stratgeys=(CrossRand1, CrossBest1, CrossCurr2Rand1, CrossRand2), itype=AgingIndividual, **ukwargs) |
||
938 | |||
939 | def evolve(self, pop, xb, task, **kwargs): |
||
940 | r"""Evolve current population. |
||
941 | |||
942 | Args: |
||
943 | pop (numpy.ndarray[Individual]): Current population. |
||
944 | xb (Individual): Global best individual. |
||
945 | task (Task): Optimization task. |
||
946 | **kwargs (Dict[str, Any]): Additional arguments. |
||
947 | |||
948 | Returns: |
||
949 | numpy.ndarray[Individual]: New population of individuals. |
||
950 | """ |
||
951 | return MultiStrategyDifferentialEvolution.evolve(self, pop, xb, task, **kwargs) |
||
952 | |||
954 |