Passed
Push — master ( 39ef7f...f70242 )
by Simon
01:57
created

ParticleSwarmOptimizer._move_positioners()   A

Complexity

Conditions 2

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 12
rs 9.95
c 0
b 0
f 0
cc 2
nop 3
1
# Author: Simon Blanke
2
# Email: [email protected]
3
# License: MIT License
4
5
6
import random
7
8
import numpy as np
9
10
from ...base_optimizer import BaseOptimizer
11
from ...base_positioner import BasePositioner
12
13
14
class ParticleSwarmOptimizer(BaseOptimizer):
15
    def __init__(self, *args, **kwargs):
16
        super().__init__(*args, **kwargs)
17
18
    def _init_particles(self, _cand_):
19
        _p_list_ = [Particle() for _ in range(self._arg_.n_part)]
20
        for i, _p_ in enumerate(_p_list_):
21
            _p_.nr = i
22
            _p_.pos_current = _cand_._space_.get_random_pos()
23
            _p_.pos_best = _p_.pos_current
24
            _p_.velo = np.zeros(len(_cand_._space_.para_space))
25
26
        return _p_list_
27
28
    def _move_positioners(self, _cand_, _p_list_):
29
        for _p_ in _p_list_:
30
            r1, r2 = random.random(), random.random()
31
32
            A = self._arg_.w * _p_.velo
33
            B = self._arg_.c_k * r1 * np.subtract(_p_.pos_best, _p_.pos_current)
34
            C = self._arg_.c_s * r2 * np.subtract(_cand_.pos_best, _p_.pos_current)
35
36
            new_velocity = A + B + C
37
38
            _p_.velo = new_velocity
39
            _p_.pos_new = _p_.move_part(_cand_, _p_.pos_current)
40
41
    def _eval_particles(self, _cand_, _p_list_, X, y):
42
        for _p_ in _p_list_:
43
            _p_.score_new = _cand_.eval_pos(_p_.pos_new, X, y)
44
45
            if _p_.score_new > _cand_.score_best:
46
                _cand_, _p_ = self._update_pos(_cand_, _p_)
47
48
    def _iterate(self, i, _cand_, _p_list_, X, y):
49
        self._move_positioners(_cand_, _p_list_)
50
        self._eval_particles(_cand_, _p_list_, X, y)
51
52
        return _cand_
53
54
    def _init_opt_positioner(self, _cand_, X, y):
55
        _p_list_ = self._init_particles(_cand_)
56
57
        return _p_list_
58
59
60
class Particle(BasePositioner):
61
    def __init__(self):
62
        self.nr = None
63
        self.velo = None
64
65
    def move_part(self, _cand_, pos):
66
        pos_new = (pos + self.velo).astype(int)
67
        # limit movement
68
        n_zeros = [0] * len(_cand_._space_.dim)
69
        return np.clip(pos_new, n_zeros, _cand_._space_.dim)
70