粒子群算法笔记
- 算法背景:
- 求解复杂非线性函数的极值问题
- 求解多参数拟合问题
- 算法原理:
粒子群算法源于鸟群觅食行为,假设有一群鸟,在随机搜索食物,在搜索区域内只有一块儿食物,一开始时所有的鸟儿都不知道食物所在的方位,但它们能够知道自己离食物有多远,以及它们能够记住在自己飞过的路程当中距离食物最近的位置,同时它们也能够知道鸟群中所有鸟儿经过的路程当中,离食物最近的位置。
那每一只鸟儿将如何去寻找食物呢?简单来说,每一只鸟儿在当前位置的基础上,如何做出决策,下一步向哪里飞呢?
实际,每只鸟儿将综合自身的经验,以及群体的经验来在做出下一步飞向哪里的决策,即每只鸟儿将根据自己所经过的路程中离食物最近的位置以及鸟群中所有鸟儿经过的路程当中离食物最近的位置来做出决策,决定下一步自己向哪里飞。 - 知识点
Xi:表示优化问题的D维空间的一个解,对应于粒子群中第i个例子的位置
Pi:表示第i个粒子所经历的所有路程上的最优位置,即飞翔过程中离目标函数最优
解最近的位置
Pg:代表所有粒子经历过的路程上的最优位置,即所有个体最优位置当中的最优位
置
Vi:代表第i个粒子的飞翔速度
算法公式:
(1) Vi = w*vi+c1*r1*(Pi-Xi)+c2*r2*(Pg-Xi)
(2) Xi = Xi+a*Vi
两个公式中,i代表粒子编号;d代表维度编号;w为惯性因子,其取值范围为非负;c为加速常数,其取值范围为非负常数;r为0到1范围内的随机数;a为约束因子,用来控制速度的权重。
惯性因子w:用来控制继承多少粒子当前的速度的,越大则对于当前速度的继承程度越小,越小则对于当前速度的继承程度越大。
加速常数c:通过公式(1)可以看出,加速常数控制着飞翔速度的计算是更加看重自身经验还是群体经验
求解函数极值代码:
def fitness(Xb):
F = pow((Xb[1] - 5.1 / (4 * pow(np.pi, 2)) * pow(Xb[0], 2) + 5 / np.pi * Xb[0] - 6), 2) + 10 * (
1 - 1 / (8 * np.pi)) * np.cos(Xb[0]) + 10
return F
import numpy as np
N=50 #粒子数量
c1=2 #自身经验在计算粒子飞翔速度上的权重
c2=2 #群体经验在计算粒子飞翔速度过程中的权重
w=0.5 #惯性因子
M=1000 #迭代次数
D=2 #维数,即自变量的个数
x=np.zeros((N,D)) #粒子群中粒子的位置
v=np.zeros((N,D)) #粒子群中粒子的飞行速度
p=np.zeros(N) #适应度函数值
y=np.zeros((N,D)) #粒子群中粒子的所有路程上的最优解的位置
Pbest=np.zeros(M) #每次迭代的最优解
初始化粒子位置和飞行速度
for i in range(N):
for j in range(D):
x[i,j]=np.random.rand()
v[i,j]=np.random.rand()
计算初始条件下的适应度函数值并记录下初始位置
for i in range(N):
p[i]=fitness(x[i,:])
y[i,:]=x[i,:]
选择初始条件下粒子群的最优解(最小值)
pg=x[N-1,:]
for i in range(N):
if fitness(x[i,:])<fitness(pg):
pg=x[i,:]
进行M次迭代
for t in range(M):
for i in range(N):
v[i,:]=w*v[i,:]+c1*np.random.rand()*(y[i,:]-x[i,:])+c2*np.random.rand()*(pg-x[i,:]) #更新速度
x[i,:]=x[i,:]+v[i,:] #更新位置
if fitness(x[i,:])<p[i]:
p[i]=fitness(x[i,:]) #单个粒子对应适应度函数最优值的更新
y[i,:]=x[i,:] #记录下第i个粒子最优的位置
if p[i]<fitness(pg):
pg=y[i,:] #更新所有粒子的最优位置
Pbest[t]=fitness(pg)
求解结果:
print(pg):[3.14159265 2.27499998] #函数最小值时x的值
print(Pbest.min()):0.39788735772973816 #函数最小值