果蠅優化算法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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章