Previous article Whale optimization algorithm (WOA) talked about the inspiration of whale optimization, its mathematical modeling and algorithm. In this article we will implement a whale optimization algorithm (WOA) for two fitness functions 1) Rastrigin function 2) Sphere function The algorithm will run for a predefined number of maximum iterations and will try to find the minimum value of these fitness functions.
Fitness functions
1) Rastrigin function
Rastrigin function is a non-convex function and is often used as a performance test problem for optimization algorithms.
function equation:
For an optimization algorithm, rastrigin function is a very challenging one. Its complex behavior causes optimization algorithms to often be stuck at local minima. Having a lot of cosine oscillations on the plane introduces the complex behavior to this function.
2) Sphere function
Sphere function is a standard function for evaluating the performance of an optimization algorithm.
function equation:
Choice of hyper-parameters
Parameters of problem:
- Number of dimensions (d) = 3
- Lower bound (minx) = -10.0
- Upper bound (maxx) = 10.0
Hyperparameters of the algorithm:
- Number of particles (N) = 50
- Maximum number of iterations (max_iter) = 100
- spiral coefficient (b) = 1
Inputs
- Fitness function
- Problem parameters ( mentioned above)
- Population size (N) and Maximum number of iterations (max_iter)
- Algorithm Specific hyperparameter b
Algorithm
The algorithm of the whale optimization and mathematical equations are already described in the previous article.
Implementation
# python implementation of whale optimization algorithm (WOA) # minimizing rastrigin and sphere function import random
import math # cos() for Rastrigin
import copy # array-copying convenience
import sys # max float
# -------fitness functions--------- # rastrigin function def fitness_rastrigin(position):
fitness_value = 0.0
for i in range ( len (position)):
xi = position[i]
fitness_value + = (xi * xi) - ( 10 * math.cos( 2 * math.pi * xi)) + 10
return fitness_value
# sphere function def fitness_sphere(position):
fitness_value = 0.0
for i in range ( len (position)):
xi = position[i]
fitness_value + = (xi * xi);
return fitness_value;
# ------------------------- # whale class class whale:
def __init__( self , fitness, dim, minx, maxx, seed):
self .rnd = random.Random(seed)
self .position = [ 0.0 for i in range (dim)]
for i in range (dim):
self .position[i] = ((maxx - minx) * self .rnd.random() + minx)
self .fitness = fitness( self .position) # curr fitness
# whale optimization algorithm(WOA) def woa(fitness, max_iter, n, dim, minx, maxx):
rnd = random.Random( 0 )
# create n random whales
whalePopulation = [whale(fitness, dim, minx, maxx, i) for i in range (n)]
# compute the value of best_position and best_fitness in the whale Population
Xbest = [ 0.0 for i in range (dim)]
Fbest = sys.float_info. max
for i in range (n): # check each whale
if whalePopulation[i].fitness < Fbest:
Fbest = whalePopulation[i].fitness
Xbest = copy.copy(whalePopulation[i].position)
# main loop of woa
Iter = 0
while Iter < max_iter:
# after every 10 iterations
# print iteration number and best fitness value so far
if Iter % 10 = = 0 and Iter > 1 :
print ( "Iter = " + str ( Iter ) + " best fitness = %.3f" % Fbest)
# linearly decreased from 2 to 0
a = 2 * ( 1 - Iter / max_iter)
a2 = - 1 + Iter * (( - 1 ) / max_iter)
for i in range (n):
A = 2 * a * rnd.random() - a
C = 2 * rnd.random()
b = 1
l = (a2 - 1 ) * rnd.random() + 1 ;
p = rnd.random()
D = [ 0.0 for i in range (dim)]
D1 = [ 0.0 for i in range (dim)]
Xnew = [ 0.0 for i in range (dim)]
Xrand = [ 0.0 for i in range (dim)]
if p < 0.5 :
if abs (A) > 1 :
for j in range (dim):
D[j] = abs (C * Xbest[j] - whalePopulation[i].position[j])
Xnew[j] = Xbest[j] - A * D[j]
else :
p = random.randint( 0 , n - 1 )
while (p = = i):
p = random.randint( 0 , n - 1 )
Xrand = whalePopulation[p].position
for j in range (dim):
D[j] = abs (C * Xrand[j] - whalePopulation[i].position[j])
Xnew[j] = Xrand[j] - A * D[j]
else :
for j in range (dim):
D1[j] = abs (Xbest[j] - whalePopulation[i].position[j])
Xnew[j] = D1[j] * math.exp(b * l) * math.cos( 2 * math.pi * l) + Xbest[j]
for j in range (dim):
whalePopulation[i].position[j] = Xnew[j]
for i in range (n):
# if Xnew < minx OR Xnew > maxx
# then clip it
for j in range (dim):
whalePopulation[i].position[j] = max (whalePopulation[i].position[j], minx)
whalePopulation[i].position[j] = min (whalePopulation[i].position[j], maxx)
whalePopulation[i].fitness = fitness(whalePopulation[i].position)
if (whalePopulation[i].fitness < Fbest):
Xbest = copy.copy(whalePopulation[i].position)
Fbest = whalePopulation[i].fitness
Iter + = 1
# end-while
# returning the best solution
return Xbest
# ---------------------------- # Driver code for rastrigin function print ( "\nBegin whale optimization algorithm on rastrigin function\n" )
dim = 3
fitness = fitness_rastrigin
print ( "Goal is to minimize Rastrigin's function in " + str (dim) + " variables" )
print ( "Function has known min = 0.0 at (" , end = "")
for i in range (dim - 1 ):
print ( "0, " , end = "")
print ( "0)" )
num_whales = 50
max_iter = 100
print ( "Setting num_whales = " + str (num_whales))
print ( "Setting max_iter = " + str (max_iter))
print ( "\nStarting WOA algorithm\n" )
best_position = woa(fitness, max_iter, num_whales, dim, - 10.0 , 10.0 )
print ( "\nWOA completed\n" )
print ( "\nBest solution found:" )
print ([ "%.6f" % best_position[k] for k in range (dim)])
err = fitness(best_position)
print ( "fitness of best solution = %.6f" % err)
print ( "\nEnd WOA for rastrigin\n" )
print ()
print ()
# Driver code for Sphere function print ( "\nBegin whale optimization algorithm on sphere function\n" )
dim = 3
fitness = fitness_sphere
print ( "Goal is to minimize sphere function in " + str (dim) + " variables" )
print ( "Function has known min = 0.0 at (" , end = "")
for i in range (dim - 1 ):
print ( "0, " , end = "")
print ( "0)" )
num_whales = 50
max_iter = 100
print ( "Setting num_whales = " + str (num_whales))
print ( "Setting max_iter = " + str (max_iter))
print ( "\nStarting WOA algorithm\n" )
best_position = woa(fitness, max_iter, num_whales, dim, - 10.0 , 10.0 )
print ( "\nWOA completed\n" )
print ( "\nBest solution found:" )
print ([ "%.6f" % best_position[k] for k in range (dim)])
err = fitness(best_position)
print ( "fitness of best solution = %.6f" % err)
print ( "\nEnd WOA for sphere\n" )
|
Output
Begin whale optimization algorithm on rastrigin function Goal is to minimize Rastrigin's function in 3 variables Function has known min = 0.0 at (0, 0, 0) Setting num_whales = 50 Setting max_iter = 100 Starting WOA algorithm Iter = 10 best fitness = 0.018 Iter = 20 best fitness = 0.000 Iter = 30 best fitness = 0.000 Iter = 40 best fitness = 0.000 Iter = 50 best fitness = 0.000 Iter = 60 best fitness = 0.000 Iter = 70 best fitness = 0.000 Iter = 80 best fitness = 0.000 Iter = 90 best fitness = 0.000 WOA completed Best solution found: ['0.000000', '-0.000000', '-0.000000'] fitness of best solution = 0.000000 End WOA for rastrigin Begin whale optimization algorithm on sphere function Goal is to minimize sphere function in 3 variables Function has known min = 0.0 at (0, 0, 0) Setting num_whales = 50 Setting max_iter = 100 Starting WOA algorithm Iter = 10 best fitness = 0.130 Iter = 20 best fitness = 0.000 Iter = 30 best fitness = 0.000 Iter = 40 best fitness = 0.000 Iter = 50 best fitness = 0.000 Iter = 60 best fitness = 0.000 Iter = 70 best fitness = 0.000 Iter = 80 best fitness = 0.000 Iter = 90 best fitness = 0.000 WOA completed Best solution found: ['0.000000', '0.000000', '-0.000000'] fitness of best solution = 0.000000 End WOA for sphere
References:
Research paper: https://www.sciencedirect.com/science/article/pii/S0965997816300163
Author’s original implementation (in MATLAB): https://www.mathworks.com/matlabcentral/fileexchange/55667-the-whale-optimization-algorithm