Completed
Push — master ( 1d68af...e525d3 )
by Simon
01:31
created

ParticleSwarmOptimizer._eval_particles()   A

Complexity

Conditions 3

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 3
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, _main_args_, _opt_args_):
16
        super().__init__(_main_args_, _opt_args_)
17
18
    def _init_particles(self, _cand_):
19
        _p_list_ = [Particle() for _ in range(self._opt_args_.n_particles)]
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_.search_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._opt_args_.inertia * _p_.velo
33
            B = (
34
                self._opt_args_.cognitive_weight
35
                * r1
36
                * np.subtract(_p_.pos_best, _p_.pos_current)
37
            )
38
            C = (
39
                self._opt_args_.social_weight
40
                * r2
41
                * np.subtract(_cand_.pos_best, _p_.pos_current)
42
            )
43
44
            new_velocity = A + B + C
45
46
            _p_.velo = new_velocity
47
            _p_.pos_new = _p_.move_part(_cand_, _p_.pos_current)
48
49
    def _eval_particle(self, _cand_, _p_):
50
        _p_.score_new = _cand_.eval_pos(_p_.pos_new)
51
52
        if _p_.score_new > _cand_.score_best:
53
            _cand_, _p_ = self._update_pos(_cand_, _p_)
54
55
    def _iterate(self, i, _cand_, _p_list_):
56
        if i % self._opt_args_.n_particles == 0:
57
            self._move_positioners(_cand_, _p_list_)
58
59
        _p_current = _p_list_[i % self._opt_args_.n_particles]
60
        self._eval_particle(_cand_, _p_current)
61
62
        return _cand_
63
64
    def _init_opt_positioner(self, _cand_):
65
        _p_list_ = self._init_particles(_cand_)
66
67
        for _p_ in _p_list_:
68
            _p_.score_current = _cand_.eval_pos(_p_.pos_current)
69
            _p_.score_best = _p_.score_current
70
71
        return _p_list_
72
73
74
class Particle(BasePositioner):
75
    def __init__(self):
76
        super().__init__(self)
77
        self.nr = None
78
        self.velo = None
79
80
    def move_part(self, _cand_, pos):
81
        pos_new = (pos + self.velo).astype(int)
82
        # limit movement
83
        n_zeros = [0] * len(_cand_._space_.dim)
84
        return np.clip(pos_new, n_zeros, _cand_._space_.dim)
85