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 最大最小權重 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)容的更新,
首先是從當前計算結果中,挑選出最優(yōu)結果,作為新的全局最優(yōu)值;
然后針對單個粒子,更新粒子的歷史最優(yōu)值;
最后,也是最復雜的一步,即更新每個粒子的速度和位置。
在寫好單步更新函數(shù)之后,將其寫入循環(huán)中,就是粒子群算法的主干了,代碼如下。
# 下面的函數(shù)寫在class Swarm中 # 為了書寫方便,這里頂個寫,注意在Swarm中的縮進 # 參數(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ù)。
算法測試
最后,代碼寫好之后,可以測試一下,假設現(xiàn)有一個比較復雜的多元函數(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 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實現(xiàn)粒子群算法詳解的文章就介紹到這了,更多相關Python粒子群算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Anaconda 查看、創(chuàng)建、管理和使用python環(huán)境的方法
這篇文章主要介紹了Anaconda 查看、創(chuàng)建、管理和使用python環(huán)境的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-12-12實例講解Python中函數(shù)的調(diào)用與定義
這篇文章主要介紹了Python中函數(shù)的調(diào)用與定義,是Python入門學習中的基礎知識,需要的朋友可以參考下2016-03-03