粒子羣算法(PSO)數學原理
一種啓發式的優化方法,具體的例子就是:在一片區域內只有一塊食物(極值),所有的鳥都不知道食物在哪裏(初始化的粒子),但是它們能夠感受到當前的位置距離食物多遠(根據當前的最優值進行優化)。數學化的算法原理:初始化一組隨機粒子,每一次迭代的粒子通過跟蹤兩個極值進行更新自己,這兩個極值是關鍵,一個是根據自身找到的最優解,另一個是整個種羣目前找到的最優值。
下面展開具體分析:
假設在第一個D維目標搜索空間中(D元函數),有N個粒子組成一個羣落,其中第i個粒子是一個N維向量:
每一個粒子都有自己的速度,也是一個N維向量:
對於每一個粒子自身而言的那個極值,就是迄今爲止搜索到的最優位置爲個體極值,記爲:
而對於全局而言,整個粒子羣迄今爲止搜索到的最優位置爲全局極值,記爲:
找到這兩個最優值之後就是更新自己的速度和位置:
其中c1和c2是學習因子,也就是加速常數,r1和r2是隨機數,這個式子的第一部分是慣性,表示粒子原本1維持的速度,第二部分是認知部分,反映歷史經驗的記憶,第三部分是社會部分,反映粒子之間的合作經驗。
下面對一個函數進行優化,作爲一個應用實例:
需要優化的目標函數是:
#define the optimal function
#feed the array return the result
def target(nparray):
return nparray[0]**2 + nparray[1]**2 + nparray[2]**2
N = 30 #amount of the partical
D = 3 #dimension of the result function
M = 1000 #iterations
c1 = 0.5
c2 = 0.5 #acceleration constant
w = 0.6 #inertia factor
import random
import numpy as np
X=np.zeros((N,D))
Y=np.zeros((N,D))
V=np.zeros((N,D))
#init the X(pos) and V(velocity)
for i in range(N):
for j in range(D):
X[i][j]=random.random()
V[i][j]=random.random()
#init the optimal pos of each partical
P = np.zeros(N)
for i in range(N):
P[i]=target(X[i])
Y[i]=X[i]
#init the optimal pos of the whole partical
pg = X[0]
for i in range(1,N):
if float(target(X[i]))<float(target(pg)):
pg=X[i]
# the main loop
for j in range(M):
for i in range(N):
V[i]=w*V[i]+c1*random.random()*(Y[i]-X[i])+c2*random.random()*(pg-X[i])
X[i]=X[i]+V[i]
if target(X[i])<P[i]:
P[i]=target(X[i])
Y[i]=X[i]
if P[i]<target(pg):
pg=Y[i]
print(pg)
print(target(pg))
[-5.58919468e-113 -1.24070745e-113 -7.58949018e-113]
9.03788133030397e-225
[Finished in 2.8s]