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算法有如下更新形式:
$\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个粒子表示为$x{i}=(x{i1},x{i2},...,x{iD})$。任何粒子之前的最佳位置(给出最佳适应度值的位置)都被记录下来,并表示为$P{i}=(P{i1},P{i2},...,P{iD})$。总体中所有粒子中最佳粒子的索引用符号g表示。粒子i的位置变化速率(速度)表示为$V{i}=(V{i1},V{i2},...,V{iD})$。\
第一个公式的第二部分 “认知”部分,它代表了粒子本身的私人思维。第三部分是 “社会”部分,它代表了粒子之间的协作。第一个公式根据粒子之前的速度和当前位置与其自身最佳体验(位置) 和该群组的最佳体验的距离来计算粒子的新速度。然后粒子根据第二个公式飞向一个新的位置。每个粒子的性能是根据预定义的适应度函数来测量的,这与要解决的问题有关。
2. 改进的PSO算法的具体表现形式
如果没有第一个公式的第一部分,所有的粒子都会趋向于向相同的位置移动,也就是搜索区域代代收缩,容易导致出现局部最优。考虑到此,将惯性权重W引入到第一个公式中。这个W起着平衡全局搜索和局部搜索的作用,它可以是一个正的常数,甚至是一个正的时间线性或非线性时间函数。
$\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不同的情况下,进行函数最小值的搜索。
% Rastriginfunction [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;endplot(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
\ 从上图我们可以看出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;% 当前位置信息presentxpresentx = 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;endplot(Fmin);
\ iter 1000 fmin: 2.5402
\ 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;% 当前位置信息presentxpresentx = 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;endplot(Fmin);
\ iter 1000 fmin: 7.7087
通过多次实验,发现普通搜索就比较稳定,值大部分大致在0~10之间跳动。因此目前来看固定值方式更加可取,但是对于不同测试函数,方法的优劣性也未必完全如此。
原文:https://juejin.cn/post/7099747818771841037