pso粒子群优化算法

时间:2022-12-11 00:30:06

粒子群优化算法(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粒子群优化算法

程序是我自己写的,很简单,只要搞明白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 ,这三个主要参数。