Python实现粒子群算法详解
作者:微小冷
算法原理
粒子群算法,缩写为PSO(Particle Swarm Optimization),是一种非线性寻优算法,其特点是实现简单、收敛速度快,对多元函数的局部最优有较好的克服能力。
Python实现
首先,需要创建一个类或者字典来表示粒子,这里用类来实现
import numpy as np uniRand = np.random.uniform class Particle: def __init__(self, N, xRange, vRange): # 生成(N)维参数 self.x = uniRand(*xRange, (N,)) self.v = uniRand(*vRange, (N,)) self.best = np.inf self.xBest = np.zeros((N,))
接下来实现粒子群,粒子群无非是多个粒子,所以要有一个存放粒子的列表。故其初始化函数如下,其中best
和xBest
分别存放全局最优解和全局最优参数。
from copy import deepcopy rand = np.random.rand class Swarm: # pNum 粒子个数,N粒子维度,即参数个数 # wRange 最大最小权重 def __init__(self, pNum, N, xRange, vRange, wRange, c): self.ps = [Particle(N, xRange, vRange) for _ in range(pNum)] self.bestPs = deepcopy(self.ps) self.best = np.inf #全局最优值 self.xBest = np.zeros((N,)) #全局最优参数 self.wRange = wRange self.c0, self.c1 = c self.N = N
然后将参数更新的规则封入一个函数中,这里包括三个内容的更新,
首先是从当前计算结果中,挑选出最优结果,作为新的全局最优值;
然后针对单个粒子,更新粒子的历史最优值;
最后,也是最复杂的一步,即更新每个粒子的速度和位置。
在写好单步更新函数之后,将其写入循环中,就是粒子群算法的主干了,代码如下。
# 下面的函数写在class Swarm中 # 为了书写方便,这里顶个写,注意在Swarm中的缩进 # 参数更新 func为待优化函数 def oneStep(self, func, w=1): for p in self.ps: y = func(p.x) # 更新历史最优值 if y < p.best: p.best = y p.xBest = deepcopy(p.x) # 更新粒子群最优情况 if y < self.best: self.best = y self.xBest = deepcopy(p.x) self.bestPs = deepcopy(self.ps) for p in self.ps: iw = uniRand(*self.wRange, 1)[0] us = self.c0 * rand(self.N) * (p.xBest - p.x) vs = self.c1 * rand(self.N) * (self.xBest - p.x) p.v = iw * p.v + us + vs p.x = p.x + p.v return self.best # nMsg为输出提示的周期 # iter为迭代次数 def optimize(self, func, nMsg, iter): for i in range(iter): best = self.oneStep() if i % nMsg == 0: print(f"第{i}次迭代最小值为{best}")
得益于pyhton的函数式特性,可以方便地将函数作为参数传入,从而在优化函数optimize
中,直接把被优化的函数func
用作输入参数。
算法测试
最后,代码写好之后,可以测试一下,假设现有一个比较复杂的多元函数,其中 Xi为不同维度的参数,令 i = 1..10 i=1..10 i=1..10,即下面是一个10元函数。
测试代码写为
def test(xs): s = 0.0 for i in range(len(xs)): s += np.cos(i*xs[i]/5)*(i+1) return s
if __name__ == "__main__": xRange = (-3,3) vRange = (-1,1) wRange = (0.5,1) C = (1.5, 1.5) s = Swarm(20, 10, xRange, vRange, wRange, C) s.optimize(test, 20, 200) print("最佳位置在:\n", s.xBest)
测试结果为
第1次迭代最小值为-29.665606552469008
第21次迭代最小值为-36.351923008184464
第41次迭代最小值为-47.14461157300818
第61次迭代最小值为-52.25291216470125
第81次迭代最小值为-52.964363058825406
第101次迭代最小值为-52.99124052250346
第121次迭代最小值为-52.99966161164592
第141次迭代最小值为-52.99990804268494
第161次迭代最小值为-52.99997494166753
第181次迭代最小值为-52.9999871143357
最佳位置在:
[ 28.01165182 -15.70858655 7.85375734 5.23563916 -3.92708994
-3.14138732 -2.61760754 2.24427198 5.89048506 -1.74515961]
可见其收敛速度还是很快的。
到此这篇关于Python实现粒子群算法详解的文章就介绍到这了,更多相关Python粒子群算法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!