本文在作者原文的基础上增加了惯性动量来更新粒子速度与位置,且w采用线性递减方式变化。
clear;
clc;
p = 0 : 0.01 : 2;%样本输入
t = sin(pi * p);%样本输出
n = 3; %隐含层神经元个数
net = newff(p,t, n, {'tansig','purelin'}, 'trainlm');
swarmCount = 20; %粒子数
swarmLength = 10; %粒子长度
vMax = 20; %粒子运动最大速度
pMax = 2; %粒子运动最大位置
swarm = rand(swarmCount, swarmLength); %初始粒子群,即粒子的位置
v = rand(swarmCount, swarmLength); %粒子的速度
swarmfitness = zeros(swarmCount, 1, 'double'); %粒子的适应度值
pBest = rand(swarmCount, swarmLength); %个体最优值
pBestfitness = zeros(swarmCount, 1, 'double'); %个体最优适应度值
pBestfitness(:, :) = 100;
gBest = rand(1, swarmLength); %全局最优值
gBestfitness = 100; %全局最优适应度值
c1 = 2;
c2 = 2;
wmax=0.95;
wmin=0.25;
maxEpoch = 2000; %最大训练次数
errGoal = 0.01; %期望误差最小值
epoch = 1;
while (epoch < maxEpoch && gBestfitness > errGoal)
for i = 1 : swarmCount
%计算粒子的适应度值
net.iw{1, 1} = swarm(i, 1 : 3)';
net.b{1} = swarm(i, 4 : 6)';
net.lw{2,1} = swarm(i, 7 : 9);
net.b{2} = swarm(i, 10 : 10);
tout = sim(net, p);%预测的输出
sse = sum((tout - t) .^ 2) / length(t);
swarmfitness(i, 1) = sse;
%更新个体最优值
if (pBestfitness(i, 1) > sse)
pBestfitness(i, 1) = sse;
pBest(i, :) = swarm(i, :);
%更新全局最优值
if(gBestfitness > sse)
gBestfitness = sse;
gBest(1, :) = swarm(i, :);
end
end
end
%更新粒子的速度和位置
W(epoch)=wmax-((wmax-wmin)/maxEpoch)*epoch;
for i = 1 : swarmCount
v(i, :) = W(1)*v(i, :) + c1 * rand(1, 1) * (pBest(i, :) - swarm(i, :)) + c2 * rand(1, 1) * (gBest(1, :) - swarm(i, :));%速度更新
tmp = v(i, :) > vMax;
v(i, tmp) = vMax;%超过边界的粒子转化为边界
swarm(i, :) = swarm(i, :) + v(i, :);%粒子位置更新
tmp = find(swarm(i, :) > pMax);%超越边界的粒子转化为边界
swarm(i, tmp) = pMax;
end
epoch = epoch + 1;
end
net.iw{1, 1} = gBest(1, 1 : 3)';
net.b{1} = gBest(1, 4 : 6)';
net.lw{2, 1} = gBest(1, 7 : 9);
net.b{2} = gBest(1, 10 : 10);
tout = sim(net, p);
figure(1)
plot(p, t, 'k-');
hold on;
plot(p, tout, 'b-');