粒子群优化算法(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 ,这三个主要参数。