Passed
Push — master ( 3e971a...f509c4 )
by
unknown
01:08
created

ParticleSwarmAlgorithm   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 59
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 59
rs 10
wmc 15

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __init__() 0 14 1
A evalSwarm() 0 5 3
A initSwarm() 0 3 2
A run() 0 9 2
C moveSwarm() 0 21 7
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
25
    def __init__(self, D, LB, UB):
26
        self.D = D
27
        self.LB = LB
28
        self.UB = UB
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(self.D):
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
63
    def toString(self):
64
        pass
65
66
    def __eq__(self, other):
67
        return self.Solution == other.Solution and self.Fitness == other.Fitness
68
69
70
class ParticleSwarmAlgorithm(object):
71
    # pylint: disable=too-many-instance-attributes
72
73
    def __init__(self, Np, D, nFES, C1, C2, w, Lower, Upper, function):
74
        '''Constructor'''
75
        self.Np = Np
76
        self.D = D
77
        self.nFES = nFES
78
        self.Swarm = []
79
        self.Lower = Lower
80
        self.Upper = Upper
81
        self.C1 = C1
82
        self.C2 = C2
83
        self.w = w
84
        Particle.FuncEval = staticmethod(function)
85
86
        self.gBest = Particle(self.D, self.Lower, self.Upper)
87
88
    def evalSwarm(self):
89
        for p in self.Swarm:
90
            p.evaluate()
91
            if p.Fitness < self.gBest.Fitness:
92
                self.gBest = copy.deepcopy(p)
93
94
    def initSwarm(self):
95
        for _i in range(self.Np):
96
            self.Swarm.append(Particle(self.D, self.Lower, self.Upper))
97
98
    def moveSwarm(self, Swarm):
99
        MovedSwarm = []
100
        for p in Swarm:
101
102
            part1 = ([(a - b) * rnd.random() * self.C1 for a,
103
                      b in zip(p.pBestSolution, p.Solution)])
104
            part2 = ([(a - b) * rnd.random() * self.C2 for a,
105
                      b in zip(self.gBest.Solution, p.Solution)])
106
107
            p.Velocity = ([self.w * a + b + c for a, b,
108
                           c in zip(p.Velocity, part1, part2)])
109
            p.Solution = ([a + b for a, b in zip(p.Solution, p.Velocity)])
110
111
            p.simpleBound()
112
113
            p.evaluate()
114
            if p.Fitness < self.gBest.Fitness:
115
                self.gBest = copy.deepcopy(p)
116
117
            MovedSwarm.append(p)
118
        return MovedSwarm
119
120
    def run(self):
121
        self.initSwarm()
122
        self.evalSwarm()
123
        FEs = self.Np
124
        while FEs <= self.nFES:
125
            MovedSwarm = self.moveSwarm(self.Swarm)
126
            self.Swarm = MovedSwarm
127
            FEs += self.Np
128
        return self.gBest.Fitness
129