粒子群算法的由来及思想
粒子群算法最早是由两名美国的科学家基于群鸟觅食,寻找最佳觅食区域的过程所提出来的,作为一种智能算法,PSO模拟的就是最佳决策的过程,鸟群觅食类似于人类的决策过程,想想在你做出选择之前,是不是会受到自己的经验(局部最优)以及周围人的经历(全局最优)的影响?同样的道理,群鸟在觅食的过程当中,每一只鸟的初始位置都处于随机状态,当然也不知道最佳的觅食点在何处,并且每只鸟的飞行方向也是随机的。可以认为,在觅食的初期,鸟群的运动轨迹都是杂乱无章的,随着时间的推移,处于随机位置的鸟类通过群内的相互学习、共享觅食信息,每一只鸟在每一次的觅食过程中结合自己的经验和同伴传送的信息估计目前所处的位置能够找到食物有多大的价值。基于这样的搜索方式,粒子群算法(Particle Swarm Optimization,PSO)应运而生。
假设在一个D维的目标搜索空间中,有N个粒子组成一个群落,其中第i个粒子表示为一个D维的向量:
第i个粒子的“飞行”速度也是一个D维的向量,记为:
在第t代的第i个粒子向第t+1代进化时,根据如下式子更新:
第一个式子,第一项是惯性权重,第二项是个体最优,第三项全局最优,三项线性组合,决定了粒子的下一步寻优方向。
参数w
下面是流程图。
我们用粒子群算法求解最大值
import numpy as np
w = 0.8 #惯性因子
c1 = 2 #自身认知因子
c2 = 2 #社会认知因子
r1 = 0.6 #自身认知学习率
r2 = 0.3 #社会认知学习率
pN = 50 #粒子数量
dim = 1 #搜索维度
max_iter = 300 #最大迭代次数
def get_fitness(x):
y = -x**2 + 20*x + 10
return y
X = np.zeros((pN, dim)) #初始粒子的位置和速度
V = np.zeros((pN, dim))
p_best = np.zeros((pN, dim), dtype = float) #粒子历史最佳位置
g_best = np.zeros((1, dim), dtype = float) #全局最佳位置
p_bestfit = np.zeros(pN) #每个个体的历史最佳适应值
g_bestfit = -1e15 #全局最佳适应值
for i in range(pN):
#初始化每一个粒子的位置和速度
X[i] = np.random.uniform(0,5,[1, dim])
V[i] = np.random.uniform(0,5,[1, dim])
p_best[i] = X[i] #初始化历史最佳位置
p_bestfit[i] = get_fitness(X[i]) #得到对应的fit值
if p_bestfit[i] > g_bestfit:
g_bestfit = p_bestfit[i]
g_best = X[i] #得到全局最佳
fitness = []
for _ in range(max_iter):
for i in range(pN): #更新g_best\p_best
temp = get_fitness(X[i]) #获得当前位置的适应值
if temp > p_bestfit[i]: #更新个体最优
p_bestfit[i] = temp
p_best[i] = X[i]
if p_bestfit[i] > g_bestfit: #更新全局最优
g_best = X[i]
g_bestfit = p_bestfit[i]
for i in range(pN): #更新权重
V[i] = w*V[i] + c1*r1*(p_best[i] - X[i]) + c2*r2*(g_best - X[i])
X[i] = X[i] + V[i]
fitness.append(g_bestfit)
print(g_best, g_bestfit)
优点:参数少,简单。
缺点:容易陷入局部最优,后期收敛慢。