今天为大家带来一期融合蝴蝶搜索的麻雀优化算法。算法是由作者自行改进,全网独一份。重要提示:融合蝴蝶搜索的麻雀优化算法不会在原有麻雀算法上增加计算复杂度!
受到蝴蝶算法全局更新方式的启发,将蝴蝶算法独特的感觉和个体感知能力融入麻雀算法中,增强麻雀算法在发现者位置更新阶段的全局搜索能力,提升了麻雀算法的寻优能力。
原理详解
经过对麻雀算法的研究,绝大多数作者都对麻雀算法的发现者阶段位置更新公式进行了改进或替换,这说明麻雀算法在发现者阶段的位置更新能力确实不佳!因此大家今后在改进麻雀算法的时候,也可以尝试改进此部分!
本篇文章采用的改进策略如下:
①采用立方体混沌映射初始化粒子
选用均匀性更好的立方混沌映射初始化麻雀种群。公式如下:
②在发现者阶段加入蝴蝶算法搜索策略,当R2<=ST的时候,公式如下:
f 是麻雀对食物的感知强度,即食物的味道能够被其他麻雀发现的强度; c 是麻雀的感觉模态; I 是刺激强度; a 是依赖于模态的幂指数,它解释了不同程度食物味道的吸收。在发现者搜索阶段,麻雀朝着食物移动。
③三角形游走策略
依旧是在麻雀算法的发现者阶段,当R2>ST的时候,加入三角形游走策略。在麻雀发现食物后,不需要直接接近食物,可以在食物周围游走,增加麻雀的随机性。三角形游走策略的公式如下:
再采用下述公式求出获得麻雀游走后得到的位置。
结果展示
在CEC2005函数中测试,设种群数为50,迭代次数为1000。将融合蝴蝶搜索和三角形游走的麻雀算法(Sparrow Search Algorithm Combining Butterfly Search and Triangle Walk,BTSSA),麻雀搜索算法(SSA),蜣螂优化算法(DBO)进行对比,结果如下:
可以看到融合蝴蝶搜索和三角形游走的麻雀算法(BTSSA)在CEC2005上表现非常好!都把当下最热的DBO算法给干趴下了。且本文所提算法并没有增加计算复杂度,没有添加很多冗余的策略(比如反向学习,贪婪策略等)。
代码展示
%%
clear
clc
close all
number='F1'; %选定优化函数,自行替换:F1~F23
[lower_bound,upper_bound,variables_no,fobj]=CEC2005(number); % [lb,ub,D,y]:下界、上界、维度、目标函数表达式
pop_size=50; % population members
max_iter=1000; % maximum number of iteration
%% DBO
[best_score,best_x,DBO_convergence_curve]=DBO(pop_size,max_iter,lower_bound,upper_bound,variables_no,fobj);
display(['The best optimal value of the objective funciton found by DBO for ' [num2str(number)],' is : ', num2str(best_score)]);
fprintf ('Best solution obtained by DBO: %s\n', num2str(best_x,'%e '));
%% SSA
[best_score,best_x,SSA_convergence_curve]=SSA(pop_size,max_iter,lower_bound,upper_bound,variables_no,fobj);
display(['The best optimal value of the objective funciton found by SSA for ' [num2str(number)],' is : ', num2str(best_score)]);
fprintf ('Best solution obtained by SSA: %s\n', num2str(best_x,'%e '));
%% BTSSA
[best_score,best_x,BTSSA_convergence_curve]=BTSSA(pop_size,max_iter,lower_bound,upper_bound,variables_no,fobj);
display(['The best optimal value of the objective funciton found by BTSSA for ' [num2str(number)],' is : ', num2str(best_score)]);
fprintf ('Best solution obtained by BTSSA: %s\n', num2str(best_x,'%e '));
%% Figure
figure1 = figure('Color',[1 1 1]);
G1=subplot(1,2,1,'Parent',figure1);
func_plot(number)
title(number)
xlabel('x')
ylabel('y')
zlabel('z')
subplot(1,2,2)
G2=subplot(1,2,2,'Parent',figure1);
CNT=20;
k=round(linspace(1,max_iter,CNT)); %随机选CNT个点
% 注意:如果收敛曲线画出来的点很少,随机点很稀疏,说明点取少了,这时应增加取点的数量,100、200、300等,逐渐增加
% 相反,如果收敛曲线上的随机点非常密集,说明点取多了,此时要减少取点数量
iter=1:1:max_iter;
if ~strcmp(number,'F16')&&~strcmp(number,'F9')&&~strcmp(number,'F11') %这里是因为这几个函数收敛太快,不适用于semilogy,直接plot
semilogy(iter(k),DBO_convergence_curve(k),'m-*','linewidth',1);
hold on
semilogy(iter(k),SSA_convergence_curve(k),'b-p','linewidth',1);
hold on
semilogy(iter(k),BTSSA_convergence_curve(k),'g-^','linewidth',1);
else
plot(iter(k),DBO_convergence_curve(k),'m-*','linewidth',1);
hold on
plot(iter(k),SSA_convergence_curve(k),'b-p','linewidth',1);
hold on
plot(iter(k),BTSSA_convergence_curve(k),'g-^','linewidth',1);
end
grid on;
title('收敛曲线')
xlabel('迭代次数');
ylabel('适应度值');
box on
legend('DBO','SSA','BTSSA')
set (gcf,'position', [300,300,800,330])
代码获取方式
后台回复关键字,不区分大小写。关键字:
BTSSA