1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| import numpy as np import matplotlib.pyplot as plt
class Particle(): def __init__(self, position, speed, best_fitness, best_position): self.position = position self.speed = speed self.best_fitness = best_fitness self.best_position = best_position
class PSO(): def __init__(self, min_speed, max_speed, Iternumbers, C1, C2, R, W, particleNum): self.min_speed = min_speed self.max_speed = max_speed self.Iternumbers = Iternumbers self.C1 = C1 self.C2 = C2 self.R = R self.W = W self.particleNum = particleNum self.best_position = None self.best_fitness = -100000
def initial(self): particles = [] for _ in range(self.particleNum): rand_position = np.random.rand() * (self.max_speed-self.min_speed) + self.min_speed rand_speed = np.random.rand() * (self.max_speed-self.min_speed) + self.min_speed fitness = self.compute_fitness(rand_position) if fitness > self.best_fitness: self.best_fitness = fitness self.best_position = rand_position particle = Particle(rand_position, rand_speed, fitness, rand_position) particles.append(particle) return particles
def compute_fitness(self, x): return x * np.sin(10*np.pi*x) + 1
def update_speed(self, particle): rand1 = np.random.rand() rand2 = np.random.rand() V_next = self.W * particle.speed + self.C1 * rand1 * (particle.best_position - particle.position) \ + self.C2 * rand2 * (self.best_position - particle.position) if V_next > self.max_speed: V_next = self.max_speed elif V_next < self.min_speed: V_next = self.min_speed else: V_next = V_next return V_next
def update_position(self, particle, V_next): X_next = particle.position + self.R * V_next if X_next > self.max_speed: X_next = self.max_speed elif X_next < self.min_speed: X_next = self.min_speed else: X_next = X_next return X_next
def update(self, particles): temp_fitness = 0 temp_position = 0 for particle in particles: V_next = self.update_speed(particle) X_next = self.update_position(particle,V_next) particle.position = X_next particle.speed = V_next fitness = self.compute_fitness(X_next) if fitness > particle.best_fitness: particle.best_fitness = fitness particle.best_position = X_next if fitness > self.best_fitness: temp_fitness = fitness temp_position = X_next if temp_fitness > self.best_fitness: self.best_fitness = temp_fitness self.best_position = temp_position return particles
def plot(self, particles): for i in range(len(particles)): position = particles[i].position fitness = self.compute_fitness(position) plt.vlines(position,0,fitness,colors='r') plt.scatter(position,fitness, c='r')
def solve(self): particles = self.initial() self.plot(particles) for _ in range(self.Iternumbers): particles = self.update(particles) self.plot(particles)
if __name__ == '__main__': pso = PSO(-1, 1, 50, 2, 2, 1, 1, 2) X = np.arange(-1,1,0.01) Y = pso.compute_fitness(X) plt.plot(X, Y, linewidth = 2) pso.solve()
plt.grid() plt.show()
|