Equation Solver with Particle Swarm Optimization
1. Import module
import random
import re
import operator as operan
2. Define The Equation
equation = 'a+2b-3c+4d=30'
3. Define Operans
ops = { "+" : operan .add ,
"-" : operan .sub }
4. Parse Equation (string) to Real Equation
def break_equation (equation ):
equation_resul = int (equation .split ('=' )[1 ])
equation_body = equation .split ('=' )[0 ]
equation_split_op = re .split (r'[-+]' , equation_body )
number_of_variable = len (equation_split_op )
operator = []
for x in list (equation_body ):
if (x == '-' or x == '+' ):
operator .append (x )
cons = []
for y in equation_split_op :
if len (list (y )) == 1 :
cons .append (1 )
else :
cons .append (int (list (y )[0 ]))
return cons , operator , equation_resul , number_of_variable
5. Print Real Equation
cons , operator , equation_resul , number_of_variable = break_equation (equation )
print (cons )
print (operator )
print (equation_resul )
print (number_of_variable )
[1, 2, 3, 4]
['+', '-', '+']
30
4
6. Compute Fitness
def cal_fitness (var_values ):
result = ops [operator [0 ]]((cons [0 ]* var_values [0 ]),(cons [1 ]* var_values [1 ]))
for i in range (1 , len (operator )):
result = ops [operator [i ]](result ,(cons [i + 1 ]* var_values [i + 1 ]))
minimasi = abs (equation_resul - result )
return minimasi ;
7. Particle Class
class Particle :
def __init__ (self , initial_position ):
self .position = initial_position
self .dimensions = len (initial_position )
self .position_of_best = initial_position
self .velocity = [random .uniform (- 1 ,1 ) for i in range (self .dimensions )]
self .error_best = float ('inf' )
self .error = float ('inf' )
def set_pbest (self ):
self .error = cal_fitness (self .position )
if self .error < self .error_best or self .error == 0 :
self .position_of_best = self .position
self .error_best = self .error_best
def compute_velocity (self , w , c1 , c2 , pg ):
for i in range (self .dimensions ):
r1 = random .random ()
r2 = random .random ()
vel_cognitive = c1 * r1 * (self .position_of_best [i ]- self .position [i ])
vel_social = c2 * r2 * (pg [i ]- self .position [i ])
self .velocity [i ] = w * self .velocity [i ] + vel_cognitive + vel_social
def compute_position (self , limit ):
for i in range (self .dimensions ):
self .position [i ] = self .position [i ] + self .velocity [i ]
if self .position [i ] > limit [i ][1 ]:
self .position [i ] = limit [i ][1 ]
if self .position [i ] < limit [i ][0 ]:
self .position [i ] = limit [i ][0 ]
8. PSO Class
class PSO :
def __init__ (self , initial_position , num_particles , limit , num_iterations , w , c1 , c2 ):
self .initial_position = initial_position
self .num_particles = num_particles
self .limit = limit
self .num_iterations = num_iterations
self .w = w
self .c1 = c1
self .c2 = c2
self .error_best_of_group = float ('inf' )
self .position_best_of_group = float ('inf' )
self .swarm = []
for i in range (0 ,num_particles ):
self .swarm .append (Particle (self .initial_position ))
def run (self ):
for i in range (self .num_iterations ):
for j in range (self .num_particles ):
self .swarm [j ].set_pbest ()
if self .swarm [j ].error < self .error_best_of_group or self .error_best_of_group == 0 :
self .position_best_of_group = list (self .swarm [j ].position )
self .error_best_of_group = float (self .swarm [j ].error )
for j in range (self .num_particles ):
self .swarm [j ].compute_velocity (self .w , self .c1 , self .c2 , self .position_best_of_group )
self .swarm [j ].compute_position (self .limit )
print ('Result:' )
print ('best position of the group: ' , end = '\t ' )
print (self .position_best_of_group )
print ('best error of the group: ' , end = '\t ' )
print (self .error_best_of_group )
9. Example
initial_position = [5 for i in range (number_of_variable )]
limit = [(0 ,10 ),(0 ,10 ),(0 ,10 ),(0 ,10 )]
pso = PSO (initial_position = initial_position , num_particles = 30 , limit = limit , num_iterations = 100 , w = 0.5 , c1 = 1 , c2 = 2 )
pso .run ()
Result:
best position of the group: [4.532972421221837, 5.127465638518598, 2.421653729133265, 5.617195315829612]
best error of the group: 0.008276225822314132