什么是粒子群算法
粒子群算法,也稱粒子群優(yōu)化算法或鳥(niǎo)群覓食算法(Particle Swarm Optimization,PSO)。由J. Kennedy和R. C. Eberhart等人于1995年提出。其屬于進(jìn)化算法的一種,也是從隨機(jī)解出發(fā),通過(guò)迭代尋找最優(yōu)解,其通過(guò)適應(yīng)度來(lái)評(píng)價(jià)解的品質(zhì)。
這種算法以其實(shí)現(xiàn)容易、精度高、收斂快等優(yōu)點(diǎn)引起了學(xué)術(shù)界的重視,并且在解決實(shí)際問(wèn)題中展示了其優(yōu)越性。
求解過(guò)程
PSO通過(guò)模擬鳥(niǎo)群的捕食行為完成最優(yōu)解的求取。
假設(shè)一群鳥(niǎo)在一個(gè)空間捕捉食物。在這個(gè)區(qū)域里只有一塊食物(對(duì)應(yīng)著最優(yōu)解)。所有的鳥(niǎo)都不知道食物在那里。但是它們可以判斷自身與食物的大致距離(通過(guò)fit值判斷與最優(yōu)解的距離)。最簡(jiǎn)單有效的方法就是搜尋目前離食物最近的鳥(niǎo)的周圍區(qū)域。
PSO中,問(wèn)題的每個(gè)解都是搜索空間中的一只“鳥(niǎo)”。我們稱之為“粒子”。所有的粒子都有一個(gè)由被優(yōu)化的函數(shù)決定的適應(yīng)值(fitness value),可以通過(guò)種群中適應(yīng)度最高的粒子的位置和自身與自身最優(yōu)情況的判斷完成位置的更新。
即,PSO 會(huì)初始化一群隨機(jī)粒子。利用迭代尋找最優(yōu)解。在每一次迭代中,粒子通過(guò)跟蹤兩個(gè)"極值"來(lái)實(shí)現(xiàn)位置的更新。
1、粒子本身所找到的最優(yōu)解,個(gè)體極值pbest。
2、整個(gè)種群目前找到的最優(yōu)解,全局極值gBest。
每個(gè)粒子有一個(gè)重要的屬性,名為速度,該屬性同樣決定了它們更新的方向和更新的距離。
粒子們會(huì)追隨當(dāng)前的最優(yōu)粒子在解空間中搜索。
粒子群算法的求解偽代碼如下:
初始化粒子群
while 未達(dá)到最大迭代次數(shù)或最小loss:
for each_p in 粒子群:
計(jì)算適應(yīng)度
如果某個(gè)粒子適應(yīng)度高于歷史上的最佳適應(yīng)度(pbest)
將該值設(shè)置為新的pbest
選擇所有粒子的最佳適配值的粒子作為gbest
for each_p in 粒子群:
根據(jù)方程(a)計(jì)算粒子速度
根據(jù)方程式(b)更新粒子位置
其中方程(a)為:

方程(b)為:

在方程中,v[i] 是第i個(gè)粒子的速度,w是慣性權(quán)重(有助于跳出局部最優(yōu)解),present[i] 是第i個(gè)粒子的當(dāng)前位置,pbest[i]是第i個(gè)粒子的歷史最佳,gbest是全局最佳,rand () 是介于(0, 1)之間的隨機(jī)數(shù)。c1、c2 是學(xué)習(xí)因子,通常情況下,c1 = c2 = 2。
對(duì)于方程(a)而言:

代表利用粒子本身所找到的最優(yōu)解更新自己的速度。

代表利用整個(gè)種群目前找到的最優(yōu)解更新自己的速度。
實(shí)現(xiàn)代碼 無(wú)錫看婦科的醫(yī)院 http://www.ytsgfk120.com/
這是一個(gè)求取二元一次方程y = -x^2 + 20*x + 10的最大值的例子。
import numpy as np
class PSO():
def __init__(self,pN,dim,max_iter,func):
self.w = 0.8 #慣性因子
self.c1 = 2 #自身認(rèn)知因子
self.c2 = 2 #社會(huì)認(rèn)知因子
self.r1 = 0.6 #自身認(rèn)知學(xué)習(xí)率
self.r2 = 0.3 #社會(huì)認(rèn)知學(xué)習(xí)率
self.pN = pN #粒子數(shù)量
self.dim = dim #搜索維度
self.max_iter = max_iter #最大迭代次數(shù)
self.X = np.zeros((self.pN,self.dim)) #初始粒子的位置和速度
self.V = np.zeros((self.pN,self.dim))
self.pbest = np.zeros((self.pN,self.dim),dtype = float) #粒子歷史最佳位置
self.gbest = np.zeros((1,self.dim),dtype = float) #全局最佳位置
self.p_bestfit = np.zeros(self.pN) #每個(gè)個(gè)體的歷史最佳適應(yīng)值
self.fit = -1e15 #全局最佳適應(yīng)值
self.func = func
def function(self,x):
return self.func(x)
def init_pop(self,): #初始化種群
for i in range(self.pN):
#初始化每一個(gè)粒子的位置和速度
self.X[i] = np.random.uniform(0,5,[1,self.dim])
self.V[i] = np.random.uniform(0,5,[1,self.dim])
self.pbest[i] = self.X[i] #初始化歷史最佳位置
self.p_bestfit[i] = self.function(self.X[i]) #得到對(duì)應(yīng)的fit值
if(self.p_bestfit[i] > self.fit):
self.fit = self.p_bestfit[i]
self.gbest = self.X[i] #得到全局最佳
def update(self):
fitness = []
for _ in range(self.max_iter):
for i in range(self.pN): #更新gbest\pbest
temp = self.function(self.X[i]) #獲得當(dāng)前位置的適應(yīng)值
if( temp > self.p_bestfit[i] ): #更新個(gè)體最優(yōu)
self.p_bestfit[i] = temp
self.pbest[i] = self.X[i]
if(self.p_bestfit[i] > self.fit): #更新全局最優(yōu)
self.gbest = self.X[i]
self.fit = self.p_bestfit[i]
for i in range(self.pN): #更新權(quán)重
self.V[i] = self.w*self.V[i] + self.c1*self.r1*(self.pbest[i] - self.X[i]) + \
self.c2*self.r2*(self.gbest - self.X[i])
self.X[i] = self.X[i] + self.V[i]
fitness.append(self.fit)
return self.gbest,self.fit
def count_func(x):
y = -x**2 + 20*x + 10
return y
pso_example = PSO(pN = 50,dim = 1,max_iter = 300, func = count_func)
pso_example.init_pop()
x_best,fit_best= pso_example.update()
print(x_best,fit_best)
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
