aboutsummaryrefslogtreecommitdiffstats
path: root/PSO.py
diff options
context:
space:
mode:
Diffstat (limited to 'PSO.py')
-rwxr-xr-xPSO.py173
1 files changed, 173 insertions, 0 deletions
diff --git a/PSO.py b/PSO.py
new file mode 100755
index 0000000..0d019cd
--- /dev/null
+++ b/PSO.py
@@ -0,0 +1,173 @@
+#!/usr/bin/env python3
+import time
+import random
+
+
+class Particle:
+ def __init__(self, x, y, z):
+ self.Pbest_x = 0
+ self.Pbest_y = 0
+ self.Pbest_z = 0
+ self.x = x
+ self.y = y
+ self.z = z
+ self.x_k1 = 0
+ self.y_k1 = 0
+ self.z_k1 = 0
+ self.V_x = 0
+ self.V_y = 0
+ self.V_z = 0
+ self.V_xk1 = 0
+ self.V_yk1 = 0
+ self.V_zk1 = 0
+
+ def __repr__(self):
+ return (
+ "{x: %s , y: %s, z: %s, Pbest_x: %s, Pbest_y: %s, Pbest_z: %s}\n"
+ % (
+ self.x,
+ self.y,
+ self.z,
+ self.Pbest_x,
+ self.Pbest_y,
+ self.Pbest_z,
+ )
+ )
+
+ def __str__(self):
+ return (
+ "{x: %s , y: %s, z: %s, Pbest_x: %s, Pbest_y: %s, Pbest_z: %s}\n"
+ % (
+ self.x,
+ self.y,
+ self.z,
+ self.Pbest_x,
+ self.Pbest_y,
+ self.Pbest_z,
+ )
+ )
+
+ def update_X(self):
+ self.x = self.x + self.V_xk1
+ self.y = self.y + self.V_yk1
+ self.z = self.z + self.V_zk1
+
+ def update_V(self, w, c1, c2, Gbest_x, Gbest_y, Gbest_z):
+ rand1 = random.random()
+ rand2 = random.random()
+ self.V_xk1 = (
+ w * self.V_x
+ + c1 * rand1 * (self.Pbest_x - self.x)
+ + c2 * rand2 * (Gbest_x - self.x)
+ )
+ self.V_yk1 = (
+ w * self.V_y
+ + c1 * rand1 * (self.Pbest_y - self.y)
+ + c2 * rand2 * (Gbest_y - self.y)
+ )
+ self.V_zk1 = (
+ w * self.V_z
+ + c1 * rand1 * (self.Pbest_z - self.z)
+ + c2 * rand2 * (Gbest_z - self.z)
+ )
+
+ def update_Pbest(self, x, y, z: float):
+ self.Pbest_x = x
+ self.Pbest_y = y
+ self.Pbest_z = z
+
+ def doRound(self, w, c1, c2, Gbest_x, Gbest_y, Gbest_z, fitness):
+ fitness_x = fitness(self.x, self.y, self.z)
+ self.update_V(w, c1, c2, Gbest_x, Gbest_y, Gbest_z)
+ self.update_X()
+ if abs(fitness(self.Pbest_x, self.Pbest_y, self.Pbest_z)) > abs(
+ fitness_x
+ ):
+ self.update_Pbest(self.x, self.y, self.z)
+
+
+class PSO:
+ def __init__(self, w, c1, c2, particle_count):
+ self.Gbest_x = 0
+ self.Gbest_y = 0
+ self.Gbest_z = 0
+ self.particle_count = particle_count
+ self.Particles = self.factory()
+ self.w = w
+ self.c1 = c1
+ self.c2 = c2
+
+ def factory(self):
+ result = list()
+ for _ in range(1, self.particle_count):
+ x = (
+ random.random() * 10
+ if random.random() > 0.5
+ else -random.random() * 10
+ )
+ y = (
+ random.random() * 10
+ if random.random() > 0.5
+ else -random.random() * 10
+ )
+ z = (
+ random.random() * 10
+ if random.random() > 0.5
+ else -random.random() * 10
+ )
+ result.append(Particle(x, y, z))
+ return result
+
+ def fitness(self, x, y, z: float):
+ return (
+ (x ** 5) - ((x ** 2) * y * z) + (z * x) + (y ** 2) - (z ** 3) - 10
+ )
+
+ def doRround(self):
+ roundBest_x = float()
+ roundBest_y = float()
+ roundBest_z = float()
+ for particle in self.Particles:
+ if abs(self.fitness(roundBest_x, roundBest_y, roundBest_z)) > abs(
+ self.fitness(particle.x, particle.y, particle.z)
+ ):
+ roundBest_x = particle.x
+ roundBest_y = particle.y
+ roundBest_z = particle.z
+ self.Gbest_x = roundBest_x
+ self.Gbest_y = roundBest_y
+ self.Gbest_z = roundBest_z
+ for particle in self.Particles:
+ particle.doRound(
+ self.w,
+ self.c1,
+ self.c2,
+ self.Gbest_x,
+ self.Gbest_y,
+ self.Gbest_z,
+ self.fitness,
+ )
+
+ def printGlobalBest(self):
+ print(
+ "x: %s, y: %s, z: %s, fitness: %s"
+ % (
+ self.Gbest_x,
+ self.Gbest_y,
+ self.Gbest_z,
+ self.fitness(self.Gbest_x, self.Gbest_y, self.Gbest_z),
+ ),
+ )
+
+
+def main():
+ random.seed(time.time())
+ round_count = 10
+ pso = PSO(5, 1.5, 1.5, 50)
+ for _ in range(1, round_count):
+ pso.doRround()
+ pso.printGlobalBest()
+
+
+if __name__ == "__main__":
+ main()