Particle swarm optimization (PSO) (Kennedy & Eberhart, 1995) is an emerging population-based meta-heuristic that simulates social behavior such as birds flocking to a promising position to achieve precise solutions in a multidimensional space. It is mainly developed for the optimization of constrains, multi-object problems, dynamic system, data clustering, and signal process. In the algorithm, to discover the optimal solution, each particle changes its searching direction according to two factors, its own best previous experience (pbest) and the best experience of all other members (gbest). Shi and Eberhart (1998) called pbest the cognition part, and gbest the social part.
# -*- coding: utf-8 -*-
"""
Created on 2017/3/18 21:24 2017
@author: Randolph.Lee
"""
import sys
import copy
import numpy as np
class Particle:
def __init__(self, ID, dimension, weight=0.5, c1=2, c2=2):
self.ID = ID
self.weight = weight
self.c1 = c1
self.c2 = c2
self.dimension = dimension
self.max_x = np.ones((1, dimension)) * 30
self.min_x = -np.ones((1, dimension)) * 30
self.max_velocity = np.ones((1, dimension)) * (self.max_x - self.min_x)
self.velocity = (2 * np.random.randn(1, dimension) - 1) * self.max_velocity
self.position = np.random.randn(1, dimension)
self.history_best = np.zeros((1, dimension))
self.history_fit = sys.maxint
self.current_fit = 0.0
def cal_fitness(self):
x_i0 = self.position[0, :-1]
x_i1 = self.position[0, 1:]
self.current_fit = sum(100 * np.power(x_i1 - np.power(x_i0, 2), 2) + np.power(x_i0 - 1, 2))
def update_property(self, g_best):
print g_best
self.velocity *= self.weight
self.velocity += np.random.rand() * self.c1 * (self.history_best - self.position) + np.random.rand() * self.c2 * (g_best - self.position)
self.position += self.velocity
# clip the velocity and the variables
for i in xrange(self.dimension):
if self.velocity[0, i] > self.max_velocity[0, i]:
self.velocity[0, i] = self.max_velocity[0, i]
if self.velocity[0, i] < -self.max_velocity[0, i]:
self.velocity[0, i] = -self.max_velocity[0, i]
if self.position[0, i] > self.max_x[0, i]:
self.position[0, i] = self.max_x[0, i]
if self.position[0, i] < self.min_x[0, i]:
self.position[0, i] = self.min_x[0, i]
def update_pbest(self):
if self.history_fit > self.current_fit:
self.history_fit = self.current_fit
self.history_best = copy.deepcopy(self.position)
if __name__ == "__main__":
max_iteration = 100
particle_num = 10
dimension = 5
# create particle instances and initialize their position and velocity
swarm = [Particle(i, dimension) for i in range(particle_num)]
history_record = []
global_record = []
global_best = np.zeros((1, dimension))
global_fit = sys.maxint
# initialize the global swarm
for i in xrange(particle_num):
print swarm[i].position
swarm[i].cal_fitness()
swarm[i].update_pbest()
if global_fit > swarm[i].current_fit:
global_fit = swarm[i].current_fit
global_best = copy.deepcopy(swarm[i].position)
global_record.append(global_fit)
start = 0
while start < max_iteration:
for i in xrange(particle_num):
swarm[i].cal_fitness()
swarm[i].update_pbest()
swarm[i].update_property(global_best)
# update the global fitness
if global_fit > swarm[i].current_fit:
global_fit = swarm[i].current_fit
global_best = copy.deepcopy(swarm[i].position)
global_record.append(global_fit)
start += 1
print global_best
print global_record