本文主要介绍了典型的粒子群算法流程以及给出了求解函数极值时的matlab代码。
1. 由Eberhart和Kennedy于1995年提出。
2. 早期简单的模型,即Boid(Bird-oid)模型,模拟鸟群觅食行为而建:
每一个鸟的个体用直角坐标系上的点表示,随机地给它们赋一个初速度和初位置,程序运行的每一步都按照“最近邻速度匹配”规则,且在速度项中增加了一个随机变量,即在迭代的每一步,除了满足“最近邻速度匹配”之外,每一步速度还要添加一个随机变化的量,这样使得整个模拟看起来更为真实。
3. 粒子群算法是一种基于种群的搜索过程,其中每个个体称作微粒,定义为在D维搜索空间中待优化问题的潜在解,保存有其历史最优位置和所有粒子的最优位置的记忆,以及速度。在每一演化代,微粒的信息被组合起来调整速度关于每一维上的分量,继而被用来计算新的微粒位置。微粒在多维搜索空间中不断改变它们的状态,直到到达平衡或最优状态,或者超过了计算限制为止。问题空间的不同维度之间唯一的联系是通过目标函数引入的。很多经验证据已经显示该算法是一个非常有效的优化工具。
经典的PSO可分为:
每个粒子找到个体极值pBest和全局极值gBest,更新粒子速度和位置:
测试用例为CEC’17 Benchmark,代码中函数 [] = feval(fhd,x,varargin{:});是调用算例计算粒子的适应值,varargin{:} 指算例编号(第几个)。
The C and Matlab codes for CEC’17 test suite can be downloaded from the website given below:
https://www.ntu.edu.sg/home/epnsugan/
具体代码如下,包括了全局版和局部版PSO,只需要更改输入参数A即可,A是方阵,表示粒子的拓扑邻域结构。
function [position,fit_value]=PSO_func2(fhd,c1,c2,w_max,w_min,D,particlesize,iterations,xmax,A,varargin)
%PSO参数、粒子速度和位置初始化
% position 粒子全局极值位置
% fit_value 全局极值适应度
% fhd = str2func('cec17_func');
% c1 学习因子(个体极值pBest)
% c2 学习因子(全局极值gBest)
% w_max w_min 惯性因子(本代码采用的是线性递减的权重因此有范围限制)
% D 目标函数自变量个数(维数)
% particlesize 粒子群规模
% iterations 最大迭代次数
% xmax 粒子运动范围(问题的自变量范围)
% A 方阵表示粒子的拓扑结构,A是全连通(所有元素为1)则更新速度和公式时采用的全局版,否则是局部版
varargin 指算例编号(第几个)
%初始化粒子
xmax = repmat(xmax,D,particlesize);
vmax = xmax*0.3; %限制粒子最大速度,太大可能飞出范围
x = -xmax+2*xmax.*rand(D,particlesize); %粒子初始位置,随机数
v = -vmax+2*vmax.*rand(D,particlesize); %粒子初始速度,随机数
%初始化个体极值和全局极值
personalbest_x = x;
personalbest_faval = feval(fhd,x,varargin{:});
[globalbest_new_faval,global_new_i] = min(personalbest_faval);
globalbest_new_x=personalbest_x(:,global_new_i);
%初始化邻域极值
temp = A.*repmat(personalbest_faval',1,particlesize);
[nBest_faval,index] = min(temp);
nBest_x = x(:,index);
%迭代循环
k = 1;
while k<=iterations %终止条件
if k<iterations
w = w_max-k*(w_max-w_min)/iterations;%权重线性递减
else
w = w_min;
end
% w=0.6;%固定权重也可以
%更新粒子群里每个个体的最新速度和位置
v = w*v+c1*rand(D,particlesize).*(personalbest_x-x)+c2*rand(D,particlesize).*(nBest_x-x);
v = (v>vmax).*vmax+(v<(-vmax)).*(-vmax)+(v<=vmax).*(v>=-vmax).*v; %避免超出速度最大值
x = x+v;
%超出x范围则重新分配
x = (x>xmax).*(-xmax+2*xmax.*rand(D,particlesize)) + (x<-xmax).*(-xmax+2*xmax.*rand(D,particlesize)) + (x<=xmax).*(x>=-xmax).*x;
% x = (x>xmax).*(xmax) + (x<-xmax).*(-xmax) + (x<=xmax).*(x>=-xmax).*x;
%个体极值
f=(feval(fhd,x,varargin{:}));
flag = f<personalbest_faval;
personalbest_faval = flag.*f+(1-flag).*personalbest_faval;
flag = repmat(flag,D,1);
personalbest_x = flag.*x+(ones(D,particlesize)-flag).*personalbest_x;
%邻域内极值
temp = A.*repmat(personalbest_faval',1,particlesize);
[nBest_faval,index] = min(temp);
nBest_x = x(:,index);
%全局极值
[globalbest_new_faval,global_new_i] = min(personalbest_faval);
globalbest_new_x=personalbest_x(:,global_new_i);
globalbest(k,1)=k;
globalbest(k,2)=globalbest_new_faval;
k=k+1; %循环计数器+1
end
position = globalbest_new_x;
fit_value = globalbest_new_faval;
%结果输出
% value1 = position;%粒子位置
% value1 = num2str(value1);
% disp(strcat('the corresponding coordinate','=',value1));
% value2 = fit_value;%适应度
% value2 = num2str(value2);
% disp(strcat('the minimum value','=',value2));
%全局极值变化过程图像绘制趋势
% if mod(k,5)==1
% figure(1);
% plot(globalbest(:,1),globalbest(:,2));
% end
% ylabel('适应值');
% xlabel('迭代次数');
%二维自变量的图像输出
scale=2;
if D==2
figure(2);
a=-xmax:scale:xmax;
b=a;
[a,b]=meshgrid(a,b);
for i=1:(2*xmax/scale+1)
for j=1:(2*xmax/scale+1)
c=[a(i,j);b(i,j)];
y(i,j)=feval(fhd,c,varargin{:});
j=j+1;
end
i=i+1;
end
mesh(a,b,y);%画三维图
view([-30,50]);%调整图的视角
hold on;
plot3(position(1),position(2),fit_value,'rp','linewidth',2);%标出极点
legend('目标函数','搜索到的最大值');
xlabel('x'),ylabel('y'),zlabel('目标值');
end
收敛性
CEC benchmark中第5个算例求解收敛曲线如下:
CEC benchmark中部分算例结果展示如下:
可以看出来大多数情况下PSO具有较好性能,但众所周知no free lunch定理,不可能对所有算例都是最好的。