Skip to content

Commit

Permalink
Add files
Browse files Browse the repository at this point in the history
  • Loading branch information
behrouzbakhtiari committed Jun 15, 2018
1 parent 4d3a3aa commit ca8bf81
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 1 deletion.
96 changes: 96 additions & 0 deletions PSO.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import random
import Problem
import numpy as np

# This class contains the code of the Particles in the swarm
class Particle:
def __init__(self,problem,c1,c2,w):
self.problem = problem
self.c1 = c1
self.c2 = c2
self.w = w
self.position = problem.generate_random_ponit()
self.velocity = np.random.uniform(0,1,problem.n)
self.personal_best = self.position.copy()
self.personal_best_value = 0

def update_positions(self):
#Update the position:
#position = position + velocity
self.position = self.position + self.velocity
return

def update_velocities(self, golbal_best):
#Update the velocity:
#velocity = w * velocity + c1 * r1 * (golbal_best - position)
# + c2 * r2 * (personal_best - position).
for i in range(self.problem.n):
r1 = np.random.rand()
r2 = np.random.rand()

#social part
social = self.c1 * r1 * (golbal_best[i] - self.position[i])

#recognition part
cognitive = self.c2 * r2 * (self.personal_best[i] - self.position[i])

self.velocity[i] = (self.w * self.velocity[i]) + social + cognitive
return


# This class contains the particle swarm optimization algorithm
class ParticleSwarmOptimizer:
def __init__(self,problem,swarmSize,iterations,c1,c2,w):
self.problem = problem
self.swarmSize = swarmSize
self.iterations = iterations
self.swarm = []
self.generate_init_swarms(c1,c2,w)

def generate_init_swarms(self,c1,c2,w):
for i in range(self.swarmSize):
#Initialize particle
particle = Particle(self.problem,c1,c2,w)
particle.personal_best_value = self.fitness_function(particle.personal_best)
self.swarm.append(particle)
self.update_global_best()


#update the global best particle
def update_global_best(self):
self.global_best = self.swarm[0].position
self.global_best_value = self.swarm[0].personal_best_value
for j in range(self.swarmSize):

#If the personal best value value is better than the global best
# value Set current personal best value as the new global best
personal_best_value = self.swarm[j].personal_best_value
if personal_best_value < self.global_best_value:
self.global_best = self.swarm[j].personal_best
self.global_best_value = personal_best_value

#Update the personal best positions
def update_personal_best(self):
for l in range(self.swarmSize):

#If the fitness value is better than the personal best fitness
# value Set current value as the personal best
personal_best_value = self.swarm[l].personal_best_value
current_value = self.fitness_function(self.swarm[l].position)
if current_value < personal_best_value:
self.swarm[l].personal_best = self.swarm[l].position
self.swarm[l].personal_best_value = current_value

def fitness_function(self,position):
return self.problem.get_value(position)

def optimize(self):
for i in range(self.iterations ):
for k in range(self.swarmSize):
#Update velocitie of each paricle
self.swarm[k].update_velocities(self.global_best)
#Update position of each paricle
self.swarm[k].update_positions()
self.update_personal_best()
self.update_global_best()
return self.global_best
122 changes: 122 additions & 0 deletions Problem.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
from abc import ABC,abstractmethod
from enum import Enum
import numpy as np
import math
#Problem interface for all test functions
class IProblem(ABC):
n = 0
lbound = 0
ubound = 0

def generate_random_ponit(self):
return np.random.uniform(self.lbound,self.ubound,size=(self.n))

def generate_random_ponits(self,count):
return np.random.uniform(self.lbound,self.ubound,size=(count,self.n))

@abstractmethod
def get_value(self, swarm):
pass

#an enum for test functions
class ProblemType(Enum):
Ackley = 1,
PowellSum = 2,
Booth = 3,
DropWave = 4,
SumSquares = 5,
Griewank = 6

#a factory class for generate test function class
class ProblemFactory:
@staticmethod
def generateProblem(type: ProblemType,n,lbound,ubound):
if type == ProblemType.Ackley:
return Ackley(n,lbound,ubound)
elif type == ProblemType.Booth:
return Booth(n,lbound,ubound)
elif type == ProblemType.PowellSum:
return PowellSum(n,lbound,ubound)
elif type == ProblemType.DropWave:
return DropWave(n,lbound,ubound)
elif type == ProblemType.SumSquares:
return SumSquares(n,lbound,ubound)
elif type == ProblemType.Griewank:
return Griewank(n,lbound,ubound)
class PowellSum(IProblem):

def __init__(self,n,lbound,ubound):
self.n = n
self.lbound = lbound
self.ubound = ubound

#get value for custom state
def get_value(self, swarm):
value = 0
for i in range(self.n):
value = value + abs(swarm[i])**(i+2)
return value

class Booth(IProblem):
def __init__(self,n,lbound,ubound):
self.n = n
self.lbound = lbound
self.ubound = ubound

def get_value(self,swarm):
value = (swarm[0] + (2 * swarm[1]) - 7)**2 + ( (2 * swarm[0]) + swarm[1] - 5)**2
return value

class DropWave(IProblem):
def __init__(self,n,lbound,ubound):
self.n = n
self.lbound = lbound
self.ubound = ubound

def get_value(self, swarm):
part1 = -1 * math.cos(12 * (math.sqrt((swarm[0]**2) + (swarm[1]**2))))
part2 = (0.5 * (swarm[0]**2) + (swarm[1]**2)) + 2
value = part1 / part2
return value

class Ackley(IProblem):
C1=20
C2=.2
C3=2*np.pi
def __init__(self,n,lbound,ubound):
self.n = n
self.lbound = lbound
self.ubound = ubound
def get_value(self, swarm):
part1 = -1. * self.C1 * np.exp(
-1. * self.C2 * np.sqrt((1./self.n) * sum(map(lambda nb: nb**2, swarm)))
)
part2 = -1. * np.exp(
(1./self.n) * \
sum(map(lambda nb: np.cos(self.C3 * nb), swarm))
)
return part1 + part2 + self.C1 + np.exp(1)

class SumSquares(IProblem):
def __init__(self,n,lbound,ubound):
self.n = n
self.lbound = lbound
self.ubound = ubound
def get_value(self, swarm):
return np.sum(np.arange(1,self.n+1) * (swarm**2))

class Griewank(IProblem):
def __init__(self,n,lbound,ubound):
self.n = n
self.lbound = lbound
self.ubound = ubound
def get_value(self, swarm):
part1 = 0
for i in range(len(swarm)):
part1 += swarm[i]**2
part2 = 1
for i in range(len(swarm)):
part2 *= math.cos(float(swarm[i]) / math.sqrt(i+1))
return 1 + (float(part1)/4000.0) - float(part2)


2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# PSO
#Particle Swarm Optimization (PSO) with Python
17 changes: 17 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import PSO
import Problem
import numpy as np


problem = Problem.ProblemFactory.generateProblem(
Problem.ProblemType.Ackley, 5, -32, 32)

iterations = 100
swarmSize = 50
c1 = 2 #social constant
c2 = 2 #cognative constant
w = 0.2 #constant inertia weight
pso = PSO.ParticleSwarmOptimizer(problem, swarmSize, iterations, c1, c2, w)
solution = pso.optimize()
print('global best position : {0} - global best value : {1}'.format(solution,problem.get_value(solution)))

0 comments on commit ca8bf81

Please sign in to comment.