Passed
Push — master ( 65b200...512d29 )
by
unknown
01:06
created

Particle.simpleBound()   B

Complexity

Conditions 6

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 6
c 2
b 1
f 0
dl 0
loc 10
rs 8
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
24
    # pylint: disable=too-many-instance-attributes
25
    def __init__(self, D, LB, UB, vMin, vMax):
26
        self.D = D
27
        self.LB = LB
28
        self.UB = UB
29
        self.vMin = vMin
30
        self.vMax = vMax
31
        self.Solution = []
32
        self.Velocity = []
33
34
        self.pBestPosition = []
35
        self.pBestSolution = []
36
        self.bestFitness = float('inf')
37
38
        self.Fitness = float('inf')
39
        self.generateParticle()
40
41
    def generateParticle(self):
42
        self.Solution = [self.LB + (self.UB - self.LB) * rnd.random()
43
                         for _i in range(self.D)]
44
        self.Velocity = [0 for _i in range(self.D)]
45
46
        self.pBestSolution = [0 for _i in range(self.D)]
47
        self.bestFitness = float('inf')
48
49
    def evaluate(self):
50
51
        self.Fitness = Particle.FuncEval(self.D, self.Solution)
52
        self.checkPersonalBest()
53
54
    def checkPersonalBest(self):
55
        if self.Fitness < self.bestFitness:
56
            self.pBestSolution = self.Solution
57
            self.bestFitness = self.Fitness
58
59
    def simpleBound(self):
60
        for i in range(self.D):
61
            if self.Solution[i] < self.LB:
62
                self.Solution[i] = self.LB
63
            if self.Solution[i] > self.UB:
64
                self.Solution[i] = self.UB
65
            if self.Velocity[i] < self.vMin:
66
                self.Velocity[i] = self.vMin
67
            if self.Velocity[i] > self.vMax:
68
                self.Velocity[i] = self.vMax
69
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
70
    def toString(self):
71
        pass
72
73
    def __eq__(self, other):
74
        return self.Solution == other.Solution and self.Fitness == other.Fitness
75
76
77
class ParticleSwarmAlgorithm(object):
78
    # pylint: disable=too-many-instance-attributes
79
80
    def __init__(self, Np, D, nFES, C1, C2, w, vMin, vMax, Lower, Upper, function):
81
        """Constructor."""
82
        self.Np = Np
83
        self.D = D
84
        self.nFES = nFES
85
        self.C1 = C1
86
        self.C2 = C2
87
        self.w = w
88
        self.vMin = vMin
89
        self.vMax = vMax
90
        self.Lower = Lower
91
        self.Upper = Upper
92
        self.Swarm = [] 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
93
               
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
94
        Particle.FuncEval = staticmethod(function)
95
96
        self.gBest = Particle(self.D, self.Lower, self.Upper, self.vMin, self.vMax)
97
98
    def evalSwarm(self):
99
        for p in self.Swarm:
100
            p.evaluate()
101
            if p.Fitness < self.gBest.Fitness:
102
                self.gBest = copy.deepcopy(p)
103
104
    def initSwarm(self):
105
        for _i in range(self.Np):
106
            self.Swarm.append(Particle(self.D, self.Lower, self.Upper, self.vMin, self.vMax))
107
108
    def moveSwarm(self, Swarm):
109
        MovedSwarm = []
110
        for p in Swarm:
111
112
            part1 = ([(a - b) * rnd.random() * self.C1 for a,
113
                      b in zip(p.pBestSolution, p.Solution)])
114
            part2 = ([(a - b) * rnd.random() * self.C2 for a,
115
                      b in zip(self.gBest.Solution, p.Solution)])
116
117
            p.Velocity = ([self.w * a + b + c for a, b,
118
                           c in zip(p.Velocity, part1, part2)])
119
            p.Solution = ([a + b for a, b in zip(p.Solution, p.Velocity)])
120
121
            p.simpleBound()
122
123
            p.evaluate()
124
            if p.Fitness < self.gBest.Fitness:
125
                self.gBest = copy.deepcopy(p)
126
127
            MovedSwarm.append(p)
128
        return MovedSwarm
129
130
    def run(self):
131
        self.initSwarm()
132
        self.evalSwarm()
133
        FEs = self.Np
134
        while FEs <= self.nFES:
135
            MovedSwarm = self.moveSwarm(self.Swarm)
136
            self.Swarm = MovedSwarm
137
            FEs += self.Np
138
        return self.gBest.Fitness
139