什么是粒子群算法算法
粒子群算法,也称粒子群优化算法或鸟群觅食算法(Particle Swarm Optimization,PSO)。由J. Kennedy和R. C. Eberhart等人于1995年提出。其属于进化算法的一种,也是从随机解出发,经过迭代寻找最优解,其经过适应度来评价解的品质。app
这种算法以其实现容易、精度高、收敛快等优势引发了学术界的重视,而且在解决实际问题中展现了其优越性。dom
求解过程ide
PSO经过模拟鸟群的捕食行为完成最优解的求取。函数
假设一群鸟在一个空间捕捉食物。在这个区域里只有一块食物(对应着最优解)。全部的鸟都不知道食物在那里。可是它们能够判断自身与食物的大体距离(经过fit值判断与最优解的距离)。最简单有效的方法就是搜寻目前离食物最近的鸟的周围区域。学习
PSO中,问题的每一个解都是搜索空间中的一只“鸟”。咱们称之为“粒子”。全部的粒子都有一个由被优化的函数决定的适应值(fitness value),能够经过种群中适应度最高的粒子的位置和自身与自身最优状况的判断完成位置的更新。优化
即,PSO 会初始化一群随机粒子。利用迭代寻找最优解。在每一次迭代中,粒子经过跟踪两个"极值"来实现位置的更新。spa
一、粒子自己所找到的最优解,个体极值pbest。orm
二、整个种群目前找到的最优解,全局极值gBest。blog
每一个粒子有一个重要的属性,名为速度,该属性一样决定了它们更新的方向和更新的距离。
粒子们会追随当前的最优粒子在解空间中搜索。
粒子群算法的求解伪代码以下:
初始化粒子群
while 未达到最大迭代次数或最小loss:
for each_p in 粒子群:
计算适应度
若是某个粒子适应度高于历史上的最佳适应度(pbest)
将该值设置为新的pbest
选择全部粒子的最佳适配值的粒子做为gbest
for each_p in 粒子群:
根据方程(a)计算粒子速度
根据方程式(b)更新粒子位置
其中方程(a)为:
方程(b)为:
在方程中,v[i] 是第i个粒子的速度,w是惯性权重(有助于跳出局部最优解),present[i] 是第i个粒子的当前位置,pbest[i]是第i个粒子的历史最佳,gbest是全局最佳,rand () 是介于(0, 1)之间的随机数。c一、c2 是学习因子,一般状况下,c1 = c2 = 2。
对于方程(a)而言:
表明利用粒子自己所找到的最优解更新本身的速度。
表明利用整个种群目前找到的最优解更新本身的速度。
实现代码无锡看妇科的医院 /
这是一个求取二元一次方程y = -x^2 + 20*x + 10的最大值的例子。
import numpy as np
class PSO():
def __init__(self,pN,dim,max_iter,func):
self.w = 0.8 #惯性因子
self.c1 = 2 #自身认知因子
self.c2 = 2 #社会认知因子
self.r1 = 0.6 #自身认知学习率
self.r2 = 0.3 #社会认知学习率
self.pN = pN #粒子数量
self.dim = dim #搜索维度
self.max_iter = max_iter #最大迭代次数
self.X = np.zeros((self.pN,self.dim)) #初始粒子的位置和速度
self.V = np.zeros((self.pN,self.dim))
self.pbest = np.zeros((self.pN,self.dim),dtype = float) #粒子历史最佳位置
self.gbest = np.zeros((1,self.dim),dtype = float) #全局最佳位置
self.p_bestfit = np.zeros(self.pN) #每一个个体的历史最佳适应值
self.fit = -1e15 #全局最佳适应值
self.func = func
def function(self,x):
return self.func(x)
def init_pop(self,): #初始化种群
for i in range(self.pN):
#初始化每个粒子的位置和速度
self.X[i] = np.random.uniform(0,5,[1,self.dim])
self.V[i] = np.random.uniform(0,5,[1,self.dim])
self.pbest[i] = self.X[i] #初始化历史最佳位置
self.p_bestfit[i] = self.function(self.X[i]) #获得对应的fit值
if(self.p_bestfit[i] > self.fit):
self.fit = self.p_bestfit[i]
self.gbest = self.X[i] #获得全局最佳
def update(self):
fitness = []
for _ in range(self.max_iter):
for i in range(self.pN): #更新gbest\pbest
temp = self.function(self.X[i]) #得到当前位置的适应值
if( temp > self.p_bestfit[i] ): #更新个体最优
self.p_bestfit[i] = temp
self.pbest[i] = self.X[i]
if(self.p_bestfit[i] > self.fit): #更新全局最优
self.gbest = self.X[i]
self.fit = self.p_bestfit[i]
for i in range(self.pN): #更新权重
self.V[i] = self.w*self.V[i] + self.c1*self.r1*(self.pbest[i] - self.X[i]) + \
self.c2*self.r2*(self.gbest - self.X[i])
self.X[i] = self.X[i] + self.V[i]
fitness.append(self.fit)
return self.gbest,self.fit
def count_func(x):
y = -x**2 + 20*x + 10
return y
pso_example = PSO(pN = 50,dim = 1,max_iter = 300, func = count_func)
pso_example.init_pop()
x_best,fit_best= pso_example.update()
print(x_best,fit_best)