pso粒子羣優化算法

粒子羣優化算法(Partical Swarm Algorithm,pso)這個算法的原理很簡單,思路就是不斷地迭代,直到尋得最優解爲止,很多書上都有該算法的介紹,此外matlab也自帶了算法的函數:pso(),這裏我自己寫了一個小小的程序來實現算法。

算法的應用背景:對於函數 y=1-cos(3x)*exp(-x), 函數曲線如下,觀察可知在橫軸約爲 x=0.9350~0.9450的地方出現曲線的極值 y=1.3706,現在我要做的是:首先在 x 區間[0,4]範圍內隨機放進去 num 個粒子(xi),目的是找到最大的(yi),他們不斷地改變自己的位置,直到有一天,他們找了很久覺得很累了(達到迭代上限),或者經過反覆比較終於找到最心愛的 y值(尋優結果滿足精度要求),然後這個結果就認爲是最優的。


程序是我自己寫的,很簡單,只要搞明白pso基本算法的原理就能夠理解

function[Pg,n,e]=pso_2(num,ranX,ranV,N,E)
%num代表粒子個數,設定在20~60之間,每個粒子都是一維
%ranX,ranV表示位置、速度的範圍,均爲二維行向量
%N,E搜索終止條件

%%初始化粒子的位置與速度,粒子就像美麗可愛的小鳥一樣,它們時而在左,時而在右,時而快時而慢
x=zeros(num,1);v=zeros(num,1);
for i=1:1:num
      x(i,1)=ranX(1,1)+(ranX(1,2)-ranX(1,1))*rand();
      v(i,1)=ranV(1,1)+(ranV(1,2)-ranV(1,1))*rand();
end
%%計算初始化以後的局部最優和全局最優
f=zeros(num,1);%%適應度函數
Pl=zeros(num,1);Pg=0;%%局部、全局最優
for i=1:1:num
    f(i,1)=1-cos(3*x(i,1))*exp(-x(i,1));
    Pl(i,1)=f(i,1);
end
Pg=max(max(Pl));

n=0;e=5;
while n<N&e>E
    PGold=Pg;
    for i=1:1:num%%計算新一輪的位置與速度
        v(i,1)=0.8*v(i,1)+2*rand()*(Pl(i,1)-x(i,1))+2*rand()*(Pg-x(i,1));
        if v(i,1)<ranV(1,1)%防止速度太小
            v(i,1)=ranV(1,1);
        else 
            if v(i,1)>ranV(1,2)%防止速度太大
                v(i,1)=ranV(1,2);
            end
        end
        x(i,1)=x(i,1)+v(i,1);
        if x(i,1)<ranX(1,1)%防止位置太小
            x(i,1)=ranX(1,1);
        else 
            if x(i,1)>ranX(1,2)%防止位置太大
                x(i,1)=ranX(1,2);
            end
        end
    end
    for i=1:1:num%%計算新一輪的適應度函數
    f(i,1)=1-cos(3*x(i,1))*exp(-x(i,1));
    %%更新局部最優和全局最優
    if Pl(i,1)<f(i,1)
        Pl(i,1)=f(i,1);
    end
    end
   if Pg<max(max(Pl))
       Pg=max(Pl);
   end
   n=n+1;
   e=abs(Pg-PGold);
end



 下面對算法的可行性做一個演示:

num=2;%只有兩個粒子
X=[0,4];% x 軸(位置)的範圍
V=[-0.5,0.5];%速度範圍
N=100;%終止條件
E=0.001;
[Pg,n,e]=pso_2(num,X,V,N,E);

運行結果顯示,只有2個粒子的情況下每次只需要迭代2或3次,但是每次得到的最優值並不總是接近於1.3706,效果不理想,然而如果設置成20個粒子,那麼經過1次尋找就能輕鬆找到1.3706附近。函數的運行效果依賴於粒子個數num,速度範圍ranV,誤差精度E ,這三個主要參數。

發佈了264 篇原創文章 · 獲贊 13 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章