Particle Swarm Optimization
import numpy as np
import matplotlib.pyplot as plt
def Schwefel(X):
f = 418.9829 * len(X)
for i in X:
f -= i * np.sin(np.sqrt(np.abs(i)))
return f
class Particle:
def __init__(self, domain_position, domain_velocity, dim):
self.pos = [np.random.uniform(-domain_position, domain_position) for i in range(dim)]
self.vel = [np.random.uniform(-domain_velocity, domain_velocity) for i in range(dim)]
self.solution_position = [0.0 for i in range(dim)]
self.local_minimum = Schwefel(self.pos)
class PSO:
def __init__(self, dim, size, domain_position, domain_velocity, C1=2, C2=2, weight=1):
self.dim = dim
self.size = size
self.domain_position = domain_position
self.domain_velocity = domain_velocity
self.C1 = C1
self.C2 = C2
self.weight = weight
self.global_minimum = float('INF')
self.solution_position = [0.0 for i in range(dim)]
self.ParticleSwarm = [Particle(self.domain_position, self.domain_velocity, self.dim) for i in range(self.size)]
self.global_loss = []
def fit(self, epochs):
for i in range(epochs):
for particle in self.ParticleSwarm:
self.update_velocity(particle)
self.update_position(particle)
self.global_loss.append(self.global_minimum)
def update_velocity(self, particle):
for i in range(self.dim):
val_temp = self.weight * particle.vel[i] + self.C1 * np.random.normal(0, 1) * (particle.solution_position[i] - particle.pos[i]) + self.C2 * np.random.normal(0, 1) * (self.solution_position[i] - particle.pos[i])
if val_temp > self.domain_velocity:
val_temp = self.domain_velocity
elif val_temp < -self.domain_velocity:
val_temp = -self.domain_velocity
particle.vel[i] = val_temp
def update_position(self, particle):
for i in range(self.dim):
particle.pos[i] = particle.pos[i] + particle.vel[i]
local_minimum = Schwefel(particle.pos)
if local_minimum < particle.local_minimum:
particle.local_minimum = local_minimum
for i in range(self.dim):
particle.solution_position[i] = particle.pos[i]
if local_minimum < self.global_minimum:
self.global_minimum = local_minimum
for i in range(self.dim):
self.solution_position[i] = particle.pos[i]
if __name__ == "__main__":
np.random.seed(8)
dim = 2
size = 10
epochs = 1000
domain_position = 500
domain_velocity = 0.15
model = PSO(dim, size, domain_position, domain_velocity)
model.fit(epochs)
print("Solution position:", model.solution_position)
print("Global minimum: %f" % Schwefel(model.solution_position))
plt.plot(model.global_loss, "-r", linewidth=2, label='loss')
plt.legend()
plt.grid(True)
plt.show()