果蝇优化算法MATLAB实现 - Go语言中文社区

果蝇优化算法MATLAB实现


果蝇优化算法--Matlab实现

1果蝇优化算法原理介绍

果蝇是一种广泛存在于温带和热带地区的昆虫,具有优于其他物种的嗅觉和视觉能力. 在寻找食物时,果蝇个体先利用自身嗅觉器官嗅到食物的气味,并向周围的果蝇发送气味信息,或者从周围的果蝇接收气味信息;之后果蝇利用其视觉器官,通过比较得出当前群体中收集到最好气味信息的果蝇位置,群体中的其他果蝇均飞向该位置,并继续展开搜索. 图 1展示了果蝇群体搜索食物的简要过程.
果蝇优化算法图

1.1步骤分析

根据果蝇群体觅食的行为特点,标准 FOA寻优
大致分为以下几个步骤.
Step 1:初始化.
设置种群规模(popsize),最大迭代次数(maxgen),果蝇群体位置范围(LR)和果蝇的单次飞行范围(FR)等相关参数值. 果蝇群体中每个个体的位置信息由其对应的(X; Y )二维坐标给出,其初始位置由下面的公式定义:

left  X_a_x_i_s=rand(LR) right.
Y_a_x_i_s=rand(LR)

Step 2:嗅觉搜索过程.
Step 2.1:当群体中的每一只果蝇利用其嗅觉搜索时,赋予它一个随机的飞行方向和距离. 果蝇个体 新的位置由下式给出:
X_i=X_a_x_i_s+rand(FR)

Y_i=Y_a_x_i_s+rand(FR)

Step 2.2:因为食物味道的来源位置是未知的,因此先利用下式计算果蝇个体距离原点的距离DISTi:
Dist_i=sqrt{X_i^{2}+Y_i^{2}}

然后通过下式计算其味道浓度判定值Si:
S_i=1/Dist_i

Step 2.3:通过下式计算当前群体中每个果蝇个体的味道浓度值Smelli:
Smell_i=fitness(S_i)

fitness表示味道浓度判断函数,在利用FOA进行优化问题求解时,它是目标函数或适应度函数.
Step 2.4:选择当前群体中具有最佳味道浓度值的果蝇,记录其味道浓度值和相应位置
[bestSmell,bestIndex]=min(Smell)

Step 3:视觉搜索过程.
保持最佳味道浓度值和对应果蝇位置信息,群体中的其他果蝇均利用视觉飞向此位置,即
Smellbest=bestSmell

X_a_x_i_s=X(bestIndex)

Y_a_x_i_s=Y(bestIndex)

Step 4:重复Step 2和Step 3,直到算法迭代次数达到maxgen.
由 FOA的计算步骤可知,标准 FOA采用基于种群的全局随机搜索策略,通过跟踪当前最优解的信息来指导种群的下一步搜索,使得种群能够以当前最优解为中心开展局部随机搜索,并朝着更优的方向搜索前进.
 

2果蝇优化算法程序设计

根据果蝇算法步骤,设计MATlab程序如下

%% FOA封装程序
clc;
clear;
for gen=1:30
%% 初始化参数
maxgen=100; %最大迭代次数
sizepop=50;
dim=30;
L=1;
%% 初始化矩阵
X_best=zeros(maxgen,dim);
Y_best=zeros(maxgen,dim);
Smell_best=zeros(1,maxgen);
%% 初始化果蝇坐标;
X_axis=10*rand(1,dim);
Y_axis=10*rand(1,dim);
%% 生成果蝇群
[Si,X,Y]=gengrate_foa(X_axis,Y_axis,sizepop,dim,L);
%% 寻找最优个体
[BestSmell,Index]=find_Sum_Square(Si);
SmellBest=BestSmell;               %SmellBest为全局最优
%% 取出最优个体的两个维度的X,Y坐标
X_axis=X(Index,:);
Y_axis=Y(Index,:);
for g=1:maxgen
    %% 生成果蝇群
    [Si,X,Y]=gengrate_foa(X_axis,Y_axis,sizepop,dim,L);
    %% 寻找最优个体
    [BestSmell,Index]=find_Sum_Square(Si);
    if BestSmell<SmellBest
        X_axis=X(Index,:);
        Y_axis=Y(Index,:);    
        %更新极值
        SmellBest=BestSmell;
    end
    Smell_best(g)=SmellBest;
    X_best(g,:)=X_axis;
    Y_best(g,:)=Y_axis;
end
    S(gen)=SmellBest;
end
%% 输出最终值
SmellBest
%% 绘制图像
figure(1)
plot(Smell_best,'b');   %绘制每一代最优浓度值
figure(2)
hold on
plot(X_best(:,1),Y_best(:,1),'r.');%绘制果蝇群X_axis,Y_axis的变化
plot(X_best(:,2),Y_best(:,2),'b.');
plot(X_best(:,3),Y_best(:,3),'k.');
figure(3)
plot(X(:,1),Y(:,1),'b.');%绘制最后一代的果蝇群;
mean(S)
min(S)
std(S)

将FOA果蝇群生成,和计算果蝇味道浓度值Smill_{i}封装成函数,输入的是种群坐标,种群个数,维度和步长值,输出的是每个果蝇的坐标和果蝇的味道浓度判定值S_i

function [Si,X,Y]=gengrate_foa(X_axis,Y_axis,sizepop,dim,L)
    Di=zeros(sizepop,dim);
    Si=zeros(sizepop,dim);
    
    X_axis=repmat(X_axis,sizepop,1);    %将种群坐标扩充;
    Y_axis=repmat(Y_axis,sizepop,1);
    X=X_axis+2*L*rand(sizepop,dim)-L;%求出每个果蝇的坐标矩阵;
    Y=Y_axis+2*L*rand(sizepop,dim)-L;
    Di1=X.^2;   %求出X^2和Y^2;
    Di2=Y.^2;
    Di=Di1+Di2; %X^2+Y^2;
    Di=Di.^0.5; %开根号;
    
    Si=1./Di;   %Si=1/Di;

end

求果蝇味道浓度值Smill_{i},对每个测试函数都不同,此处用了SumSquare函数,这个函数的表达式是

                                                                                 F(x)=sum_{i=1}^{n}ix^2

其三维函数图像如下图

 

 

                                                   SumSquare函数图像

其函数编写如下,函数输入只需要果蝇个体的味道判定值S_i,带入函数中解出最优的味道浓度值和其索引,就能对应着找到最优的果蝇个体了。

%% 果蝇浓度判定函数;
%Function:Sum Square
%表达式:f(x)=Sum(i*(Xi)^2);
function [BestSmell,Index]=find_Sum_Square(Si)

[si_m,si_n]=size(Si);
sum_2=zeros(1,si_n);
for d=1:si_n
    sum_2(d)=d;
end

Si_2=Si.^2;         %所有元素平方;
Smell=Si_2.*sum_2;
Smell=sum(Smell,2);
[BestSmell,Index]=min(Smell);
end

 


对函数进行测试

试验设置独立运行30次,并记录每次的寻优结果,最后求一下30次寻优结果的均值,最小值和均方差。

对测试结果绘制图片,figure(1)绘制的是每次迭代的种群最优值,可以看到最优值一直在降低,最终趋向于收敛于0(函数最优值),这就说明果蝇群每一次迭代都在向最优值前进,一点点寻优。

迭代曲线

 

figure(2)绘制的是果蝇群坐标随着迭代次数增长的变化,一点点在向外面扩散,这里设置的函数为30维,画图的话只画了其中3维,分别用红色,蓝色和黑色表示,每一维扩散的方向都不同。

果蝇群坐标变化

figure(3)绘制的是最后一代果蝇群的坐标分布,这里只画了一维的坐标分布,可以看出是围绕着中心点向四周随机飞行的,因为这里设置步长为1,所以上下幅度为最大为2。

果蝇群分布

要是想测试其他寻优函数,可以根据我的测试函数模板进行编写,将Si作为变量X带入,求出最小的Y值就是最优果蝇了,下面在放上两个我已经编好的寻优函数,Ackley和Rastrigin。

%% 果蝇浓度判定函数;
%Function:Rastrigin
%表达式:f(x)=Sum[(Xi)^2-10cos(2pi*xi)+10];
function [BestSmell,Index]=find_Rastrigin(Si)
[si_m,si_n]=size(Si);
sum_2=zeros(si_m,1);
                    %第一部分:平方和
Si_2=Si.^2;         %所有元素平方;
sum_1=sum(Si_2,2);  %求各维度平方和;


%第二部分:cos(2pi*Xi)
for p=1:si_m        
    for d=1:si_n
        sum_2(p)=sum_2(p)+10*cos(2*pi*Si(p,d));
    end
end
Smell=sum_1-sum_2+10*si_n;
[BestSmell,Index]=min(Smell);
end

 

%Function:Ackley
%表达式:
function [BestSmell,Index]=find_Ackley(Si)
[si_m,si_n]=size(Si);
sum_2=zeros(si_m,1);
                    %第一部分:平方和
Si_2=Si.^2;         %所有元素平方;
sum_1=sum(Si_2,2);  %求各维度平方和;
sum_1=-0.2.*((sum_1/30).^0.5);    
sum_1=-20.*(exp(sum_1));


%第二部分:cos(2pi*Xi)
for p=1:si_m        %cos(Xi)/sqrt(i)部分
    for d=1:si_n
        sum_2(p)=sum_2(p)+cos(2*pi*Si(p,d)); 
    end
    sum_2(p)=sum_2(p)/30;
    sum_2(p)=-1*exp(sum_2(p));
end
Smell=sum_1+sum_2+20+exp(1);
[BestSmell,Index]=min(Smell);
end

代码已经经过测试了,可以直接拷贝到m文件中,保存在相同路径运行,注意函数的名称要和文件名称相同。主函数里面的参数sizepop,dim以及L,maxgen都是可以随意设置的,可以设置观测不同结果。

资源:

1、最后附上我的代码,里面封装了几个常用的测试函数和原代码。

https://download.csdn.net/download/stm32_newlearner/10722535

2、打包了综述(果蝇优化算法研究综述)所有论文,包括很多外文,可以说很全的果蝇算法文献了,对算法优化研究很有作用。

https://download.csdn.net/download/stm32_newlearner/10976713

 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/stm32_newlearner/article/details/82990567
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-05-16 17:14:25
  • 阅读 ( 1625 )
  • 分类:算法

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢