Completed
Pull Request — master (#106)
by Grega
04:33
created

ParticleSwarmAlgorithm.__init__()   A

Complexity

Conditions 1

Size

Total Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 1
c 1
b 1
f 0
dl 0
loc 48
rs 9.125
1
import random as rnd
2
import copy
3
from NiaPy.benchmarks.utility import Utility
4
5
__all__ = ['ParticleSwarmAlgorithm']
6
7
8
class Particle(object):
9
    """Defines particle for population."""
10
11
    def __init__(self, D, LB, UB, vMin, vMax):
12
        self.D = D  # dimension of the problem
13
        self.LB = LB  # lower bound
14
        self.UB = UB  # upper bound
15
        self.vMin = vMin  # minimal velocity
16
        self.vMax = vMax  # maximal velocity
17
        self.Solution = []
18
        self.Velocity = []
19
20
        self.pBestPosition = []
21
        self.pBestSolution = []
22
        self.bestFitness = float('inf')
23
24
        self.Fitness = float('inf')
25
        self.generateParticle()
26
27
    def generateParticle(self):
28
        self.Solution = [self.LB + (self.UB - self.LB) * rnd.random()
29
                         for _i in range(self.D)]
30
        self.Velocity = [0 for _i in range(self.D)]
31
32
        self.pBestSolution = [0 for _i in range(self.D)]
33
        self.bestFitness = float('inf')
34
35
    def evaluate(self):
36
        self.Fitness = Particle.FuncEval(self.D, self.Solution)
37
        self.checkPersonalBest()
38
39
    def checkPersonalBest(self):
40
        if self.Fitness < self.bestFitness:
41
            self.pBestSolution = self.Solution
42
            self.bestFitness = self.Fitness
43
44
    def simpleBound(self):
45
        for i in range(self.D):
46
            if self.Solution[i] < self.LB:
47
                self.Solution[i] = self.LB
48
            if self.Solution[i] > self.UB:
49
                self.Solution[i] = self.UB
50
            if self.Velocity[i] < self.vMin:
51
                self.Velocity[i] = self.vMin
52
            if self.Velocity[i] > self.vMax:
53
                self.Velocity[i] = self.vMax
54
55
    def toString(self):
56
        pass
57
58
    def __eq__(self, other):
59
        return self.Solution == other.Solution and self.Fitness == other.Fitness
60
61
62
class ParticleSwarmAlgorithm(object):
63
    r"""Implementation of Particle Swarm Optimization algorithm.
64
65
    **Algorithm:** Particle Swarm Optimization algorithm
66
67
    **Date:** 2018
68
69
    **Author:** Uros Mlakar
70
71
    **License:** MIT
72
73
    **Reference paper:**
74
        Kennedy, J. and Eberhart, R. "Particle Swarm Optimization".
75
        Proceedings of IEEE International Conference on Neural Networks.
76
        IV. pp. 1942--1948, 1995.
77
78
    EDITED: TODO: Tests and validation! Bug in code.
79
    """
80
81
    def __init__(self, Np, D, nFES, C1, C2, w, velocityMin,velocityMax, weightMin, weightMax, benchmark):
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
Loading history...
82
        r"""**__init__(self, Np, D, nFES, C1, C2, w, vMin, vMax, benchmark)**.
83
84
        Arguments:
85
            NP {integer} -- population size
86
87
            D {integer} -- dimension of problem
88
89
            nFES {integer} -- number of function evaluations
90
91
            C1 {decimal} -- cognitive component
92
93
            C2 {decimal} -- social component
94
95
            w {decimal} -- inertia weight
96
97
            vMin {decimal} -- minimal velocity
98
99
            vMax {decimal} -- maximal velocity
100
101
            benchmark {object} -- benchmark implementation object
102
103
        """
104
105
        self.benchmark = Utility().get_benchmark(benchmark)
106
        self.Np = Np  # population size; number of search agents
107
        self.D = D  # dimension of the problem
108
        self.C1 = C1  # cognitive component
109
        self.C2 = C2  # social component
110
        self.w = w  # initial inertia weight
111
        self.wMin = weightMin 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
112
        self.wMax = weightMax
113
        self.vMin = velocityMin  # minimal velocity
114
        self.vMax = velocityMax  # maximal velocity
115
        self.Lower = self.benchmark.Lower  # lower bound
116
        self.Upper = self.benchmark.Upper  # upper bound
117
        self.Swarm = []
118
        self.nFES = nFES  # number of function evaluations
119
        self.FEs = 0
120
        self.Done = False
121
        Particle.FuncEval = staticmethod(self.benchmark.function())
122
123
        self.gBest = Particle(
124
            self.D,
125
            self.Lower,
126
            self.Upper,
127
            self.vMin,
128
            self.vMax)
129
130
    def evalSwarm(self):
131
        for p in self.Swarm:
132
            p.evaluate()
133
            if p.Fitness < self.gBest.Fitness:
134
                self.gBest = copy.deepcopy(p)
135
136
    def initSwarm(self):
137
        for _i in range(self.Np):
138
            self.Swarm.append(
139
                Particle(self.D,
140
                         self.Lower,
141
                         self.Upper,
142
                         self.vMin,
143
                         self.vMax))
144
145
    def tryEval(self, p):
146
        if self.FEs <= self.nFES:
147
            p.evaluate()
148
            self.FEs += 1
149
        else:
150
            self.Done = True
151
152
    def moveSwarm(self, Swarm):
153
        MovedSwarm = []
154
        for p in Swarm:
155
156
            part1 = ([(a - b) * rnd.random() * self.C1 for a,
157
                      b in zip(p.pBestSolution, p.Solution)])
158
            part2 = ([(a - b) * rnd.random() * self.C2 for a,
159
                      b in zip(self.gBest.Solution, p.Solution)])
160
161
            p.Velocity = ([self.w * a + b + c for a, b,
162
                           c in zip(p.Velocity, part1, part2)])
163
            p.Solution = ([a + b for a, b in zip(p.Solution, p.Velocity)])
164
165
            p.simpleBound()
166
            self.tryEval(p)
167
            if p.Fitness < self.gBest.Fitness:
168
                self.gBest = copy.deepcopy(p)
169
170
            MovedSwarm.append(p)
171
        return MovedSwarm
172
173
    def run(self):
174
        self.initSwarm()
175
        self.evalSwarm()
176
        self.FEs += self.Np
177
        NumIters = int(self.nFES / self.Np)
178
        CurrentIter=0
0 ignored issues
show
Coding Style introduced by
Exactly one space required around assignment
Loading history...
179
        while not self.Done:
180
            MovedSwarm = self.moveSwarm(self.Swarm)
181
            self.Swarm = MovedSwarm
182
            self.w=self.wMax-CurrentIter*((self.wMax-self.wMin)/NumIters)
0 ignored issues
show
Coding Style introduced by
Exactly one space required around assignment
Loading history...
183
            CurrentIter += 1
184
185
        return self.gBest.Fitness
186