粒子群算法学习
粒子群算法
粒子群優化算法[45]最原始的工作可以追溯到1987年Reynolds對鳥群社會系統Boids(Reynolds對其仿真鳥群系統的命名)的仿真研究 。通常,群體的行為可以由幾條簡單的規則進行建模,雖然每個個體具有簡單的行為規則,但是卻群體的行為卻是非常的復雜,所以他們在鳥類仿真中,即Boids系統中采取了下面的三條簡單的規則:
(1)飛離最近的個體(鳥),避免與其發生碰撞沖突;
(2)盡量使自己與周圍的鳥保持速度一致;
(3)盡量試圖向自己認為的群體中心靠近。
雖然只有三條規則,但Boids系統已經表現出非常逼真的群體聚集行為。但Reynolds僅僅實現了該仿真,并無實用價值。
1995年Kennedy[46-48]和Eberhart在Reynolds等人的研究基礎上創造性地提出了粒子群優化算法,應用于連續空間的優化計算中 。Kennedy和Eberhart在boids中加入了一個特定點,定義為食物,每只鳥根據周圍鳥的覓食行為來搜尋食物。Kennedy和Eberhart的初衷是希望模擬研究鳥群覓食行為,但試驗結果卻顯示這個仿真模型蘊含著很強的優化能力,尤其是在多維空間中的尋優。最初仿真的時候,每只鳥在計算機屏幕上顯示為一個點,而“點”在數學領域具有多種意義,于是作者用“粒子(particle)”來稱呼每個個體,這樣就產生了基本的粒子群優化算法[49]。
假設在一個D 維搜索空間中,有m個粒子組成一粒子群,其中第i 個粒子的空間位置為
,它是優化問題的一個潛在解,將它帶入優化目標函數可以計算出其相應的適應值,根據適應值
可衡量 的優劣;第i個粒子所經歷的最好位置稱為其個體歷史最好位置,記為
,相應的適應值為個體最好適應值 Fi ;同時,每個粒子還具有各自的飛行速度
。所有粒子經歷過的位置中的最好位置稱為全局歷史最好位置,記為
,相應的適應值為全局歷史最優適應值 。在基本PSO算法中,對第n 代粒子,其第 d 維(1≤d≤D )元素速度、位置更新迭代如式(4-1)、(4-2):
(4-1)
(4-2)
其中:ω為慣性權值;c1 和c2 都為正常數,稱為加速系數;r1 和r2 是兩個在[0, 1]范圍內變化的隨機數。第 d維粒子元素的位置變化范圍和速度變化范圍分別限制為
和
。迭代過程中,若某一維粒子元素的 或 超出邊界值則令其等于邊界值。
粒子群速度更新公式(4-1)中的第 1部分由粒子先前速度的慣性引起,為“慣性”部分;第 2 部分為“認知”部分,表示粒子本身的思考,即粒子根據自身歷史經驗信息對自己下一步行為的影響;第 3部分為“社會”部分,表示粒子之間的信息共享和相互合作,即群體信息對粒子下一步行為的影響。
基本PSO算法步驟如下:
(1)粒子群初始化;
(2)根據目標函數計算各粒子適應度值,并初始化個體、全局最優值;
(3)判斷是否滿足終止條件,是則搜索停止,輸出搜索結果;否則繼續下步;
(4)根據速度、位置更新公式更新各粒子的速度和位置;
(5)根據目標函數計算各粒子適應度值;
(6)更新各粒子歷史最優值以及全局最優值;
(7)跳轉至步驟3。
對于終止條件,通常可以設置為適應值誤差達到預設要求,或迭代次數超過最大允許迭代次數。
基本的連續 PSO 算法中,其主要參數,即慣性權值、加速系數、種群規模和迭代次數對算法的性能均有不同程度的影響 。
慣性權值ω的取值對 PSO 算法的收斂性能至關重要。在最初的基本粒子群算法中沒有慣性權值這一參數 。最初的 PSO 算法容易陷入局部最小,于是在其后的研究中引入了慣性權值來改善 PSO 算法的局部搜索能力,形成了目前常用的基本 PSO算法形式 。取較大的ω值使得粒子能更好地保留速度,從而能更快地搜索解空間,提高算法的收斂速度;但同時由于速度大可能導致算法無法更好地進行局部搜索,容易錯過最優解,特別是過大的ω會使得PSO 算法速度過大而無法搜索到全局最優。取較小的ω值則有利于局部搜索,能夠更好地搜索到最優值,但因為粒子速度受其影響相應變小從而無法更快地進行全局搜索,進而影響算法收斂速度;同時過小ω值更是容易導致算法陷入局部極值。因此,一個合適的ω值能有效兼顧搜索精度和搜索速度、全局搜索和局部搜索,保證算法性能。
加速系數c1 和c2 代表每個粒子向其個體歷史最好位置和群體全局歷史最好位置的移動加速項的權值。較低的加速系數值可以使得粒子收斂到其最優解的過程較慢,從而能夠更好搜索當前位置與最優解之間的解空間;但過低的加速系數值則可能導致粒子始終徘徊在最優鄰域外而無法有效搜索目標區域,從而導致算法性能下降。較高的加速系數值則可以使得粒子快速集中于目標區域進行搜索,提高算法效率;但過高的加速系數值則有可能導致粒子搜索間隔過大,容易越過目標區域無法有效地找到全局最優解。因此加速系數對 PSO 能否收斂也起重要作用,合適的加速系數有利于算法較快地收斂,同時具有一定的跳出局部最優的能力。
對于速度更新公式(4-1)中,若c1 = c2 = 0,粒子將一直以當前的速度進行慣性飛行,直到到達邊界。此時粒子僅僅依靠慣性移動,不能從自己的搜索經驗和其他粒子的搜索經驗中吸取有用的信息,因此無法利用群體智能,PSO 算法沒有啟發性,粒子只能搜索有限的區域,很難找到全局最優解,算法優化性能很差。若c = 0,則粒子沒有認知能力,不能從自己的飛行經驗吸取有效信息,只有社會部分,所以c 又稱為社會參數;此時收斂速度比基本 PSO 快,但由于不能有效利用自身的經驗知識,所有的粒子都向當前全局最優集中,因此無法很好地對整個解空間進行搜索,在求解存在多個局部最優的復雜優化問題時比基本 PSO 容易陷入局部極值,優化性能也變差。若c2 = 0,則微粒之間沒有社會信息共享,不能從同伴的飛行經驗中吸取有效信息,只有認知部分,所以c 又稱為認知參數;此時個體間沒有信息互享,一個規模為m 的粒子群等價于m 個1單個粒子的運行,搜索到全局最優解的機率很小。
PSO 算法中,群體規模對算法的優化性能也影響很大。一般來說,群體規模越大,搜索到全局最優解的可能性也越大,優化性能相對也越好;但同時算法消耗的計算量也越大,計算性能相對下降。群體規模越小,搜索到全局最優解的可能性就越小,但算法消耗的計算量也越小。群體規模對算法性能的影響并不是簡單的線性關系,當群體規模到達一定程度后,再增加群體規模對算法性能的提升有限,反而增加運算量;但群體規模不能過小,過小的群體規模將無法體現出群智能優化算法的智能性,導致算法性能嚴重受損。
對于最大允許迭代次數,較大的迭代次數使得算法能夠更好地搜索解空間,因此找到全局最優解的可能性也大些;相應地,較小的最大允許迭代次數會減小算法找到全局最優解的可能性。對于基本連續 PSO 來說,由于缺乏有效的跳出局部最優操作,因此粒子一旦陷入局部極值后就難以跳出,位置更新處于停滯狀態,此時迭代次數再增多也無法提高優化效果,只會浪費計算資源。但過小的迭代次數則會導致算法在沒有對目標區域實現有效搜索之前就停止更新,將嚴重影響算法性能。此外,隨機數可以保證粒子群群體的多樣性和搜索的隨機性。最大、最小速度可以決定當前位置與最好位置之間區域的分辨率(或精度)。如果最大速度(或最小速度)的絕對值過大,粒子可能會因為累積的慣性速度太大而越過目標區域,從而無法有效搜索到全局最優解;但如果最大速度(或最小速度)的絕對值過小,則粒子不能迅速向當前全局最優解集中,對其鄰域進行有效地搜索,同時還容易陷入局部極值無法跳出。
因此,最大、最小速度的限制主要是防止算法計算溢出、改善搜索效率和提高搜索精度。 基本PSO 算法中只涉及基本的加、減、乘運算操作,編程簡單,易于實現,關鍵參數較少,設定相對簡單,所以引起了廣泛的關注,目前已有多篇文獻對 PSO 算法進行綜述 。
代碼實現
#使用蜂群算法計算這個函數f = @(x,y) -20.*exp(-0.2.*sqrt((x.^2+y.^2)./2))-exp((cos(2.*pi.*x)+cos(2.*pi.*y))./2)+20+exp(1)在區間[-4,4]上的最小值 #它真正的最小值點是(0,0)import numpy as np import matplotlib.pyplot as plt#定義待優化函數:只能處理行向量形式的單個輸入,若有矩陣形式的多個輸入應當進行迭代 def CostFunction(input):x = input[0]y = input[1]result = -20*np.exp(-0.2*np.sqrt((x*x+y*y)/2))- \np.exp((np.cos(2*np.pi*x)+np.cos(2*np.pi*y))/2)+20+np.exp(1)return result#初始化各參數nVar = 2 VarMin = -4 #求解邊界 VarMax = 4 VelMin = -8 #速度邊界 VelMax = 8 nPop = 40 iter_max = 100 #最大迭代次數 C1 = 2 #單粒子最優加速常數 C2 = 2 #全局最優加速常數 W = 0.5 #慣性因子 Gbest = np.inf #全局最優 History = np.inf*np.ones(iter_max) #歷史最優值記錄#定義“粒子”類 class Particle(object):#初始化粒子的所有屬性def __init__(self):self.Position = VarMin + (VarMax-VarMin)*np.random.rand(nVar)self.Velocity = VelMin + (VelMax-VelMin)*np.random.rand(nVar)self.Cost = np.infself.Pbest = self.Positionself.Cbest = np.inf#根據當前位置更新代價值的方法def UpdateCost(self):global Gbestself.Cost = CostFunction(self.Position)if self.Cost < self.Cbest:self.Cbest = self.Costself.Pbest = self.Positionif self.Cost < Gbest:Gbest = self.Cost#根據當前速度和單粒子歷史最優位置、全局最優位置更新粒子速度def UpdateVelocity(self):global Gbestglobal VelMaxglobal VelMinglobal nVarself.Velocity = W*self.Velocity + C1*np.random.rand(1)\*(self.Pbest-self.Position) + C2*np.random.rand(1)\*(Gbest-self.Position)for s in range(nVar):if self.Velocity[s] > VelMax:self.Velocity[s] = VelMaxif self.Velocity[s] < VelMin:self.Velocity[s] = VelMin#更新粒子位置def UpdatePosition(self):global VarMinglobal VarMaxglobal nVarself.Position = self.Position + self.Velocityfor s in range(nVar):if self.Position[s] > VarMax:self.Position[s] = VarMaxif self.Position[s] < VarMin:self.Position[s] = VarMin#初始化粒子群 Group = [] for j in range(nPop):Group.append(Particle())#開始迭代 for iter in range(iter_max):for j in range(nPop):Group[j].UpdateCost()if Group[j].Cost < History[iter]:History[iter] = Group[j].Costfor j in range(nPop):Group[j].UpdateVelocity()Group[j].UpdatePosition()#輸出結果 print(Gbest) for i in range(nPop):if i % 5 == 0:print("這是最后的第i個粒子:",Group[i].Position, Group[i].Cost)y = History.tolist() x = [i for i in range(iter_max)] plt.plot(x,y) plt.show()
總結
- 上一篇: C++实现一个基于mfc的学生信息管理系
- 下一篇: 计算机网络原理之网络层(解疑答惑)