Passed
Push — master ( d39371...69bf6f )
by Simon
03:38
created

ParticleSwarmOptimizer.__init__()   A

Complexity

Conditions 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nop 5
dl 0
loc 10
rs 10
c 0
b 0
f 0
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_population_optimizer import BasePopulationOptimizer
11
from ...search import Search
12
from ..base_optimizer import BaseOptimizer
13
14
15
class ParticleSwarmOptimizer(BasePopulationOptimizer, Search):
16
    def __init__(
17
        self, search_space, inertia=0.5, cognitive_weight=0.5, social_weight=0.5,
18
    ):
19
        super().__init__(search_space)
20
21
        self.inertia = inertia
22
        self.cognitive_weight = cognitive_weight
23
        self.social_weight = social_weight
24
25
        self.particles = []
26
27
    def _move_part(self, pos, velo):
28
        pos_new = (pos + velo).astype(int)
29
        # limit movement
30
        n_zeros = [0] * len(self.space_dim)
31
        self.p_current.pos_new = np.clip(pos_new, n_zeros, self.space_dim)
32
33
        return self.p_current.pos_new
34
35
    def _move_positioner(self):
36
        r1, r2 = random.random(), random.random()
37
38
        A = self.inertia * self.p_current.velo
39
        B = (
40
            self.cognitive_weight
41
            * r1
42
            * np.subtract(self.p_current.pos_best, self.p_current.pos_current)
43
        )
44
        C = (
45
            self.social_weight
46
            * r2
47
            * np.subtract(self.global_pos_best, self.p_current.pos_current)
48
        )
49
50
        new_velocity = A + B + C
51
52
        return self._move_part(self.p_current.pos_current, new_velocity)
53
54
    def _sort_best(self):
55
        scores_list = []
56
        for _p_ in self.particles:
57
            scores_list.append(_p_.score_current)
58
59
        scores_np = np.array(scores_list)
60
        idx_sorted_ind = list(scores_np.argsort()[::-1])
61
62
        self.p_sorted = [self.particles[i] for i in idx_sorted_ind]
63
64
    def init_pos(self, pos):
65
        particle = BaseOptimizer(self.space_dim)
66
        self.particles.append(particle)
67
        particle.init_pos(pos)
68
69
        self.p_current = particle
70
        self.p_current.velo = np.zeros(len(self.space_dim))
71
72
    def iterate(self):
73
        n_iter = self._iterations(self.particles)
74
        self.p_current = self.particles[n_iter % len(self.particles)]
75
76
        self._sort_best()
77
        self.global_pos_best = self.p_sorted[0].pos_best
78
        pos = self._move_positioner()
79
80
        return pos
81
82
    def evaluate(self, score_new):
83
        self.p_current.score_new = score_new
84
85
        self.p_current._evaluate_new2current(score_new)
86
        self.p_current._evaluate_current2best()
87
88