Completed
Push — master ( ce1e03...f67568 )
by Simon
14:21
created

hyperactive.optimizers.population.evolution_strategy   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 107
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 72
dl 0
loc 107
rs 10
c 0
b 0
f 0
wmc 17

11 Methods

Rating   Name   Duplication   Size   Complexity  
A EvolutionStrategyOptimizer._crossover() 0 15 3
A Individual.__init__() 0 2 1
A EvolutionStrategyOptimizer._cross_two_ind() 0 11 3
A EvolutionStrategyOptimizer._move_positioners() 0 6 1
A EvolutionStrategyOptimizer._rank_individuals() 0 9 2
A EvolutionStrategyOptimizer.__init__() 0 6 1
A EvolutionStrategyOptimizer._init_iteration() 0 7 1
A EvolutionStrategyOptimizer._iterate() 0 8 1
A EvolutionStrategyOptimizer._mutate_individuals() 0 4 2
A EvolutionStrategyOptimizer._init_individual() 0 5 1
A EvolutionStrategyOptimizer._select_individuals() 0 8 1
1
# Author: Simon Blanke
2
# Email: [email protected]
3
# License: MIT License
4
5
from math import floor, ceil
6
import numpy as np
7
import random
8
9
from ...base_optimizer import BaseOptimizer
10
from ..local import HillClimbingPositioner
11
12
13
class EvolutionStrategyOptimizer(BaseOptimizer):
14
    def __init__(self, _opt_args_):
15
        super().__init__(_opt_args_)
16
        self.n_positioners = self._opt_args_.individuals
17
18
        self.n_mutations = floor(self.n_positioners * self._opt_args_.mutation_rate)
19
        self.n_crossovers = ceil(self.n_positioners * self._opt_args_.crossover_rate)
20
21
    def _init_individual(self, _cand_):
22
        _p_ = Individual(**self._opt_args_.kwargs_opt)
23
        _p_.move_random(_cand_)
24
25
        return _p_
26
27
    def _mutate_individuals(self, _cand_, mutate_idx):
28
        p_list_mutate = [self.p_list[i] for i in mutate_idx]
29
        for _p_ in p_list_mutate:
30
            _p_.move_climb(_cand_, _p_.pos_new)
31
32
    def _crossover(self, _cand_, cross_idx, replace_idx):
33
        p_list_replace = [self.p_list[i] for i in replace_idx]
34
        for i, _p_ in enumerate(p_list_replace):
35
            j = i + 1
36
            if j == len(cross_idx):
37
                j = 0
38
39
            pos_new = self._cross_two_ind(
40
                [
41
                    [self.p_list[i] for i in cross_idx][i],
42
                    [self.p_list[i] for i in cross_idx][j],
43
                ]
44
            )
45
46
            _p_.pos_new = pos_new
47
48
    def _cross_two_ind(self, p_list):
49
        pos_new = []
50
51
        for pos1, pos2 in zip(p_list[0].pos_new, p_list[1].pos_new):
52
            rand = random.randint(0, 1)
53
            if rand == 0:
54
                pos_new.append(pos1)
55
            else:
56
                pos_new.append(pos2)
57
58
        return np.array(pos_new)
59
60
    def _move_positioners(self, _cand_):
61
        idx_sorted_ind = self._rank_individuals()
62
        mutate_idx, cross_idx, replace_idx = self._select_individuals(idx_sorted_ind)
63
64
        self._crossover(_cand_, cross_idx, replace_idx)
65
        self._mutate_individuals(_cand_, mutate_idx)
66
67
    def _rank_individuals(self):
68
        scores_list = []
69
        for _p_ in self.p_list:
70
            scores_list.append(_p_.score_current)
71
72
        scores_np = np.array(scores_list)
73
        idx_sorted_ind = list(scores_np.argsort()[::-1])
74
75
        return idx_sorted_ind
76
77
    def _select_individuals(self, index_best):
78
        mutate_idx = index_best[: self.n_mutations]
79
        cross_idx = index_best[: self.n_crossovers]
80
81
        n = self.n_crossovers
82
        replace_idx = index_best[-n:]
83
84
        return mutate_idx, cross_idx, replace_idx
85
86
    def _iterate(self, i, _cand_):
87
        _p_current = self.p_list[i % self.n_positioners]
88
89
        self._move_positioners(_cand_)
90
        self._optimizer_eval(_cand_, _p_current)
91
        self._update_pos(_cand_, _p_current)
92
93
        return _cand_
94
95
    def _init_iteration(self, _cand_):
96
        p = self._init_individual(_cand_)
97
98
        self._optimizer_eval(_cand_, p)
99
        self._update_pos(_cand_, p)
100
101
        return p
102
103
104
class Individual(HillClimbingPositioner):
105
    def __init__(self, *args, **kwargs):
106
        super().__init__(*args, **kwargs)
107