A Modified Particle Swarm Optimizer

425 阅读3分钟

1. 改进的PSO算法、

如果要了解这篇期刊,得首先了解Particle swarm optimization(粒子群优化算法),参见博客:Particle Swarm Optimization。而本篇论文就是基于上述论文改进而来的。

Shi Y, Eberhart R. A modified particle swarm optimizer[C]//1998 IEEE international conference on evolutionary computation proceedings. IEEE world congress on computational intelligence (Cat. No. 98TH8360). IEEE, 1998: 69-73. 标准的PSO算法有如下更新形式:

vid=vid+c1rand()(pidxid)+c2Rand()(pgdxid)xid=xid+vid\begin{gathered} \mathrm{v}_{\mathrm{id}}=\mathrm{v}_{\mathrm{id}}+\mathrm{c}_{1} * \operatorname{rand}()^{*}\left(\mathrm{p}_{\mathrm{id}}-\mathrm{x}_{\mathrm{id}}\right)+ \mathrm{c}_{2} * \operatorname{Rand}()^{*}\left(\mathrm{p}_{\mathrm{gd}}-\mathrm{x}_{\mathrm{id}}\right) \\ \mathrm{x}_{\mathrm{id}}=\mathrm{x}_{\mathrm{id}}+\mathrm{v}_{\mathrm{id}} \end{gathered}

每个粒子都被视为二维空间中的一个点。第i个粒子表示为xi=(xi1,xi2,...,xiD)x_{i}=(x_{i1},x_{i2},...,x_{iD})。任何粒子之前的最佳位置(给出最佳适应度值的位置)都被记录下来,并表示为Pi=(Pi1,Pi2,...,PiD)P_{i}=(P_{i1},P_{i2},...,P_{iD})。总体中所有粒子中最佳粒子的索引用符号g表示。粒子i的位置变化速率(速度)表示为Vi=(Vi1,Vi2,...,ViD)V_{i}=(V_{i1},V_{i2},...,V_{iD})

第一个公式的第二部分 “认知”部分,它代表了粒子本身的私人思维。第三部分是 “社会”部分,它代表了粒子之间的协作。第一个公式根据粒子之前的速度当前位置其自身最佳体验(位置)该群组的最佳体验的距离来计算粒子的新速度。然后粒子根据第二个公式飞向一个新的位置。每个粒子的性能是根据预定义的适应度函数来测量的,这与要解决的问题有关。

2. 改进的PSO算法的具体表现形式

如果没有第一个公式的第一部分,所有的粒子都会趋向于向相同的位置移动,也就是搜索区域代代收缩,容易导致出现局部最优。考虑到此,将惯性权重W引入到第一个公式中。这个W起着平衡全局搜索和局部搜索的作用,它可以是一个正的常数,甚至是一个正的时间线性或非线性时间函数。

Vid=W Vid+c1rand()(pidxid)+c2Rand()(pgdxid)Xid=Xid+Vid\begin{array}{c} \mathrm{V}_{\mathrm{id}}=\mathrm{W}^{*} \mathrm{~V}_{\mathrm{id}}+\mathrm{c}_{1} * \operatorname{rand}() *\left(\mathrm{p}_{\mathrm{id}}-\mathrm{x}_{\mathrm{id}}\right)+ \mathrm{c}_{2} * \operatorname{Rand}() *\left(\mathrm{p}_{\mathrm{gd}}-\mathrm{x}_{\mathrm{id}}\right) \\ \mathbf{X}_{\mathrm{id}}=\mathbf{X}_{\mathrm{id}}+\mathrm{V}_{\mathrm{id}} \end{array}

当W越大,该搜索越趋近于全局搜索。当W越小,该搜索越趋近于局部搜索。

3.改进的PSO算法的实现和实验

首先,我们在W不同的情况下,进行函数最小值的搜索。

% Rastrigin
function [Out] = F1(X)
T1 = X.^2;
T2 = -10*cos(2*pi*X)+10;
Out = sum(T1+T2,2);
%D=[-5.12,5.12]
clc;clear;clearvars;
% 随机生成5个数据
num_initial = 5;
num_vari = 5;
% 搜索区间
upper_bound = 5.12;
lower_bound = -5.12;
iter = 10000;
w = 0.1;
% 随机生成5个数据,并获得其评估值
sample_x = lhsdesign(num_initial, num_vari).*(upper_bound - lower_bound) + lower_bound.*ones(num_initial, num_vari);
sample_y = F1(sample_x);
Fmin = zeros(30, 1);
W = zeros(30, 1);
k = 1;
while w < 3
    % 初始化一些参数
    pbestx = sample_x;
    pbesty = sample_y;
    % 当前位置信息presentx
    presentx = lhsdesign(num_initial, num_vari).*(upper_bound - lower_bound) + lower_bound.*ones(num_initial, num_vari);
    vx = sample_x;
    [fmin, gbest] = min(pbesty);
    for i = 1 : iter
        r = rand(num_initial, num_vari);
        % pso更新下一步的位置,这里可以设置一下超过搜索范围的就设置为边界
        vx = w.*vx + 2 * r .* (pbestx - presentx) + 2 * r .* (pbestx(gbest, :) - presentx);
        vx(vx > upper_bound) = upper_bound;
        vx(vx < lower_bound) = lower_bound;
        presentx = presentx + vx;
        presentx(presentx > upper_bound) = upper_bound;
        presentx(presentx < lower_bound) = lower_bound;
        presenty = F1(presentx);
        % 更新每个单独个体最佳位置
        pbestx(presenty < pbesty, :) = presentx(presenty < pbesty, :);
        pbesty = F1(pbestx);
        % 更新所有个体最佳位置
        [fmin, gbest] = min(pbesty);
        % fprintf("iter %d fmin: %.4f\n", i, fmin);
    end
    fprintf("w %f fmin: %.4f\n", w, fmin);
    Fmin(k, 1) = fmin;
    k = k +1;
    w = w + 0.1;
end
plot(Fmin);

输出结果:

w 0.100000 fmin: 5.3629
w 0.200000 fmin: 17.7088
w 0.300000 fmin: 3.2766
w 0.400000 fmin: 8.4845
w 0.500000 fmin: 0.0707
w 0.600000 fmin: 0.0000
w 0.700000 fmin: 1.8117
w 0.800000 fmin: 4.8366
w 0.900000 fmin: 4.1828
w 1.000000 fmin: 2.2808
w 1.100000 fmin: 0.0000
w 1.200000 fmin: 0.0000
w 1.300000 fmin: 0.0000
w 1.400000 fmin: 0.0000
w 1.500000 fmin: 0.0000
w 1.600000 fmin: 0.0000
w 1.700000 fmin: 0.0000
w 1.800000 fmin: 0.0000
w 1.900000 fmin: 0.0000
w 2.000000 fmin: 0.0000
w 2.100000 fmin: 28.9247
w 2.200000 fmin: 28.9247
w 2.300000 fmin: 28.9247
w 2.400000 fmin: 28.9247
w 2.500000 fmin: 28.9247
w 2.600000 fmin: 28.9247
w 2.700000 fmin: 30.3679
w 2.800000 fmin: 57.8494
w 2.900000 fmin: 57.8494

image.png
从上图我们可以看出W在1.0~2.0期间时候,能够找到效果更好的函数值。W越大或者W越趋近于0,反而并不利于找到函数最佳的函数值。所以不能完全局部搜索,也不能完全全部搜索,要介于二者之间。

对于任何优化搜索算法,算法最好先具有更多的开发能力来寻找好种子的位置再具有在种子的周围局部搜索的探索能力。因此,我们定义了惯性权重是一个时间的递减函数,而不是一个固定的常数。它从一个很大的值2开始,当迭代次数达到1000时,它线性下降到0。 

clc;clear;clearvars;
% 随机生成5个数据
num_initial = 5;
num_vari = 5;
% 搜索区间
upper_bound = 5.12;
lower_bound = -5.12;
iter = 1000;
w = 2;
% 随机生成5个数据,并获得其评估值
sample_x = lhsdesign(num_initial, num_vari).*(upper_bound - lower_bound) + lower_bound.*ones(num_initial, num_vari);
sample_y = F1(sample_x);
Fmin = zeros(iter, 1);
k = 1;
 
% 初始化一些参数
pbestx = sample_x;
pbesty = sample_y;
% 当前位置信息presentx
presentx = lhsdesign(num_initial, num_vari).*(upper_bound - lower_bound) + lower_bound.*ones(num_initial, num_vari);
vx = sample_x;
[fmin, gbest] = min(pbesty);
for i = 1 : iter
    r = rand(num_initial, num_vari);
    % pso更新下一步的位置,这里可以设置一下超过搜索范围的就设置为边界
    vx = w.*vx + 2 * r .* (pbestx - presentx) + 2 * r .* (pbestx(gbest, :) - presentx);
    vx(vx > upper_bound) = upper_bound;
    vx(vx < lower_bound) = lower_bound;
    presentx = presentx + vx;
    presentx(presentx > upper_bound) = upper_bound;
    presentx(presentx < lower_bound) = lower_bound;
    presenty = F1(presentx);
    % 更新每个单独个体最佳位置
    pbestx(presenty < pbesty, :) = presentx(presenty < pbesty, :);
    pbesty = F1(pbestx);
    % 更新所有个体最佳位置
    [fmin, gbest] = min(pbesty);
    fprintf("iter %d fmin: %.4f\n", i, fmin);
    Fmin(k, 1) = fmin;
    k = k +1;
    w = w - 0.002;
end
plot(Fmin);

image.png
iter 1000 fmin: 2.5402

image.png
iter 1000 fmin: 28.9247

通过运行多次,选取典型的两次两次发现,这个并不稳定,很依赖前期全局搜索的优劣,后期的局部搜索是建立在前期良好搜索基础之上。

普通搜索:

clc;clear;clearvars;
% 随机生成5个数据
num_initial = 5;
num_vari = 5;
% 搜索区间
upper_bound = 5.12;
lower_bound = -5.12;
iter = 1000;
w = 1;
% 随机生成5个数据,并获得其评估值
sample_x = lhsdesign(num_initial, num_vari).*(upper_bound - lower_bound) + lower_bound.*ones(num_initial, num_vari);
sample_y = F1(sample_x);
Fmin = zeros(iter, 1);
k = 1;
 
% 初始化一些参数
pbestx = sample_x;
pbesty = sample_y;
% 当前位置信息presentx
presentx = lhsdesign(num_initial, num_vari).*(upper_bound - lower_bound) + lower_bound.*ones(num_initial, num_vari);
vx = sample_x;
[fmin, gbest] = min(pbesty);
for i = 1 : iter
    r = rand(num_initial, num_vari);
    % pso更新下一步的位置,这里可以设置一下超过搜索范围的就设置为边界
    vx = w.*vx + 2 * r .* (pbestx - presentx) + 2 * r .* (pbestx(gbest, :) - presentx);
    vx(vx > upper_bound) = upper_bound;
    vx(vx < lower_bound) = lower_bound;
    presentx = presentx + vx;
    presentx(presentx > upper_bound) = upper_bound;
    presentx(presentx < lower_bound) = lower_bound;
    presenty = F1(presentx);
    % 更新每个单独个体最佳位置
    pbestx(presenty < pbesty, :) = presentx(presenty < pbesty, :);
    pbesty = F1(pbestx);
    % 更新所有个体最佳位置
    [fmin, gbest] = min(pbesty);
    fprintf("iter %d fmin: %.4f\n", i, fmin);
    Fmin(k, 1) = fmin;
    k = k +1;
end
plot(Fmin);

image.png
iter 1000 fmin: 7.7087

通过多次实验,发现普通搜索就比较稳定,值大部分大致在0~10之间跳动。因此目前来看固定值方式更加可取,但是对于不同测试函数,方法的优劣性也未必完全如此。