Python實(shí)現(xiàn)粒子群算法詳解
算法原理
粒子群算法,縮寫為PSO(Particle Swarm Optimization),是一種非線性尋優(yōu)算法,其特點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單、收斂速度快,對(duì)多元函數(shù)的局部最優(yōu)有較好的克服能力。
Python實(shí)現(xiàn)
首先,需要?jiǎng)?chuàng)建一個(gè)類或者字典來表示粒子,這里用類來實(shí)現(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,))
接下來實(shí)現(xiàn)粒子群,粒子群無非是多個(gè)粒子,所以要有一個(gè)存放粒子的列表。故其初始化函數(shù)如下,其中best
和xBest
分別存放全局最優(yōu)解和全局最優(yōu)參數(shù)。
from copy import deepcopy rand = np.random.rand class Swarm: # pNum 粒子個(gè)數(shù),N粒子維度,即參數(shù)個(gè)數(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ī)則封入一個(gè)函數(shù)中,這里包括三個(gè)內(nèi)容的更新,
首先是從當(dāng)前計(jì)算結(jié)果中,挑選出最優(yōu)結(jié)果,作為新的全局最優(yōu)值;
然后針對(duì)單個(gè)粒子,更新粒子的歷史最優(yōu)值;
最后,也是最復(fù)雜的一步,即更新每個(gè)粒子的速度和位置。
在寫好單步更新函數(shù)之后,將其寫入循環(huán)中,就是粒子群算法的主干了,代碼如下。
# 下面的函數(shù)寫在class Swarm中 # 為了書寫方便,這里頂個(gè)寫,注意在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ù)。
算法測(cè)試
最后,代碼寫好之后,可以測(cè)試一下,假設(shè)現(xiàn)有一個(gè)比較復(fù)雜的多元函數(shù),其中 Xi為不同維度的參數(shù),令 i = 1..10 i=1..10 i=1..10,即下面是一個(gè)10元函數(shù)。
測(cè)試代碼寫為
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)
測(cè)試結(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實(shí)現(xiàn)粒子群算法詳解的文章就介紹到這了,更多相關(guān)Python粒子群算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pytorch實(shí)現(xiàn)圖像識(shí)別(實(shí)戰(zhàn))
這篇文章主要介紹了pytorch實(shí)現(xiàn)圖像識(shí)別(實(shí)戰(zhàn)),文章主要分享實(shí)現(xiàn)代碼,但也具有一定的參考價(jià)值,需要的小伙伴可以才可以一下,希望對(duì)你有所幫助2022-02-02使用Python設(shè)計(jì)一個(gè)代碼統(tǒng)計(jì)工具
這篇文章主要介紹了使用Python設(shè)計(jì)一個(gè)代碼統(tǒng)計(jì)工具的相關(guān)資料,包括文件個(gè)數(shù),代碼行數(shù),注釋行數(shù),空行行數(shù)。感興趣的朋友跟隨腳本之家小編一起看看吧2018-04-04Anaconda 查看、創(chuàng)建、管理和使用python環(huán)境的方法
這篇文章主要介紹了Anaconda 查看、創(chuàng)建、管理和使用python環(huán)境的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12python實(shí)現(xiàn)外賣信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)外賣信息管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01python下載圖片實(shí)現(xiàn)方法(超簡(jiǎn)單)
下面小編就為大家?guī)硪黄猵ython下載圖片實(shí)現(xiàn)方法(超簡(jiǎn)單)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07實(shí)例講解Python中函數(shù)的調(diào)用與定義
這篇文章主要介紹了Python中函數(shù)的調(diào)用與定義,是Python入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-03-03