---------------------------------------------------------------------------------------------------------------
目录
MATLAB2021a或者高级版本
PSO是粒子群优化算法(Particle Swarm Optimization)的英文缩写,是一种基于种群的随机优化技术,由Eberhart和Kennedy于1995年提出。粒子群算法模仿昆虫、兽群、鸟群和鱼群等的群集行为,这些群体按照一种合作的方式寻找食物,群体中的每个成员通过学习它自身的经验和其他成员的经验来不断改变其搜索模式。
在PSO算法中,用粒子来描述鸟类个体,每个粒子在搜索空间中搜索,飞行过程为搜索过程,飞行速度可以根据粒子历史最优位置和种群历史最优位置动态调整,粒子当前位置就是对应优化问题的一个候选解 ,称为个体极值,粒子群中的最优的个体极值称为全局最优解。不断地迭代,粒子更新速度和我位置,最终满足条件的全局最优解即为所求目标。PSO的基本步骤如下:
(1)初始化:迭代次数,目标函数的自变量个数,粒子的最大速度,位置信息,我们在速度区间和搜索空间上随机初始化速度和位置,粒子群规模,每个粒子随机初始化一个飞翔速度。此外还有粒子位置信息和速度信息的最小值最大值约束范围。
(2)适应度函数的定义。
适应度函数为粒子群算法的求解目标函数,比如我们要计算某个函数f(x)的最小值,那么可以定义 适应度函数为f(x),x为粒子的位置,即搜索最优的粒子位置x,使得适应度函数f(x)达到最小值。
(3)粒子更新。


首先,定义一个适应度函数程序:func_fitness.m
- function [minf,x,y] = func_fitness(x)
-
- minf = (x-5)^2;
-
-
- x=x;
这个函数表达式为:

然后定义粒子群优化算法程序:
参数初始化
-
- %%
- c1 = 2;
- c2 = 2;
- %x的范围
- min1 = -100;
- max1 = 100;
-
- %速度的范围
- vmin =-1;
- vmax = 1;
- %粒子数目
- Pop = 100;
- BsJ = 1;
- %迭代次数
- tmax = 100;
-
- x = zeros(1,Pop);
- va = zeros(size(x));
- x_best = zeros(1,Pop);
粒子群更新
- %速度1设置
- va(1,i) = va(1,i) + c1*rand(1)*(x_best(1,i)-x(1,i)) + c2*rand(1)*(Tx_best-x(1,i));
- %更新
- x(1,i) = x(1,i) + va(1,i);
最优值输出
- [BsJ,x(1,i)] = func_fitness(x(1,i));
-
- if BsJ<BsJi(i)
- BsJi(i) = BsJ;
- x_best(1,i) = x(1,i);
- end
- if BsJi(i)<minJi
- minJi = BsJi(i);
- Tx_best = x(1,i);
- end
完整程序如下:
- clc;
- clear;
- close all;
- warning off;
- rng('default');
-
-
- %%
- c1 = 2;
- c2 = 2;
- %x的范围
- min1 = -100;
- max1 = 100;
-
- %速度的范围
- vmin =-1;
- vmax = 1;
- %粒子数目
- Pop = 100;
- BsJ = 1;
- %迭代次数
- tmax = 100;
-
- x = zeros(1,Pop);
- va = zeros(size(x));
- x_best = zeros(1,Pop);
-
- %粒子初始化
- for i=1:Pop
- x(1,i) = rand(1)*(max1-min1)+min1;
- x_best(1,i) = rand(1)*(max1-min1)+min1;
-
- [BsJ,x(1,i)] = func_fitness(x(1,i));
- BsJi(i) = BsJ;
-
- va(1,i) =(vmax-vmin)*rand(1)+vmin;
- end
- [minJi,index]= min(BsJi);
-
- Tx_best = 10;
-
-
- for t=1:tmax
- t
- time(t) = t;
- for i=1:Pop
- rng(i);
- %N
- %速度1设置
- va(1,i) = va(1,i) + c1*rand(1)*(x_best(1,i)-x(1,i)) + c2*rand(1)*(Tx_best-x(1,i));
- %更新
- x(1,i) = x(1,i) + va(1,i);
- %变量1的限制
- if x(1,i) >= max1
- x(1,i) = max1;
- end
- if x(1,i) <= min1
- x(1,i) = min1;
- end
-
- [BsJ,x(1,i)] = func_fitness(x(1,i));
-
- if BsJ<BsJi(i)
- BsJi(i) = BsJ;
- x_best(1,i) = x(1,i);
- end
- if BsJi(i)<minJi
- minJi = BsJi(i);
- Tx_best = x(1,i);
- end
- end
- Jibest(t) = minJi;
- end
- Tx_best
-
- figure;
- plot(Jibest,'b','linewidth',1);
- xlabel('迭代次数');
- ylabel('J');
- grid on
首先,定义一个适应度函数程序:func_fitness.m
- function [minf,x] = func_fitness(x)
-
- minf = 1/(1+abs(x));
-
- x=x;
这个函数表达式为:

完整程序如下:
- clc;
- clear;
- close all;
- warning off;
- rng('default');
-
-
- %%
- c1 = 2;
- c2 = 2;
- %x的范围
- min1 = -1000;
- max1 = 1000;
-
- %速度的范围
- vmin =-1;
- vmax = 1;
- %粒子数目
- Pop = 100;
- BsJ = 1;
- %迭代次数
- tmax = 200;
-
- x = zeros(1,Pop);
- va = zeros(size(x));
- x_best = zeros(1,Pop);
-
- %粒子初始化
- for i=1:Pop
- x(1,i) = rand(1)*(max1-min1)+min1;
- x_best(1,i) = rand(1)*(max1-min1)+min1;
-
- [BsJ,x(1,i)] = func_fitness(x(1,i));
- BsJi(i) = BsJ;
-
- va(1,i) =(vmax-vmin)*rand(1)+vmin;
- end
- [maxJi,index]= max(BsJi);
-
- Tx_best = 0;
-
-
- for t=1:tmax
- t
- time(t) = t;
- for i=1:Pop
- rng(i);
- %N
- %速度1设置
- va(1,i) = va(1,i) + c1*rand(1)*(x_best(1,i)-x(1,i)) + c2*rand(1)*(Tx_best-x(1,i));
- %更新
- x(1,i) = x(1,i) + va(1,i);
- %变量1的限制
- if x(1,i) >= max1
- x(1,i) = max1;
- end
- if x(1,i) <= min1
- x(1,i) = min1;
- end
-
- [BsJ,x(1,i)] = func_fitness(x(1,i));
-
- if BsJ>BsJi(i)
- BsJi(i) = BsJ;
- x_best(1,i) = x(1,i);
- end
- if BsJi(i)>maxJi
- maxJi = BsJi(i);
- Tx_best = x(1,i);
- end
- end
- Jibest(t) = maxJi;
- end
- Tx_best
-
- figure;
- plot(Jibest,'b','linewidth',1);
- xlabel('迭代次数');
- ylabel('J');
- grid on
最后,通过MATLAB仿真:

从仿真可以看到,PSO的迭代过程,从0.6逐渐降低到0附近,说明优化成功,此时对应的最优解为4.9972,而实际最优解为5.所以优化成功。


从仿真可以看到,PSO的迭代过程,从0.95逐渐提高到1附近,说明优化成功,此时对应的最优解为-2.3233e-4,而实际最优解为0.所以优化成功。
通过上面两个案例,我们学会了如何通过PSO算法搜索目标函数的最小值或者最大值。那么根据这个方法,我们还可以实现其他目标函数的最优值。
比如:计算某个面积的最优覆盖了,结构最优化等等,其核心就是将适应度函数的表达式进行数学建模,而其解作为粒子群x的位置信息输入,那么当x达到最优位置时,自然就找到了目标函数的最优解。