粒子群算法(PSO)是通过模拟鸟群觅食行为而发展起来的一种基于群体协作的随机搜索算法。PSO模拟鸟群的觅食行为。一群分散的鸟在随机地飞行觅食,它们不知道食物所在的具体位置,但是有一个间接的机制会让小鸟知道它当前位置离食物的距离(例如食物香味的浓淡等),于是各个小鸟就会在飞行过程中不断记录和更新它曾经到达的离食物最近位置,同时,它们通过信息交流的方式比较大家所找到的最好位置,得到一个当前整个群体已经找到的最佳位置。这样,每个小鸟在飞行的时候就有了一个指导的方向,它们会结合自身的经验和整个群体的经验,调整自己的飞行速度和所在位置,不断地寻找更加接近食物的位置,最终使得群体聚集到食物位置。
(1)初始化所有的粒子,初始化他们的速度和位置,并且将个体的历史最优pBest设为当前位置,而群体中最优的个体作为当前的gBest。
(2)在每一代的进化中,计算各个粒子的适应度函数值。
(3)如果该粒子当前的适应度函数值比其历史最优值要好,那么历史最优将会被当前位置所替代;如果该粒子的历史最优比全局最优要好,那么全局最优将会被该粒子的历史最优所替代。
(4)更新每个粒子的速度和位置。
(5)如果还没有到达结束条件,则转到 (2),否则输出gBest并结束。
%% 清空环境
clc
clear
%% 参数初始化
%粒子群算法中的三个参数
c1 = 1.49445;%加速因子
c2 = 1.49445;
w=0.9; %惯性权重
maxgen=1000; % 进化次数
sizepop=200; %种群规模
Vmax=1; %限制速度围
Vmin=-1;
popmax=5; %变量取值范围
popmin=-5;
dim=10; %适应度函数维数
func=1; %选择待优化的函数,1为Rastrigin,2为Schaffer,3为Griewank
Drawfunc(func);%画出待优化的函数,只画出二维情况作为可视化输出
%% 产生初始粒子和速度
for i=1:sizepop
%随机产生一个种群
pop(i,:)=popmax*rands(1,dim); %初始种群
V(i,:)=Vmax*rands(1,dim); %初始化速度
%计算适应度
fitness(i)=fun(pop(i,:),func); %粒子的适应度
end
%% 个体极值和群体极值
[bestfitness bestindex]=min(fitness);
gbest=pop(bestindex,:); %全局最佳
pbest=pop; %个体最佳
fitnesspbest=fitness; %个体最佳适应度值
fitnessgbest=bestfitness; %全局最佳适应度值
%% 迭代寻优
for i=1:maxgen
w=(0.95-0.05)/(0-maxgen)*i+0.95; %w的值随着进化次数呈线性变化
fprintf('第%d代 w=%f ',i,w);
fprintf('最优适应度%f\n',fitnessgbest);
c1=(1.99-0.01)/(0-maxgen)*i+1.99; %c1的值随着进化次数呈线性变化
c2=(0.01-1.99)/(maxgen-0)*i+0.01; %c2的值随着进化次数呈线性变化
for j=1:sizepop
%速度更新
V(j,:) = w*V(j,:) + c1*rand*(pbest(j,:) - pop(j,:)) + c2*rand*(gbest - pop(j,:)); %根据个体最优pbest和群体最优gbest计算下一时刻速度
V(j,find(V(j,:)>Vmax))=Vmax; %限制速度不能太大
V(j,find(V(j,:)<Vmin))=Vmin;
%种群更新
pop(j,:)=pop(j,:)+0.5*V(j,:); %位置更新
pop(j,find(pop(j,:)>popmax))=popmax;%坐标不能超出范围
pop(j,find(pop(j,:)<popmin))=popmin;
if rand>0.98 %加入变异种子,用于跳出局部最优值
pop(j,:)=rands(1,dim);
end
%更新第j个粒子的适应度值
fitness(j)=fun(pop(j,:),func);
end
for j=1:sizepop
%个体最优更新
if fitness(j) < fitnesspbest(j)
pbest(j,:) = pop(j,:);
fitnesspbest(j) = fitness(j);
end
%群体最优更新
if fitness(j) < fitnessgbest
gbest = pop(j,:);
fitnessgbest = fitness(j);
end
end
yy(i)=fitnessgbest;
end
%% 结果分析
figure;
plot(yy)
title('最优个体适应度','fontsize',12);
xlabel('进化代数','fontsize',12);ylabel('适应度','fontsize',12);
当其他参数不变,参数w随着迭代次数的变化而线性变化时
结论:w是惯性权重参数,w取值较大时,种群中粒子的搜索能力变强,局部搜索能力减弱,虽有利于算法的全局搜索并得到全局最优解,但不易得到精确解;相反,w取值较小时,种群中粒子的局部搜索能力增强,全局搜索能力减弱,虽有利于算法的收敛,但粒子容易陷入局部“最优解”。因此,当算法初期具有较大的w,使得算法初期具有较强的搜索能力,而随着算法的进行w的值逐渐变小,使得算法能得到相对精确的结果时,算法的性能较好。
当其他参数不变,参数c1随着迭代次数的变化而线性变化时
结论:c1为自身加速因子参数,决定微粒个体经验对微粒自身运行轨迹的影响,使粒子向群体内的最优点靠近。c1较小时,可能使粒子盲目向局部最优靠拢,在远离目标区域内徘徊,从而陷入局部最优;c1较大时,粒子行为分散,收敛速度变慢,难以找到最优解。
当其他参数不变,参数c2随着迭代次数的变化而线性变化时
结论:c2为全局加速因子参数,决定群体经验对微粒自身运行轨迹的影响。c2较小时,粒子趋向于自身曾经走过的最优路线,从而使得粒子较分散,导致收敛速度缓慢;c2较大时,可使粒子迅速向目标区域移动,但盲目移动至目标区域可能会使粒子错过最优解。
结论:从适应度上看,随着维度的增大,Rastrigin函数的适应度值越来越大,Schaffer函数的适应度值始终为-1,Griewank函数的适应度值由0缓慢增大;从运行时间上看,三者的运行时间都随着维度的增大而增加,其中Schaffer函数变化幅度比Rastrigin函数、Griewank函数大。
结论:从适应度上看,随着种群数量的增大,Rastrigin函数的适应度值缓慢增大,Schaffer函数的适应度值始终为-1,Griewank函数的适应度值始终为0;从运行时间上看,三者的运行时间都随着适应度函数维度的增大而增大,其中Schaffer函数、Griewank函数变化幅度相对较大,Rastrigin函数变化幅度不明显。
粒子群算法中各个参数对算法的运行效率有较大影响。例如参数w(惯性权重)的改变会对最优结果的搜索产生影响,而种群数量、维度的改变基本不会影响最优结果的搜索。即使在同一参数设置下,算法的效率也大有不同,例如其他参数不变时,Rastrigin函数、Schaffer函数、Griewank函数三者的最优结果的搜索也会不同。