前言
本文主要记录学习粒子群算法过程,以y = x+10*sin(5*x)+7*cos(4*x)
函数为例,利用粒子群来寻找最小值。
以下是本篇文章正文内容
一、示例函数
1.显示图像代码
clc;clear;
x = 0:0.01:10;
y = x+10*sin(5*x)+7*cos(4*x);
plot(x,y)
2.函数图像
二、matlab程序
1.粒子群原理(自述)
下面是本人自己画的一张粒子群示意图
,
1>、用图解释:寻找食物(寻优),先确定一个目标点(图中食物位置),然后在规定区域内(椭圆内),将n个粒子随机分布在规定区域任意位置,随后计算每个粒子到目标点(图中食物位置)的距离,这个距离称为“目标函数”,这个距离当然是越小越好。那么如何寻找食物呢,就是更新每个粒子的位置,对每一次迭代的粒子计算适应度,并且在粒子中比较,得到整个粒子群的最优适应度,直到迭代结束。
2>、将图解释到具体案例:比如变量x的范围为(0,10),那么在此区域内随机取n个横坐标点,随后计算n个坐标对应的纵坐标(目标函数值),比较得到最小适应度值(寻找最小值时);通过迭代更新每个粒子的速度和位置信息,每迭代一次则记录一次最优适应度值,直到迭代结束。
2.粒子群参数设置
粒子群算法主要参数:
N种群数, D维度(变量数), T迭代次数, C1学习因子1, C2学习因子2, W权衡系数, X粒子坐标, V粒子速度, p个体最优位置, pbest个体最优函数值, g全局最优位置, gbst全局最优函数值。
% % % % % % % % % 粒子群参数初始化 % % % % % % % % % %
n = 200; %粒子数
d = 1; %维度数=变量数
wmax = 0.9; %权衡系数极大值
wmin = 0.4; %权衡系数极小值
Tmax = 30; %迭代最大次数
xmin = 0; %x变量下限
xmax = 10; %x变量上限
vmax = 1; %速度最大值
vmin = -1; %速度最小值
c1 = 1.2; %学习因子1
c2 = 1.2; %学习因子2
r1 = rand; %随机小数1
r2 = rand; %随机小数2
3.目标函数代码
%% 目标函数:y = x+10*sin(5*x)+7*cos(4*x)
function value = fit(x)
value = x+10*sin(5*x)+7*cos(4*x);
4.结果图
此处左图一红圈为每次迭代最优位置点显示,动态显示,右侧为适应度迭代图。
5.每次迭代结果显示
保留三位小数:
disp('=================================================================================')
fprintf('第%d迭代最优适应度值:%.3f',iter,gbest);
6.全部代码(自写)
以下为本人自行编写代码,并且寻优过程有动态图显示操作。
%% 粒子群算法寻找y = x+10*sin(5*x)+7*cos(4*x)函数最小值
% @Auther:周述正
% useness:学习
clear;
clc;
close all;
% % % % % % % % % 粒子群参数初始化 % % % % % % % % % %
n = 200; %粒子数
d = 1; %维度数=变量数
wmax = 0.9; %权衡系数极大值
wmin = 0.4; %权衡系数极小值
Tmax = 30; %迭代最大次数
xmin = 0; %x变量下限
xmax = 10; %x变量上限
vmax = 1; %速度最大值
vmin = -1; %速度最小值
c1 = 1.2; %学习因子1
c2 = 1.2; %学习因子2
r1 = rand; %随机小数1
r2 = rand; %随机小数2
% % % % % % % % 初始化位置分布与速度 % % % % % % % % %
x(:,1) = xmin+(xmax-xmin)*rand(n ,d);
v = vmin+(vmax-vmin)*rand(n,d);
%% 初始粒子群个体适应度函数
p = x; %所有粒子位置
pbest = ones(n,1); %每一代n个
for k=1:n
pbest(k) = fit(x(k,d));
end
%% 初始粒子群全局最优适应度函数
g = ones(1,d); %全局最优位置,变量值---x
gbest = inf; %初始无穷大适应度
old_gb = ones(Tmax,1); %记录迭代Tmax次的每次迭代全局最优值
for j=1:n
if(pbest(j)<gbest)
g = p(j,:); %从全部粒子中提取最优适应度对应的粒子位置
gbest = pbest(j); %提取最优适应度值
end
end
%% 画图
subplot(1,2,1);
a = 0:0.01:10;
b = a+10*sin(5*a)+7*cos(4*a);
plot(a,b)
xlabel('x');
ylabel('y');
title('y = x+10*sin(5*x)+7*cos(4*x)');
pause(0.2);
hold on;
%% 迭代开始 使用for循环,减少i++代码
for iter=1:Tmax
w = wmax-(wmax-wmin)*iter/Tmax;
for j=1:n
%对更新后的粒子位置计算适应度函数
if(fit(x(j,:))<pbest(j))
p(j,:) = x(j,:);
pbest(j) = fit(x(j,d));
end
%获取最优适应度函数以及位置
if(pbest(j)<gbest)
gbest = pbest(j);
g = p(j,:);
end
%位置,速度更新
v(j,:) = w*v(j,:)+c1*r1*(p(j,:)-x(j,:))+c2*r2*(g-x(j,:));
x(j,:) = x(j,:)+v(j,:);
%处理边界条件
if(x(j,1)>xmax || x(j,1)<xmin)
x(j,1) = xmin+(xmax-xmin)*rand;
end
end
old_gb(iter) = gbest;
disp('======================================================================')
fprintf('第%d迭代最优适应度值:%.3f',iter,gbest);
%% 动态图
yo = g(1)+10*sin(5*g(1))+7*cos(4*g(1));
plot(g(1),yo,'ro');
hold on;
pause(1);
end
迭代适应度值显示
subplot(1,2,2) ;
plot(1:Tmax,old_gb,'r')
title('粒子迭代')
xlabel('迭代次数')
ylabel('适应度函数值')
总结
粒子群算法其实是一种比较巧妙、灵巧的算法,主要是概率性搜索,在寻找函数极值上要比很多方法更快速、好用。期望今后能够在某个项目上能够用上粒子群算法,这样更加能够加深对数模的理解,毕竟理论应用到实际才算是生产力。