1 选题描述
粒子群算法(particle swarm optimization,PSO)是计算智能领域,除了蚁群算法、鱼群算法之外的一种群体智能地优化算法。该算法最早由Kennedy和Eberhart在1995年提出的。PSO算法源于对鸟类捕食行为的研究,鸟类捕食时,找到食物最简单有效的策略就是搜寻当前距离事物最近的鸟的周围区域。PSO算法是从这种生物种群行为特征中得到启发并用于求解优化问题的,算法中每个粒子都代表问题的一个潜在解,每个粒子对应一个由适应度函数决定的适应度值。粒子的速度决定了粒子移动的方向和距离,速度随自身及其他粒子的移动经验进行动态调整,从而实现个体在可解空间中的寻优。
PSO算法首先在可行解空间中初始化一群粒子,每个粒子都代表极值优化问题的一个潜在最优解,用位置、速度和适应度值三项指标表示该粒子特征,适应度值由适应度函数计算得到,其值得好坏表示粒子的优劣。粒子在姐空间中运动,通过跟踪个体极值Pbest和群体极值Gbest更新个体位置。个体极值Pbest是指个体所经历位置中计算得到的适应度值最优位置,群体极值Gbest是指种群中的所有粒子搜索到的适应度最优位置。粒子每更新一次位置,就计算一次适应度值,并且通过比较新粒子的适应度值和个体极值、群体极值的适应度值更新个体极值Pbest和群体极值Gbest位置。
粒子群算法已经在优化问题求解、电力系统、计算机、控制等诸多领域得到了成功应用。利用粒子群算法解决函数优化问题简单自然,易于实现,而且有深刻的智能背景,是科学研究和工程应用中十分重要的一员。
2 程序设计分析
2.1 算法思想及原理
PSO算法不像遗传算法那样对个人进行选择、交叉和变异操作,而是将群体中的每个个体视为多维搜索空间中的一个没有质量和体积的粒子(点),这些粒子在搜索空间中以一定的速度飞行,并根据粒子本身的飞行经验以及同班的飞行经验对自己的飞行速度进行动态调整,即每个粒子通过统计迭代过程中自身的最优值和群体的最优值来不断地修正自己的前进方向和速度大小,从而形成群体寻优的正反馈机制。PSO算法就是这样依据每个粒子对环境的适应度将个体逐步移到较优的区域,并最终搜索、寻找到问题的最优解。
在PSO算法中,用粒子的位置表示待优化问题的解,每个粒子性能的优劣程度取决于待优化问题目标函数确定的适应值,每个粒子由一个速度矢量决定其飞行方向和速率大小。设在一个D维的目标搜索空间中,有n个粒子组成一个种群X=(X1,X2 ,…,Xn),其中第i个粒子表示为一个D维的向量,代表第i个粒子在D维搜索空间中的位置,也代表问题的一个潜在解。根据目标函数即可计算出每个粒子位置Xi对应的适应度值。第i个粒子的速度为Vi=(Vi1,Vi2,Vi3 ,…,ViD,其个体极值为Pi=(Pi1,Pi2,…,PiD,种群的群体极值为Pg=(Pg1,Pg2,…,PgD。
在每次迭代过程中,粒子通过个体极值和群体极值更新自身的速度和位置,即
其中,为惯性权重;d=1,2,…,D; i=1,2,…,n;k为当前迭代次数;Vid为粒子的速度;c1和c2是非负的常数,称为加速度因子;r1和r2是分布于[0,1]区间的随机数。为防止粒子的盲目搜索,一般将其位置和速度限制在一定的区间[-Xmax,Xmax]、[-Xmax,Xmax]。
2.2 算法参数设置
为惯性权重,取大值可使算法具有较强的全局搜索能力,取小值则算法倾向于局部搜索。一般的做法是将初始去0.9并使其随迭代次数的增加而线性递减至0.4,这样就可以先侧重于全局搜索,是搜索空间快速收敛与某一区域,然后采用局部精细搜索以获得高精度的解;
c1和c2为两个学习因子(加速度因子),是非负常数,一般取为2;
更新过程中,粒子每一维的位置、速度都被限制在允许范围之内。如果当前对粒子的加速导致它在某维的速度Vi超过该维的最大速度Vdmax,则该维的速度被限制为该维最大速度上限Vdmax。一般来说,Vdmax的选择不应超过的粒子宽度范围,如果Vdmax太大,粒子可能飞过最优解的位置;如果太小,可能降低粒子的全局搜索能力。
3 算法流程图
图1:PSO算法流程图
4 函数优化过程
4.1 PSO算法解决一元函数优化问题
4.1.1问题描述
针对一元函数,求其最大值(其中,x取值为[-1,2])。
4.1.2用C语言编码求解
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>
#define MAX(a,b) ((a)>(b)?(a):(b))
#define PI 3.14159265
#define N 20 //种群规模
#define G 100 //迭代次数
#define c1 2
#define c2 2 //加速度因子
#define w1 0.9
#define w2 0.4 //惯性权重
#define Vmax 0.01 //最大速度
double x[N],y[N],v[N],pbest[N],gbest;
double randd()
{
return (double)rand()/RAND_MAX;
}
int randi(int k)
{
return (int)(randd()*k+0.5);
}
void cal_fitness() //计算适应度值
{
int i;
for(i=0;i<N;i++) y[i]=x[i]*sin(10*PI*x[i])+2;
}
void init()
{
int i;
for(i=0;i<N;i++)
{
x[i]=-1+3*randd(); //随机初始化个体位置
v[i]=randd()*Vmax; //随机初始化个体速度
}
cal_fitness();
gbest=y[0];
for(i=0;i<N;i++)
{
pbest[i]=y[i]; //个体极值
gbest=MAX(gbest,y[i]); //群体极值
}
}
void pso()
{
int i,g;
double w;
for(g=0;g<G;g++)
{
w=w2+(w1-w2)*(G-g)/G;
for(i=0;i<N;i++) //粒子速度和位置更新
{
v[i]=w*v[i]+c1*randd()*(pbest[i]-x[i])+c2*randd()*(gbest-x[i]);
if(v[i]>Vmax) v[i]=Vmax; //限制速度的值使其不超过规定的上限
x[i]+=v[i];
if(x[i]<-1) x[i]=-1;
if(x[i]>2) x[i]=2;
}
cal_fitness();
for(i=0;i<N;i++)
{
pbest[i]=MAX(pbest[i],y[i]);
gbest=MAX(gbest,pbest[i]);
}
}
printf(“%.6lf\n”,gbest);
}
int main()
{
srand((unsigned)time(NULL));
init();
pso();
return 0;
}
4.2 PSO算法解决二元函数优化问题
4.2.1问题描述
针对二元非线性函数:
求其极大值以及极大值点。(函数选自高等数学(下))
4.2.2用MATLAB编码求解
(1)函数文件代码
function y = fun(x)
y=sin( sqrt(x(1).^2+x(2).^2) )./sqrt(x(1).^2+x(2).^2)+exp((cos(2*pi*x(1))+cos(2*pi*x(2)))/2)-2.71289;
(2)主函数文件代码
clc
clear
%% 参数初始化
c1 = 2;
c2 = 2;
maxgen=300; % 进化次数
sizepop=20; %种群规模
Vmax=0.5;
Vmin=-0.5;
popmax=2;
popmin=-2;
%% 产生初始粒子和速度
for i=1:sizepop
%随机产生一个种群
pop(i,:)=2*rands(1,2); %初始种群
V(i,:)=0.5*rands(1,2); %初始化速度
%计算适应度
fitness(i)=fun(pop(i,:)); %染色体的适应度
end
%% 个体极值和群体极值
[bestfitness bestindex]=max(fitness);
zbest=pop(bestindex,:); %全局最佳
gbest=pop; %个体最佳
fitnessgbest=fitness; %个体最佳适应度值
fitnesszbest=bestfitness; %全局最佳适应度值
%% 迭代寻优
for i=1:maxgen
for j=1:sizepop
%速度更新
V(j,:) = V(j,:) + c1*rand*(gbest(j,:) – pop(j,:)) + c2*rand*(zbest – pop(j,:));
V(j,find(V(j,:)>Vmax))=Vmax;
V(j,find(V(j,:)<Vmin))=Vmin;
%种群更新
pop(j,:)=pop(j,:)+V(j,:);
pop(j,find(pop(j,:)>popmax))=popmax;
pop(j,find(pop(j,:)<popmin))=popmin;
%适应度值
fitness(j)=fun(pop(j,:));
end
for j=1:sizepop
%个体最优更新
if fitness(j) > fitnessgbest(j)
gbest(j,:) = pop(j,:);
fitnessgbest(j) = fitness(j);
end
%群体最优更新
if fitness(j) > fitnesszbest
zbest = pop(j,:);
fitnesszbest = fitness(j);
end
end
yy(i)=fitnesszbest;
end
%% 结果分析
plot(yy)
title(‘最优个体适应度‘,’fontsize’,12);
xlabel(‘进化代数‘,’fontsize’,12);ylabel(‘适应度‘,’fontsize’,12);
5 实验结果及测试
5.1一元函数优化结果及测试
5.1.1一元函数优化结果
图2:一元函数优化运行结果
5.1.2函数图解
图3:一元函数图像
5.1.3测试及对比
由图像可以看出,该函数的最大值在3.8左右,使用MATLAB取点,调用ginput函数将最高峰的点取出来,得到该点的坐标为(1.8514,3.8421),而程序运行结果基本稳定在3.8502左右,计算误差值为:0.21%。实验结果令人满意。
5.2 二元函数优化结果及测试
5.2.1二元函数优化结果
图4:适应度优化
图5:二元函数优化结果
5.2.2 函数图解
由于该二元函数不容易确定极值点范围,故可通过图像先大概了解其极值点分布,从而更好地设置相应参数。
图6:函数图形
5.2.3测试及对比
由函数图像可以看出,该函数有很多局部极大值点,二极限位置为(0,0),在(0,0)附近取得极大值。通过对函数的理论分析也可以知道,当趋近于零时,函数的最大值在1左右,经检测,程序运行结果令人满意。
6 优点、不足及改进
粒子群算法是一种新的群智能优化算法,自从提出以来,以其独特的魅力受到了研究者们的青睐。目前已经取得较大的发展。但是由于提出时间不长,算法还缺乏深刻的理论分析和坚实的数学基础,还有很多问题有待进一步解决。
6.1 PSO算法优点
(1)PSO算法没有交叉和变异运算,依靠粒子速度完成搜索,并且在迭代进化中只有最优的粒子把信息传递给其他粒子,搜索速度快;
(2)PSO算法具有记忆性,粒子群体的历史最好位置可以记忆并传递给其他粒子;
(3)需要调整的参数较少,结构简单,易于工程实现;
(4)采用实数编码,直接由问题的解决定,问题解的变量数直接作为粒子的维数。
6.2 PSO算法的缺点
(1)容易陷入局部最优,导致收敛精度低和不易收敛;
(2)不能有效解决某些优化问题;
(3)不能有效求解一些非直角坐标系描述问题,如有关能量场或场内粒子运动规律的求解问题。
6.3 PSO算法的改进
6.3.1增加惯性因子改进粒子群算法
在求解实际应用的各种问题中,对算法的局部搜索能力和全局搜索能力的比例要求不尽相同,甚至对同一个问题,在其进化的不同阶段,对他们的要求也有可能不一样。较大时具有较强的全局搜索能力,较小时具有较强的局部收敛能力,因此有点类似于模拟退火中的温度,随着迭代次数的增加,的值应该不断地减小,从而使得在算法开始初期,要求有较强的全局搜索能力,在后期,要求有较强的局部搜索能力,以提高算法的整体性能。
6.3.2基于收敛性分析改进粒子群算法
由于标准PSO算法有可能出现太早收敛的情况,在标准PSO算法中,粒子仅仅追随个体最优和全局最优两个粒子运动,这种策略在一定程度上影响了算法的全局收敛性能。为了改善算法收敛能力,在算法的开始阶段,每个粒子的领域为其本身,随着进化代数的增加,领域范围也在不断地增大,直至整个种群。该算法在一定程度上克服了PSO算法在优化搜索后期随迭代次数增加,结果却没有明显改进的缺点。
6.3.3导入其他演化算法思想改进PSO算法
标准PSO算法中粒子在解空间追随最优粒子进行搜索,但是PSO算法中没有明显的选择、交叉以及变异等演化算法。适当地引入演化算法,在一定程度上可以提高算法的性能。导入其他演化算法思想来改进PSO算法是目前一个研究热点。在进化过程中,保存种群中所有粒子适应度的排序,然后用适应度好的前一半粒子替代适应度不好的后一半粒子。