Python實現(xiàn)粒子群算法詳解
算法原理
粒子群算法,縮寫為PSO(Particle Swarm Optimization),是一種非線性尋優(yōu)算法,其特點是實現(xiàn)簡單、收斂速度快,對多元函數(shù)的局部最優(yōu)有較好的克服能力。

Python實現(xiàn)
首先,需要創(chuàng)建一個類或者字典來表示粒子,這里用類來實現(xiàn)
import numpy as np
uniRand = np.random.uniform
class Particle:
def __init__(self, N, xRange, vRange):
# 生成(N)維參數(shù)
self.x = uniRand(*xRange, (N,))
self.v = uniRand(*vRange, (N,))
self.best = np.inf
self.xBest = np.zeros((N,))接下來實現(xiàn)粒子群,粒子群無非是多個粒子,所以要有一個存放粒子的列表。故其初始化函數(shù)如下,其中best和xBest分別存放全局最優(yōu)解和全局最優(yōu)參數(shù)。
from copy import deepcopy
rand = np.random.rand
class Swarm:
# pNum 粒子個數(shù),N粒子維度,即參數(shù)個數(shù)
# wRange 最大最小權(quán)重
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 #全局最優(yōu)值
self.xBest = np.zeros((N,)) #全局最優(yōu)參數(shù)
self.wRange = wRange
self.c0, self.c1 = c
self.N = N然后將參數(shù)更新的規(guī)則封入一個函數(shù)中,這里包括三個內(nèi)容的更新,
首先是從當(dāng)前計算結(jié)果中,挑選出最優(yōu)結(jié)果,作為新的全局最優(yōu)值;
然后針對單個粒子,更新粒子的歷史最優(yōu)值;
最后,也是最復(fù)雜的一步,即更新每個粒子的速度和位置。
在寫好單步更新函數(shù)之后,將其寫入循環(huán)中,就是粒子群算法的主干了,代碼如下。
# 下面的函數(shù)寫在class Swarm中
# 為了書寫方便,這里頂個寫,注意在Swarm中的縮進(jìn)
# 參數(shù)更新 func為待優(yōu)化函數(shù)
def oneStep(self, func, w=1):
for p in self.ps:
y = func(p.x)
# 更新歷史最優(yōu)值
if y < p.best:
p.best = y
p.xBest = deepcopy(p.x)
# 更新粒子群最優(yōu)情況
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為迭代次數(shù)
def optimize(self, func, nMsg, iter):
for i in range(iter):
best = self.oneStep()
if i % nMsg == 0:
print(f"第{i}次迭代最小值為{best}")得益于pyhton的函數(shù)式特性,可以方便地將函數(shù)作為參數(shù)傳入,從而在優(yōu)化函數(shù)optimize中,直接把被優(yōu)化的函數(shù)func用作輸入?yún)?shù)。
算法測試
最后,代碼寫好之后,可以測試一下,假設(shè)現(xiàn)有一個比較復(fù)雜的多元函數(shù),其中 Xi為不同維度的參數(shù),令 i = 1..10 i=1..10 i=1..10,即下面是一個10元函數(shù)。

測試代碼寫為
def test(xs):
s = 0.0
for i in range(len(xs)):
s += np.cos(i*xs[i]/5)*(i+1)
return sif __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)測試結(jié)果為
第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]
可見其收斂速度還是很快的。
到此這篇關(guān)于Python實現(xiàn)粒子群算法詳解的文章就介紹到這了,更多相關(guān)Python粒子群算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

