Passed
Push — master ( 4008d8...7acf8f )
by
unknown
01:16
created

Particle.generateParticle()   A

Complexity

Conditions 4

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
c 1
b 0
f 0
dl 0
loc 7
rs 9.2
1
"""Particle Swarm Optimization algorithm.
2
3
Date: 12. 2. 2018
4
5
Authors : Uros Mlakar
6
7
License: MIT
8
9
Reference paper: Kennedy, J. and Eberhart, R. "Particle Swarm Optimization".
10
Proceedings of IEEE International Conference on Neural Networks. IV. pp. 1942--1948, 1995.
11
12
EDITED: TODO: Tests and validation! Bug in code.
13
"""
14
15
import random as rnd
16
import copy
17
18
__all__ = ['ParticleSwarmAlgorithm']
19
20
21
class Particle(object):
22
    '''Defines particle for population'''
23
    # pylint: disable=too-many-instance-attributes
24
    def __init__(self, D, LB, UB):
25
        self.D = D
26
        self.LB = LB
27
        self.UB = UB
28
        self.vmax = 6
29
        self.Solution = []
30
        self.Velocity = []
31
32
        self.pBestPosition = []
33
        self.bestFitness = float('inf')
34
35
        self.Fitness = float('inf')
36
        self.generateParticle()
37
38
    def generateParticle(self):
39
        self.Solution = [self.LB + (self.UB - self.LB)
40
                         * rnd.random() for _i in range(self.D)]
41
        self.Velocity = [0 for _i in range(self.D)]
42
43
        self.pBestSolution = [0 for _i in range(self.D)]
44
        self.bestFitness = float('inf')
45
46
    def evaluate(self):
47
48
        self.Fitness = Particle.FuncEval(self.D, self.Solution)
49
        self.checkPersonalBest()
50
51
    def checkPersonalBest(self):
52
        if self.Fitness < self.bestFitness:
53
            self.pBestSolution = self.Solution
0 ignored issues
show
Coding Style introduced by
The attribute pBestSolution was defined outside __init__.

It is generally a good practice to initialize all attributes to default values in the __init__ method:

class Foo:
    def __init__(self, x=None):
        self.x = x
Loading history...
54
            self.bestFitness = self.Fitness
55
56
    def simpleBound(self):
57
        for i in range(len(self.Solution)):
58
            if self.Solution[i] < self.LB:
59
                self.Solution[i] = self.LB
60
            if self.Solution[i] > self.UB:
61
                self.Solution[i] = self.UB
62
            if self.Velocity[i] > self.vmax:
63
                self.Velocity[i] = self.vmax
64
            if self.Velocity[i] < -self.vmax:
65
                self.Velocity[i] = -self.vmax
66
67
    def toString(self):
68
        pass
69
70
    def __eq__(self, other):
71
        return self.Solution == other.Solution and self.Fitness == other.Fitness
72
73
74
class ParticleSwarmAlgorithm(object):
75
    # pylint: disable=too-many-instance-attributes
76
    def __init__(self, Np, D, nFES, C1, C2, w, Lower, Upper, function):
77
        '''Constructor'''
78
        self.Np = Np
79
        self.D = D
80
        self.nFES = nFES
81
        self.Swarm = []
82
        self.Lower = Lower
83
        self.Upper = Upper
84
        self.C1 = C1
85
        self.C2 = C2
86
        self.w = w
87
        self.vmax = 0.9
88
        self.vmin = 0.2
89
        Particle.FuncEval = staticmethod(function)
90
91
        self.gBest = Particle(D, Lower, Upper)
92
93
    def evalSwarm(self):
94
        for p in self.Swarm:
95
            p.evaluate()
96
            if p.Fitness < self.gBest.Fitness:
97
                self.gBest = copy.deepcopy(p)
98
99
    def initSwarm(self):
100
        for _i in range(self.Np):
101
            self.Swarm.append(Particle(self.D, self.Lower, self.Upper))
102
103
    def moveSwarm(self, Swarm):
104
        MovedSwarm = []
105
        for p in Swarm:
106
107
            part1 = ([(a - b) * rnd.random() * self.C1 for a,
108
                      b in zip(p.pBestSolution, p.Solution)])
109
            part2 = ([(a - b) * rnd.random() * self.C2 for a,
110
                      b in zip(self.gBest.Solution, p.Solution)])
111
112
            p.Velocity = ([self.w * a + b + c for a, b,
113
                           c in zip(p.Velocity, part1, part2)])
114
            p.Solution = ([a + b for a, b in zip(p.Solution, p.Velocity)])
115
            p.simpleBound()
116
117
            p.evaluate()
118
            if p.Fitness < self.gBest.Fitness:
119
                self.gBest = copy.deepcopy(p)
120
121
            MovedSwarm.append(p)
122
        return MovedSwarm
123
124
    def run(self):
125
        self.initSwarm()
126
        self.evalSwarm()
127
        FEs = self.Np
128
        while FEs <= self.nFES:
129
            MovedSwarm = self.moveSwarm(self.Swarm)
130
            self.Swarm = MovedSwarm
131
            FEs += self.Np
132
        return self.gBest.Fitness
133