前言
- 当粒子已经找到最佳位置后,再增加迭代次数只会浪费计算时间,那么我们能否设计一个策略,能够自动退出迭代呢?
循环跳出策略
(1)初始化最大迭代次数、计数器以及最大计数值(例如分别取100, 0, 20)
(2)定义“函数变化量容忍度”,一般取非常小的正数;
(3)在迭代的过程中,每次计算出来最佳适应度后,都计算该适应度和上一次迭代时最佳适应度的变化量(取绝对值);
(4)判断这个变化量和“函数变化量容忍度”的相对大小,如果前者小,则计数器加1;否则计数器清0;
(5)不断重复这个过程,有以下两种可能:
① 此时还没有超过最大迭代次数,计数器的值超过了最大计数值,那么我们就跳出迭代循环,搜索结束。
② 此时已经达到了最大迭代次数,那么直接跳出循环,搜索结束。
代码实现
求解函数y = 7cos(5x) + 4*sin(x)在[-5,5]内的最大值
%% 改进:自动退出迭代循环
Count = 0; % 计数器初始化为0
max_Count = 30; % 最大计数值初始化为30
tolerance = 1e-2; % 函数变化量容忍度,取10^(-2)%% 绘制函数的图形
x = -5:0.01:5;
y = 7*cos(5*x) + 4*sin(x);
figure(1)
plot(x,y,'b-')
title('y = 7*cos(5*x) + 4*sin(x)')
hold on % 不关闭图形,继续在上面画图%% 粒子群算法中的预设参数(参数的设置不是固定的,可以适当修改)
n = 10; % 粒子数量
narvs = 1; % 变量个数
c1 = 2; % 每个粒子的个体学习因子
c2 = 2; % 每个粒子的社会学习因子
w = 0.9; % 惯性权重
K = 100; % 迭代的次数
vmax = 1.2; % 粒子的最大速度
x_lb = -3; % x的下界
x_ub = 3; % x的上界%% 初始化粒子的位置和速度
x = zeros(n,narvs);
x = x_lb + (x_ub-x_lb).*rand(n,narvs) % 随机初始化粒子所在的位置
v = -vmax + 2*vmax .* rand(n,narvs); % 随机初始化粒子的速度%% 计算适应度
fit = zeros(n,1); % 初始化这n个粒子的适应度全为0
for i = 1:n % 循环整个粒子群,计算每一个粒子的适应度fit(i) = Obj_fun1(x(i,:)); % 调用Obj_fun1函数来计算适应度
end
pbest = x; % 初始化这n个粒子迄今为止找到的最佳位置(是一个n*narvs的向量)
ind = find(fit == max(fit), 1); % 找到适应度最大的那个粒子的下标
gbest = x(ind,:); % 定义所有粒子迄今为止找到的最佳位置(是一个1*narvs的向量)%% 在图上标上这n个粒子的位置用于演示
h = scatter(x,fit,80,'*r'); % scatter是绘制二维散点图的函数%% 迭代K次来更新速度与位置
% fitnessbest = ones(K,1); % 初始化每次迭代得到的最佳的适应度
for d = 1:K % 开始迭代,一共迭代K次tem = gbest; % 将上一步找到的最佳位置保存为临时变量for i = 1:n % 依次更新第i个粒子的速度与位置v(i,:) = w*v(i,:) + c1*rand(1)*(pbest(i,:) - x(i,:)) + c2*rand(1)*(gbest - x(i,:)); % 更新第i个粒子的速度% 如果粒子的速度超过了最大速度限制,就对其进行调整for j = 1: narvsif v(i,j) < -vmax(j)v(i,j) = -vmax(j);elseif v(i,j) > vmax(j)v(i,j) = vmax(j);endendx(i,:) = x(i,:) + v(i,:); % 更新第i个粒子的位置% 如果粒子的位置超出了定义域,就对其进行调整for j = 1: narvsif x(i,j) < x_lb(j)x(i,j) = x_lb(j);elseif x(i,j) > x_ub(j)x(i,j) = x_ub(j);endendfit(i) = Obj_fun1(x(i,:)); % 重新计算第i个粒子的适应度if fit(i) > Obj_fun1(pbest(i,:)) % 如果第i个粒子的适应度大于这个粒子迄今为止找到的最佳位置对应的适应度pbest(i,:) = x(i,:); % 更新第i个粒子迄今为止找到的最佳位置endif fit(i) > Obj_fun1(gbest) % 如果第i个粒子的适应度大于所有的粒子迄今为止找到的最佳位置对应的适应度gbest = pbest(i,:); % 更新所有粒子迄今为止找到的最佳位置endendfitnessbest(d) = Obj_fun1(gbest); % 更新第d次迭代得到的最佳的适应度delta_fit = abs(Obj_fun1(gbest) - Obj_fun1(tem)); % 计算相邻两次迭代适应度的变化量if delta_fit < tolerance % 判断这个变化量和“函数变化量容忍度”的相对大小,如果前者小,则计数器加1Count = Count + 1;elseCount = 0; % 否则计数器清0end if Count > max_Count % 如果计数器的值达到了最大计数值break; % 跳出循环endpause(0.1) % 暂停0.1sh.XData = x; % 更新散点图句柄的x轴的数据h.YData = fit; % 更新散点图句柄的y轴的数据
endfigure(2)
plot(fitnessbest) % 绘制出每次迭代最佳适应度的变化图
xlabel('迭代次数');
disp('最佳的位置是:'); disp(gbest)
disp('此时最优值是:'); disp(Obj_fun1(gbest))
function y = Obj_fun1(x)y = 7*cos(5*x) + 4*sin(x);
end
迭代一百次的情况下优化与未优化的对比如下
自动退出迭代循环
基本粒子群算法
对比可知,未经优化的粒子群算法会浪费大量时间在无明显变化的搜索中。