今天来复现一篇改进的蝴蝶算法,参考文献为:
[1]高文欣, 刘升, 肖子雅, 等. 柯西变异和自适应权重优化的蝴蝶算法[J]. 计算机工程与应用, 2020, 56(15): 43-50.
文章摘要如下:
针对基本蝴蝶优化算法(Butterfly Optimization Algorithm,BOA)存在的收敛精度较低、容易陷入局部最优解的问题,提出柯西变异和自适应权重优化的蝴蝶算法(Cauchy variation and adaptive Weight Butterfly OptimizationAlgorithm,CWBOA)。通过在全局位置更新处引入柯西分布函数进行变异,在局部位置更新处引入自适应权重因子,改进了蝴蝶算法的局部搜索能力;并且引入动态切换概率p 来权衡全局探索与局部开发过程的比重。改进的算法通过对多个单峰、多峰和固定测试维度的函数进行求解,结果表明,CWBOA对大多数测试函数有更好的求解精度、速度和稳定性。
改进策略详解
改进点1:柯西变异
针对蝴蝶优化算法易陷入局部最优的特点,利用柯西变异来增加种群的多样性,提高算法的全局搜索能力,增加搜索空间。柯西分布函数在原点处的峰值较小但在两端的分布比较长,利用柯西变异能够在当前变异的蝴蝶个体附近生成更大的扰动从而使得柯西分布函数的范围比较广[11],采用柯西变异两端分布更容易跳出局部最优值。本文融入柯西算子,充分利用柯西分布函数两端变异的效果来优化算全局最优个体,使得算法能够更好地达到全局最优。标准柯西分布函数公式如下:
改进后,公式如下:
改进点2:自适应权重
惯性权重因子是很重要的一个参数,当惯性权重比较大时,算法全局搜索能力较强,能够增加种群多样性,可以搜索较大的区域;当惯性权重比较小时,算法局部搜索能力较强,可以在最优解周围精细搜索,加快收敛速度。蝴蝶接近食物的时候,采用较小的自适应权重改变此时最优的蝴蝶的位置,使得蝴蝶局部寻优能力得到提高。自适应权重公式如下式所示:
改进后的公式如下:
通过融合自适应权重因子w ,使蝴蝶个体具有更好的局部寻优能力。
改进点3:动态切换概率策略
在基本蝴蝶优化算法中,局部搜索和全局寻优过程用常量切换概率p ∈[0,1] 来控制,一个合理的搜索过程在算法的前期应该进行较强烈的全局搜索,迅速定位搜索空间中全局最优解所在范围,在探索后期局部开采能力应增强,以提升算法的寻优精度。本文引入动态切换概率来平衡局部开采和全局开采的比重,来实现更好的寻优策略。动态切换概率p 的公式如下:
结果展示
在CEC2005中测试:每个算法运行200次,种群设置为30个。BOA为原始蝴蝶算法,CWBOA为改进的蝴蝶算法。
部分代码展示:
%% 淘个代码 %%
%微信公众号搜索:淘个代码,获取更多免费代码
%禁止倒卖转售,违者必究!!!!!
%唯一官方店铺:https://mbd.pub/o/author-amqYmHBs/work,其他途径都是骗子!
clear
clc
close all
addpath(genpath(pwd));
number='F1'; %选定优化函数,自行替换:F1~F23
[lower_bound,upper_bound,variables_no,fobj]=Get_Functions_details(number); % [lb,ub,D,y]:下界、上界、维度、目标函数表达式
pop_size=30; % population members
max_iter=200; % maximum number of iteration
%% CWBOA
[CWBOA_Best_score,Best_pos,CWBOA_curve]=CWBOA(pop_size,max_iter,lower_bound,upper_bound,variables_no,fobj); % Calculating the solution of the given problem using CWBOA
display(['The best optimal value of the objective funciton found by CWBOA for ' [num2str(number)],' is : ', num2str(CWBOA_Best_score)]);
%% BOA
[BOA_Best_score,~,BOA_curve]=BOA(pop_size,max_iter,lower_bound,upper_bound,variables_no,fobj);
display(['The best optimal value of the objective funciton found by BOA for ' [num2str(number)],' is : ', num2str(BOA_Best_score)]);
%% 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),BOA_curve(k),'m-*','linewidth',1);
hold on
semilogy(iter(k),CWBOA_curve(k),'g-x','linewidth',1);
else
hold on
plot(iter(k),BOA_curve(k),'m-*','linewidth',1);
hold on
plot(iter(k),CWBOA_curve(k),'g-x','linewidth',1);
end
grid on;
title('收敛曲线')
xlabel('迭代次数');
ylabel('适应度值');
box on
legend('BOA','CWBOA')
set (gcf,'position', [300,300,800,330])
rmpath(genpath(pwd))
代码目录
点击下方卡片获取更多代码!