NiaPy
NiaPy copied to clipboard
Squirrel search algorithm implementation
Squirrel search algorithm publication is currently the most cited article in SWEVO.
It would be nice to have this algorithm in our collection.
Has anyone time to implement this algorithm?
can you assign me on this?
@altaregos, thanks. Yeah. Of course.
I've made an attempt:
import numpy as np
from niapy.algorithms import Algorithm
from niapy.util.random import levy_flight
from niapy.task import Task
class SquirrelSearchAlgorithm(Algorithm):
Name = ['SquirrelSearchAlgorithm', 'SSA']
def __init__(self, population_size=50, food_sources=4, prob_predation=0.1, gliding_constant=1.9, scale=18, *args, **kwargs):
super().__init__(population_size, *args, **kwargs)
self.food_sources = food_sources
self.prob_predation = prob_predation
self.gliding_constant = gliding_constant
self.scale = scale
def set_parameters(self, population_size=50, food_sources=4, prob_predation=0.1, gliding_constant=1.9, scale=18, *args, **kwargs):
super().set_parameters(population_size, *args, **kwargs)
self.food_sources = food_sources
self.prob_predation = prob_predation
self.gliding_constant = gliding_constant
self.scale = scale
def get_parameters(self):
params = super().get_parameters()
params.update({
'food_sources': self.food_sources,
'prob_predation': self.prob_predation,
'gliding_constant': self.gliding_constant,
'scale': self.scale,
})
return params
def gliding_distance(self):
lift = 0.9783723933835806 / self.uniform(0.675, 1.5)
drag = 1.630620655639301
return 8.0 / (self.scale * drag / lift)
def run_iteration(self, task, population, population_fitness, best_x, best_fitness, **params):
indices = np.argsort(population_fitness)
ht = indices[0]
at = indices[1:self.food_sources]
nt = indices[self.food_sources:]
new_population = population.copy()
for index in at:
if self.random() >= self.prob_predation:
new_population[index] += self.gliding_distance() * self.gliding_constant * (population[ht] - population[index])
new_population[index] = task.repair(new_population[index], rng=self.rng)
else:
new_population[index] = self.uniform(task.lower, task.upper)
nt = self.rng.permutation(nt)
nt_1 = nt[:len(nt) // 2] # half go to acorn trees
nt_2 = nt[len(nt) // 2:] # other half go to hickory trees
for index in nt_1:
if self.random() >= self.prob_predation:
a = self.rng.choice(at)
new_population[index] += self.gliding_distance() * self.gliding_constant * (population[a] - population[index])
new_population[index] = task.repair(new_population[index], rng=self.rng)
else:
new_population[index] = self.uniform(task.lower, task.upper)
for index in nt_2:
if self.random() >= self.prob_predation:
new_population[index] += self.gliding_distance() * self.gliding_constant * (population[ht] - population[index])
new_population[index] = task.repair(new_population[index], rng=self.rng)
else:
new_population[index] = self.uniform(task.lower, task.upper)
s_min = 1e-5 / (365 ** ((task.iters + 1) / (task.max_iters / 2.5)))
sc = np.sqrt(np.sum((new_population[at] - new_population[ht]) ** 2))
if sc < s_min:
new_population[nt_1] = task.lower + levy_flight(size=(len(nt_1), task.dimension), rng=self.rng) * task.range
new_population[nt_1] = task.repair(new_population[nt_1], rng=self.rng)
new_fitness = np.apply_along_axis(task.eval, 1, new_population)
best_x, best_fitness = self.get_best(new_population, new_fitness, best_x, best_fitness)
return new_population, new_fitness, best_x, best_fitness, {}
if __name__ == '__main__':
fit = []
for i in range(30):
task = Task('sphere', dimension=30, lower=-10, upper=10, max_iters=500)
algo = SquirrelSearchAlgorithm()
_, best_fitness = algo.run(task)
fit.append(best_fitness)
print(f'Best: {np.min(fit)}')
print(f'Worst: {np.max(fit)}')
print(f'Mean: {np.mean(fit)}')
print(f'Std: {np.std(fit)}')
But I don't get the same results as the ones in the article. For this example (30 runs, 30-D sphere on [-10, 10], max_iters=500) i get:
Best: 7.5371836448343156e-06
Worst: 8.828262744205666e-05
Mean: 4.013667587147927e-05
Std: 2.289286326787123e-05
and in the article they got:
Best: 7.9225e-20
Worst: 5.7411e-07
Mean: 4.1689E-08
Std: 1.4356E-07
The article is extremely unclear, in my opinion. At least it was to me. It doesn't say how to choose which squirrels on normal trees go towards acorn trees and which towards the hickory tree, it just says "do it randomly". I just chose half randomly. Also, I don't know if I'm calculating the season constant correctly, because the equation is formatted weirdly and there's no real explanation of it. And then if the seasons change, I don't know which squirrels to move via levy flights.
Any ideas what I'm doing wrong? Otherwise I'd say it's best just not to include it.
Hi How use this algorithm for optimization upl in mining Plz help me
@zStupan, I'm confused by what you mean. Aren't the SSA results going to be different each time you run it? I haven't looked into this much, but just putting ideas out there
@BrandonDuncan13 yes the results are different each time, but I would expect that the average fitness over 30 runs would be of similar magnitude as the results in the paper.
I mean, how to use this algorithm for optimization. I can't write its program. What should I study for this?
@zStupan Ohh, okay, I see what you're talking about now. Yeah I agree the average fitness should be a similar magnitude. I will spend time trying to improve your code within the next few weeks but I don't have much confidence in improving it haha
@Nehazzi If you're looking to apply this optimization algorithm to a coding project, I would either look at the MatLab code that exists for SSA or look at how other optimization algorithms have been applied to coding projects. Then you can figure out how to apply the SSA code above to your coding project. Idk what you're asking but I think that's what you were looking for