一、官方定义:
首先我们要知道粒子群算法具体要解决的问题是什么,官方定义是:子群算法,也称粒子群优化算法或鸟群觅食算法(Particle Swarm Optimization),缩写为 PSO, 是近年来由J. Kennedy和R. C. Eberhart等开发的一种新的进化算法(Evolutionary Algorithm - EA)。PSO 算法属于进化算法的一种,和模拟退火算法相似,它也是从随机解出发,通过迭代寻找最优解,它也是通过适应度来评价解的品质,但它比遗传算法规则更为简单,它没有遗传算法的“交叉”(Crossover) 和“变异”(Mutation) 操作,它通过追随当前搜索到的最优值来寻找全局最优。这种算法以其实现容易、精度高、收敛快等优点引起了学术界的重视,并且在解决实际问题中展示了其优越性。粒子群算法是一种并行算法。
二、通俗理解:
我们设想有这样一个场景:一群小鸟在随机的寻找食物,而且在这个特定的区域中只有一块食物,他们并不知道食物的具体位置,只知道和食物的距离,他们想要找到食物,最优的策略或者说最节省体能的寻找到食物的方法是啥?鸟群在搜索的时候总能找到最优的方法搜索到食物。
那么我们可以得到一个类似于如下图这样的思路:也就是粒子群算法的基本思想:
那么搜寻食物的最优策略是什么呢?
1、 搜寻距离食物最近的鸟的的周围区域。
2、 根据自己记得飞行经验判断食物所在区域。
单独这样讲的话可能我们还是不能从中抽象出近点的粒子群算法公式:那么应用一个故事来讲解:
故事讲解:
鸟妈妈有7个鸟宝宝,有一天,鸟妈妈让鸟宝宝们自己去找虫子吃。于是鸟宝宝们开始了大范围的捕食行为。一开始鸟宝宝们不知道哪里可以找得到虫子,于是每个鸟宝宝都朝着不同的方向独自寻找。
但是为了能够更快的找到虫子吃,鸟宝宝们协商好,谁发现了虫子,就互相说一声。
找了一会,终于有一个鸟宝宝(称之为小蓝),似乎发现在他附近不远处有虫子的踪迹。于是它传话给其他鸟宝宝,其他鸟宝宝,收到消息后,边开始改变轨迹,飞到小蓝这边。最终,随着小蓝越来越接近虫子。其他虫宝宝也差不多都聚集到了小蓝这边。最终,大家都吃到了虫子。
抽象提取:
鸟宝宝捕食的故事,正是这个粒子群算法存在的原因。因此,如果想更好的了解粒子群算法,我们就要来分析鸟宝宝捕食的故事。首先,我们来分析分析鸟宝宝们的运动状态,即鸟宝宝自身是怎么决定自己的飞翔速度和位置的。
(1) 呐首先,我们知道物体是具有惯性的,鸟宝宝在一开始飞翔的时候,无论它下一次想怎么飞,往哪个方向飞,它都有一个惯性,它必须根据当前的速度和方向来进行下一步的调整。对吧,这个可以理解吧,因此,“惯性”——当前的速度vcurrentvcurrent是一个因素。
(2) 其次,由于鸟宝宝长期捕食,因此鸟宝宝有经验,它虽然不知道具体哪里是有虫子的存在,但是它能大概知道虫子分布在哪里。比如当鸟宝宝飞到贫瘠的地方,它肯定知道这里是不会有虫子的,因此,在鸟宝宝的心中,它每次飞,都会根据自己的经验来找,比如以往虫子分布的地区,它肯定优先对这部分的地方进行搜索。因此,自己的“认知”——经验,也是一个因素。
(3) 最后,每个鸟宝宝发现自己离虫子更接近的时候,便会发出信号给同伴,在遇到这样的信号,其余还在找的鸟宝宝们就会想着,同伴的位置更接近虫子,我要往它那边过去看看。我们称之为“社会共享”,这也是鸟宝宝在移动时考虑的一个因素。
综上所述,鸟宝宝每次在决定下一步移动的速度和方向时,脑子里是由这三个因素影响的。我们想,如果能够用一条公式来描述着三个因素的影响的话,那不就能写出每个鸟宝宝的移动方向和速度么。但是,每一个鸟宝宝,对这三个因素的考虑都是不一致的,比如对于捕食经验不高的鸟宝宝,移动的时候会更看重同伴分享的信息,而对于捕食经验高的鸟宝宝,则更看重自己的经验。因此,我们的公式,在“认知”和“社会共享”这部分,是具有随机性的。
抽象为数学公式:
粒子群的算法可以这样解释和理解:
(1)每一个小鸟都是我们中的一个解,也就是我们把每一个小鸟当成一个“粒子”,而我们的小鸟索要寻找到的虫子,也就是食物就是我们的最优解。总结起来就是一句话,小鸟寻找事物的过程就是所有粒子在解空间内寻找到最优解的过程。
(2)每一个粒子都是由一个 fitness function 来确定fitness value,依此来确定位置的好坏。
(3)每一个粒子都有记忆功能,记忆了自己所搜寻过的最好位置位置。
(4)每一个粒子都有一个速度以及决定飞行的距离和方向,这个根据它本身的飞行经验和同伴共享的信息所决定。
现在,在d维空间中,有n个粒子。其中:
粒子i的位置:Xi=(xi1,xi2,⋅⋅⋅,xid)
粒子i的速度:Vi=(vi1,vi2,⋅⋅⋅,vid)
粒子i所搜寻到的最好的位置(personal best):
Pbestid=(pbesti1,pbesti2,⋅⋅⋅,pbestid)Pbestid=(pbesti1,pbesti2,⋅⋅⋅,pbestid)
种群所经历的最好的位置(global best):
Gbestd=(gbest1,gbest2,⋅⋅⋅,gbestd)Gbestd=(gbest1,gbest2,⋅⋅⋅,gbestd)
另外,我们要给我们的粒子速度和位置做一个限制,毕竟我们不希望鸟宝宝的速度过快或者以及飞出我们要搜寻的范围。因此对于每个粒子i,有:Xi∈[Xmin,Xmax]
根据前面的分析,我们可以写出下面两条公式:
- 在d维空间中,粒子i的速度更新公式为:
Vki=wVk−1i+c1rand()(Pbesti−Xk−1i)+c2Rand()(Gbesti−Xk−1i)Vik=wVik−1+c1rand()(Pbesti−Xik−1)+c2Rand()(Gbesti−Xik−1)
- 在d维空间中,粒子i的位置更新公式为:
Xki=Xk−1id+Vk−1iXik=Xidk−1+Vik−1
在上式中,上标k-1和k表示粒子从k-1次飞行操作到下一次飞行操作的过程。
(1) 我们先来看看速度更新公式,可以看出包含三部分,分别是我们前面分析的“惯性”、“认知”、“社会共享”这三大块。而rand()和Rand()分别给“认知”和“社会共享”提供随机性,即每个粒子对这两部分的看重是不一样的。其中c_{1}和c_{2}是我们自己加的,表示我们自己对这两部分的分量的控制。另外w是一个惯性的权重,是用于调节对解空间的搜索范围。关于这个w的出现还有一段历史,大家感兴趣的可以去查查论文,这里就不细讲了。
(2) 接着是位置更新公式,这部分很简单,我们都知道x=x0+vtx=x0+vt。可是这里为什么少了个tt呢,这里我们可以简单理解为从k-1次飞行到下一次飞行,耗费了一个单位时间tt,因此就没有tt出现了。
代码步骤:
(1) Initial:
初始化粒子群体(群体规模为n),每个粒子的信息包括随机位置和随机速度。
(2) Evaluation
根据fitness function,算出每个粒子的fitness value。
(3) Find the Pbest
对于每个粒子,将其当前的fitness value与历史最佳的位置(Pbest)所对应的fitness value做比较。若当前的fitness value更高,则将当前的位置更新Pbest。
(4) Find the Gbest
对于每个粒子,将其当前的fitness value与群体历史最佳的位置(Gbest)所对应的fitness value做比较。若当前的fitness value更高,则将当前的位置更新Gbest。
(5) Update the Velocity and Position:
根据公式更新每个粒子的速度和位置
(6) 如果未找到最佳值,则返回步骤2。(若达到了最佳迭代数量或者最佳fitness value的增量小于给定的阈值,则停止算法)