麻雀优化算法是2020年提出来的,该算法利用麻雀的角色分工和协作机制高效搜索,具有全局优化性能好、寻优性能强的特点,适合与其他技术相融合以改进算法性能。
SSA是基于麻雀觅食与反捕食行为而模拟的一种生物群智能优化策略,也是一种采用发现者、跟随者和警戒者 3类麻雀觅食行为实现算法位置不断变换迭代的优化模型。
种群规模为 n的麻雀位置可表示为:
麻雀觅食位置适应度值的数学表示形式为:
具体过程参考论文:[1]薛建凯. 一种新型的群智能优化技术的研究与应用[D].东华大学,2020.
class SSA():
def __init__(self, func, n_dim=None, pop_size=20, max_iter=50, lb=-512, ub=512, verbose=True):
self.func = func
self.n_dim = n_dim # dimension of particles, which is the number of variables of func
self.pop = pop_size # number of particles
P_percent = 0.2 # # 生产者的人口规模占总人口规模的20%
D_percent = 0.1 # 预警者的人口规模占总人口规模的10%
self.pNum = round(self.pop * P_percent) # 生产者的人口规模占总人口规模的20%
self.warn = round(self.pop * D_percent) # 预警者的人口规模占总人口规模的10%
self.max_iter = max_iter # max iter
self.verbose = verbose # print the result of each iter or not
self.lb, self.ub = np.array(lb) * np.ones(self.n_dim), np.array(ub) * np.ones(self.n_dim)
assert self.n_dim == len(self.lb) == len(self.ub), 'dim == len(lb) == len(ub) is not True'
assert np.all(self.ub > self.lb), 'upper-bound must be greater than lower-bound'
self.X = np.random.uniform(low=self.lb, high=self.ub, size=(self.pop, self.n_dim))
self.Y = [self.func(self.X[i]) for i in range(len(self.X))] # y = f(x) for all particles
self.pbest_x = self.X.copy() # personal best location of every particle in history
self.pbest_y = [np.inf for i in range(self.pop)] # best image of every particle in history
self.gbest_x = self.pbest_x.mean(axis=0).reshape(1, -1) # global best location for all particles
self.gbest_y = np.inf # global best y for all particles
self.gbest_y_hist = [] # gbest_y of every iteration
self.update_pbest()
self.update_gbest()
#
# record verbose values
self.record_mode = False
self.record_value = {'X': [], 'V': [], 'Y': []}
self.best_x, self.best_y = self.gbest_x, self.gbest_y # history reasons, will be deprecated
self.idx_max = 0
self.x_max = self.X[self.idx_max, :]
self.y_max = self.Y[self.idx_max]
def cal_y(self, start, end):
for i in range(start, end):
self.Y[i] = self.func(self.X[i])
def update_pbest(self):
'''
personal best
:return:
'''
for i in range(len(self.Y)):
if self.pbest_y[i] > self.Y[i]:
self.pbest_x[i] = self.X[i]
self.pbest_y[i] = self.Y[i]
def update_gbest(self):
'''
global best
:return:
'''
idx_min = self.pbest_y.index(min(self.pbest_y))
if self.gbest_y > self.pbest_y[idx_min]:
self.gbest_x = self.X[idx_min, :].copy()
self.gbest_y = self.pbest_y[idx_min]
采用两格函数测试分别是:Ackley函数和Drop_Wave函数如下图所示:
Ackley函数最小值为0,Drop_Wave函数最小值为-1.这两个函数都有很多局部最优解。
参数设置如下
n_dim =2
lb = [-20 for i in range(n_dim)]
ub = [20 for i in range(n_dim)]
demo_func = test_function.Ackley
pop_size = 100
max_iter = 1000
ssa = SSA(demo_func, n_dim=n_dim, pop_size=pop_size, max_iter=max_iter, lb=lb, ub=ub,verbose=True)
ssa.run()
参数设置如下
n_dim =2
lb = [-20 for i in range(n_dim)]
ub = [20 for i in range(n_dim)]
demo_func = test_function.Drop_Wave
pop_size = 100
max_iter = 1000
ssa = SSA(demo_func, n_dim=n_dim, pop_size=pop_size, max_iter=max_iter, lb=lb, ub=ub,verbose=True)
ssa.run()
结果还是很好的,函数图像的代码和麻雀算法的源码的获取可以私聊作者。未来将对比一下其他算法,比如粒子群或者灰狼算法。