粒子群算法

原始粒子群算法

粒子群算法(Particle Swarm Optimization, PSO)的基本思想是随机初始化一群没有体积没有质量的粒子,将每个粒子视为优化问题的一个可行解,粒子的好坏由一个事先设定的适应度函数来确定。每个粒子将在可行解空间中运行,并由一个速度变量决定其方向和距离。通常粒子将追随当前的最优粒子,并经逐代搜索后得到最优解。在每一代中,粒子将跟踪两个极值:一个是粒子本身迄今为止找到的最优解,另一个则是整个群体迄今为止找到的最优解。

假设一个由 \(M\) 个粒子组成的群体在 \(D\) 维的搜索空间以一定的速度飞行。粒子 \(i\)\(t\) 时刻的状态属性设置如下:

  • 位置\(x_i^t = {\left( {x_{i1}^t,x_{i2}^t, \cdots ,x_{id}^t} \right)^T}\),其中 \(x_{id}^t \in \left[ {{L_d},{U_d}} \right]\)\(L_d\)\(U_d\) 分别为搜索空间的下限和上限;
  • 速度\(v_i^t = {\left( {v_{i1}^t,v_{i2}^t, \cdots ,v_{id}^t} \right)^T}\),其中 \(v_{id}^t \in \left[ {{v_{min,d}},{v_{max,d}}} \right]\)\(v_{min,d}\)\(v_{max,d}\) 分别为最小和最大速度;
  • 个体最优位置\(p_i^t = {\left( {p_{i1}^t,p_{i2}^t, \cdots ,p_{iD}^t} \right)^T}\) ;
  • 全局最优位置\(p_g^t = {\left( {p_{g1}^t,p_{g2}^t, \cdots ,p_{gD}^t} \right)^T}\) ;

其中,\(1 \le d \le D\)\(1 \le i \le M\)

则粒子在 \(t+1\) 时刻的位置通过下式更新获得:

\[v_{id}^{t + 1} = v_{id}^t + {c_1}{r_1}\left( {p_{id}^t - x_{id}^t} \right) + {c_2}{r_2}\left( {p_{gd}^t - x_{gd}^t} \right) \tag{1} \]

\[x_{id}^{t + 1} = x_{id}^t + v_{id}^{t + 1} \tag{2} \]

式中,\(r_1\)\(r_2\) 为均匀分布在 \((0,1)\) 区间上的随机数;\(c_1\)\(c_2\) 称为学习因子,通常取 \(c_1=c_2=2\)

(1)主要由三部分线组成:

  • 第一部分为粒子先前速度的继承,表示粒子对当前自身运动状态的信任,依据自身的速度进行惯性运动;
  • 第二部分为 “认知” 部分,表示粒子本身的思考,即根据综合考虑自身以往的经历从而实现对下一步行为决策,这种行为决策便是 “认知” ;
  • 第三部分为 “社会” 部分,表示粒子间的信息共享与相互合作。在搜索过程中粒子一方面记住它们自己的经验,同时考虑其他同伴的经验。当单个粒子觉察同伴经验较好的时候,它将进行适应性的调整,寻求一致认知过程。

基本 PSO 算法的实现步骤如下:

(1)初始化。设定 PSO 算法中涉及的各类参数:搜索空间的上限和下限 \(L_D\)\(U_d\) ,学习因子 \(c_1\)\(c_2\) ,算法最大迭代次数 \(T_{max}\) 或收敛精度 $\xi $,粒子速度范围 \(\left[ {{v_{min}},{v_{max}}} \right]\);随机初始化搜索点的位置 \(x_i\) 及其速度 \(v_i\) ,设置当前位置即为每个粒子的 \(p_i\) ,从个体极值找出全局极值,记录该最好值的粒子序号 \(g\) 机器位置 \(p_g\)

(2)评价每一个粒子。计算粒子的适应值,如果好于该粒子当前的个体极值,则将 \(p_i\) 设置为该粒子的位置,且更新个体极值。如果所有粒子的个体极值中最好的好于当前的全局值,则将 \(p_g\) 设置为该粒子的位置,更新全局值及其序号 \(g\)

(3)粒子的状态更新。用式(1)和式(2)对每一个粒子的速度和位置进行更新。如果 \(v_i \gt v_{max}\) 将其置为 \(v_{max}\) ,如果 \(v_i \lt v_{min}\) 将其置为 \(v_{min}\)

(4)检验是否符合结束条件。如果当前的迭代次数达到了预先设定的最大次数 \(T_{max}\) ,或最终结果小于预定收敛精度 \(\xi\) 要求,则停止迭代,输出最优解,否则转到步骤(2)。

标准粒子群算法

标准 PSO(Stand PSO,SPSO)模型与原始 PSO 模型的不同之处在于,通过一个惯性权重 \(\omega\) (Y.Shi et al,1998)来协调 PSO 算法的全局和局部寻优能力。具体做法是将基本 PSO 的速度方程修改为如式(3)所示,而位置方程保持不变:

\[v_{id}^{t + 1} = \omega v_{id}^t + {c_1}{r_1}\left( {p_{id}^t - x_{id}^t} \right) + {c_2}{r_2}\left( {p_{gd}^t - x_{gd}^t} \right) \tag{3} \]

这里 \(\omega\) 称为惯性权重,其大小决定了粒子对当前速度继承的多少,选择一个合适的 \(\omega\) 有助于 PSO 均衡它的探索能力与开发能力。

Y.Shi 等(2000)指出了惯性权重的作用,较大的惯性权重有利于展开全局寻优,而较小的惯性权重则有利于局部寻优。因此,如果在迭代计算过程中呈线性递减惯性权重,则 PSO 算法在开始时具有良好的全局搜索性能,能够迅速定位到接近全局最优点的区域,而在后期具有良好的局部搜索性能,能够精确地得到全局最优解。Y.Shi 等(2000)经过多组反复实验后,建议采用从 0.9 线性递减到 0.4 的策略,通常会取得比较好的算法性能。线性递减公式如下:

\[\omega = {\omega _{start}} - \frac{{{\omega _{start}} - {\omega _{end}}}}{{{t_{max}}}} \times t \tag{4} \]

式中,\(t_{max}\) 为最大迭代次数, \(t\) 为当前迭代次数,\(\omega _{start}\)\(\omega _{end}\) 分别为初始惯性权重和终止惯性权重。

标准测试函数

使用标准测试函数对基本 PSO 算法及其改进算法进行试验研究,这些标准测试函数都是经过精心设计和严格测试的,如果某一优化算法能较为满意地解决一个标准测试问题,则可以认为它在大量的问题上会取得良好的表现。

(1) Sphere 函数:

\[{f_1}\left( x \right) = \sum\limits_{i = 1}^n {x_i^2} \]

又称 DeJong 函数,这是一个简单的单峰函数,各类优化算法性能都能较为容易地发现全局最优解,它的简单性有助于研究优化算法在问题维度上的效果。该函数的全局最优点位于 \(x = \left\{ {0, \cdots ,0} \right\}\) ,全局最优点的函数值 \(f_1(x) = 0\)

(2)Schwefel 函数:

\[{f_2}\left( x \right) = \sum\limits_i^n {\left| {{x_i}} \right|} + \prod\limits_i^n {\left| {{x_i}} \right|} \]

该函数的全局最优点位于 \(x = \left\{ {0, \cdots ,0} \right\}\) ,全局最优点的函数值 \(f_2(x) = 0\) 。由于该函数是单峰函数,但是该函数由于 \(\prod\) 的存在使得各变量相互影响,比 Sphere 函数较难求解。

(3)Rosenbrock 函数:

\[{f_3}\left( x \right) = \sum\limits_i^n {\left( {100{{\left( {{x_{i + 1}} - x_i^2} \right)}^2} + {{\left( {{x_i} - 1} \right)}^2}} \right)} \]

这是一个单峰函数,但并不易于求解。该函数在远离最优点区域的适应值地形很简单,但靠近最优点的区域为香蕉状。变量之间具有很强的相关性,且梯度信息经常舞蹈算法的搜索方向。该函数在最优点 \(x = \left\{ {1, \cdots ,1} \right\}\),具有最小函数值 \(f_3(x) = 0\)

(4)Rastrigin 函数:

\[{f_4}\left( x \right) = \sum\limits_i^n {\left( {x_i^2 - 10\cos \left( {2\pi {x_i}} \right) + 10} \right)} \]

这是 Sphere 类函数的多峰版本,具有大量按正弦拐点排列的、很深的局部最优点。全局最优值为 \(f_4(x) = 0\) ,在点 \(x = \left\{ {0, \cdots ,0} \right\}\) 处获取。优化算法很容易在通往全局最优点的路径上陷入一个局部最优点。

(5)Griewank 函数:

\[{f_5}\left( x \right) = \frac{1}{{4000}}\sum\limits_{i = 1}^n {x_i^2} - \prod\limits_{i = 1}^n {\cos \left( {\frac{{{x_i}}}{{\sqrt i }}} \right) + 1} \]

该函数是一个复杂的多峰函数,粗在大量的局部最小点和高大障碍物,由于各变量之间显著相关,优化算法很容易陷入局部最优,该函数全局最优值为 \(f_5(x) = 0\) ,在点 \(x = \left\{ {0, \cdots ,0} \right\}\) 处获取。

(6)Ackley 函数:

\[{f_6}\left( x \right) = - 20\exp \left( { - 0.2 \times \sqrt {\frac{1}{{30}}\sum\limits_{i = 1}^D {x_i^2} } } \right) - \exp \left( {\frac{1}{{30}}\sum\limits_{i = 1}^D {\cos 2\pi {x_i}} } \right) + e \]

Ackley 函数,一个多峰的,存在许多局部最小的,自变量之间相互独立的函数,当\(x = \left\{ {0, \cdots ,0} \right\}\) 时,全局最优值为 \(f_6(x) = 0\)

(7)Quarticfunction (Nosie)函数:

\[{f_7}\left( x \right) = \sum\limits_{i = 1}^n {ix_i^4} + rand\left[ {0,1} \right) \]

这是一个含有高斯噪声的 4 次函数,当不考虑噪声影响时,它具有一个全局极小值 \(f_7 ( 0, \cdots ,0 ) = 0\)

(8)Shaffer 函数:

\[{f_8}\left( x \right) = \frac{{{{\sin }^2}\sqrt {x_1^2 + x_2^2} - 0.5}}{{{{\left[ {1 + 0.001(x_1^2 + x_2^2)} \right]}^2}}} - 0.5 \]

这是一个多峰函数,有无数个极小值点,一般算法都很难找到全局最优点,其中只有一个最小值点即当 \(x=\{0,0\}\) 时,全局最优值为 \(f_8(x) = -1\)

粒子群算法的基本实现

下面使用 Matlab 语言,以 Griewank 函数为测试对象,根据上述的标准 PSO 实现给出了应用 PSO 算法优化求解的具体过程。

% 相关参数的设置
UB = 600; % 函数的上界
lb = 300; % 函数的下界
PopSize = 40; % 种群大小
Dim = 10; % 微粒的维数
c1 = 2; % 学习因子
c2 = 2; % 学习因子
w_start = 0.9; % 惯性权重的初始值
w_end = 0.4; % 惯性权重的终止值
Vmax = 100; % 微粒的最大速度
MaxIter = 1500; % 最大迭代次数
Iter = 0; % 初始迭代次数

% Initialize Swarm and Velocity
X = rand(PopSize,Dim) * (UB-LB) + LB; % 为例位置随机初始化
V = rand(PopSize,Dim); % 微粒速度随机初始化

% 测试函数:Griewank 函数
ind = repmat(1:Dim, PopSize,1);
FX = sum(((X.^2)/4000)')' - prod(cos(X./ sqrt(ind))')' + 1;

% 设定当前位置为粒子的最好位置,并记录其最好值
PBest = X;
FPBest = FX;

% 找到初始微粒群体的最好微粒
[Fgbest,r] = min(FX);
CF = Fgbest; % 记录当前全局最优值
Best = X(r,:); % 用于保存最优粒子的位置
FBest = Fgbest;

% 循环
while(iter <= MaxIter)
    iter = iter + 1;
    % 更新惯性权重的值
    w_now = ((w_start - w_end) * (Maxiter - iter)/MaxIter) + w_end;
    A = repmat(X(r,:), PopSize,1);
    
    % 生成随机数
    R1 = rand(PopSize,Dim);
    R2 = rand(PopSize,Dim);
    
    % 速度更新 
    V = w_now * V + c1*R1.*(PBest-X) + c2*R2.*(A-X);
    
    % 对进化后速度大于最大速度的微粒进行处理
    changeRows = V > Vmax;
    V(find(changeRows)) = Vmax;
    
    % 对进化后速度小于最小速度的微粒进行处理
    changeRows = V < -Vmax;
    V(find(changeRows)) = -Vmax;   
    
    % 微粒位置进行更新
    X = X + 1.0*V;
    
    % 重新计算新位置的适应度值
    ind = repmat(1:Dim, PopSize, 1);
    FX = sum(((X.^2)/4000)')' - prod(cos(X./ sqrt(ind))')' + 1;
    
    % 更新每个微粒的最好位置
    P = FX < FPBest;
    FPBest(find(P)) = FX(find(P)); % 适应值更换
    PBest(find(P),:) = X(find(P),:); % 粒子位置更换
    
    [Fgbest, g] = min(FPBest); % 保存最好适应值
    
    if Fgbest < CF % 如果本次适应值好于上次则保存
        [fBest, b] = min(FPBest); % 最好适应值为 fBest
        Best = PBest(n,:); % 最好位置为 Best
    end
    CF = Fgbest; % 保留本次适应值,准备与下一次比较
end

参考来源

《粒子群优化算法》 李丽,牛奔著

posted @ 2022-01-22 20:16  GShang  阅读(865)  评论(0编辑  收藏  举报