PSO粒子群演算法的python簡單實現備忘錄

2021-08-06 07:00:10 字數 4417 閱讀 5656

粒子群演算法源於複雜適應系統(complex adaptive system,cas)。cas理論於2023年正式提出,cas中的成員稱為主體。比如研究鳥群系統,每個鳥在這個系統中就稱為主體。主體有適應性,它能夠與環境及其他的主體進行交流,並且根據交流的過程「學習」或「積累經驗」改變自身結構與行為。整個系統的演變或進化包括:新層次的產生(小鳥的出生);分化和多樣性的出現(鳥群中的鳥分成許多小的群);新的主題的出現(鳥尋找食物過程中,不斷發現新的食物)。

我覺得簡單來講,就是有乙個函式,你想求它的最大值或最小值,直接求很難求解,你就只好用迂迴地方法,設定好多點,然後計算對比他們的值,然後不斷迭代,直到找到使得函式得到最大值或最小值的點。

比如我們求取函式

y=1-cos(3*x)*exp(-x)的在[0,4]最大值。並在[0,4]之間放置了兩個隨機的點,這些點的座標假設為x1=1.5; x2=2.5;這裡的點是乙個標量,但是我們經常遇到的問題可能是更一般的情況--x為乙個向量的情況,比如二維的情況 z=2*x1+3*x22的情況。這個時候我們的每個粒子為二維,記粒子p1=(x11,x12),p2=(x21,x22),p3=(x31,x32),......pn=(xn1,xn2)。這裡n為粒子群群體的規模,也就是這個群中粒子的個數,每個粒子的維數為2。更一般的是粒子的維數為q,這樣在這個種群中有n個粒子,每個粒子為q 維。

由n個粒子組成的群體對q維(就是每個粒子的維數)空間進行搜尋。每個粒子表示為:xi=(xi1,xi2,xi3,...,xiq),每個粒子對應的速度可以表示為vi=(vi1,vi2,vi3,....,viq),每個粒子在搜尋時要考慮兩個因素:

1. 自己搜尋到的歷史最優值 pi ,pi=(pi1,pi2,....,piq),i=1,2,3,....,n。

2. 全部粒子搜尋到的最優值pg,pg=(pg1,pg2,....,pgq),注意這裡的pg只有乙個。

"""pso粒子類(本程式只設定了最大迭代輪數,而未設定其他限制條件)

#p:self;粒子數量;搜尋維度(也就是乙個粒子裡有幾個變數);最大迭代次數

"""class pso():

def __init__(self, pn, dim, max_iter):

self.w = 0.8 #保持原來速度的係數,所以叫做慣性權重

self.c1 = 2 #粒子跟蹤自己歷史最優值的權重係數,它表示粒子自身的認識,所以叫「認知」。通常設定為2

self.c2 = 2 #粒子跟蹤群體最優值的權重係數,它表示粒子對整個群體知識的認識,所以叫做「社會知識」,經常叫做「社會」。通常設定為2

self.r1 = 0.6 #[0,1]區間內均勻分布的偽隨機數

self.r2 = 0.3 #[0,1]區間內均勻分布的偽隨機數

self.r3 = 1 #對位置更新的時候,在速度前面加的乙個係數,這個係數我們叫做約束因子。通常設定為1

self.pn = pn #粒子數量

self.dim = dim #搜尋維度

self.max_iter = max_iter #最大迭代次數

self.x = np.zeros((self.pn, self.dim)) #所有粒子的位置

self.v = np.zeros((self.pn, self.dim)) #所有粒子的速度

self.pbest = np.zeros((self.pn, self.dim)) #個體經歷的最佳位置

self.gbest = np.zeros((1, self.dim)) #全域性最佳位置

self.p_fit = np.zeros(self.pn) #每個個體的歷史最佳適應值

self.fit = 1e10 #全域性最佳適應值

"""#適應度的計算(對於函式而言,其實就是計算y的值),這個例子用的就是簡單地將其平方再加和

#p:self;粒子數量;粒子的位置資訊

#r:適應度的值

"""def function(self, x):

sum = 0

length = len(x)

x = x ** 2 #將每乙個維度的x值求平方

#對各個維度的平方求加和

for i in range(length):

sum += x[i]

return sum

"""#初始化粒子資訊

#p:self

#r:無;在過程中更新粒子所需的資訊

"""def init_population(self):

#遍歷所有粒子

for i in range(self.pn):

#遍歷所有維度

for j in range(self.dim):

self.x[i][j] = random.uniform(0, 1) #隨機初始化位置資訊

self.v[i][j] = random.uniform(0, 1) #隨機初始化速度資訊

#初始化個體經歷的最佳位置

self.pbest[i] = self.x[i]

#每個個體的歷史最佳適度

tmp = self.function(self.x[i])

self.p_fit[i] = tmp

#對比各個粒子的適應度,選擇最高的作為全域性最優

if (tmp < self.fit):

self.fit = tmp

self.gbest = self.x[i]

"""#演算法主體,計算更新位置資訊、速度資訊和適應度,並給出最終結果

#p:self

#r:最佳適應度(也就是所求的y值)

"""def iterator(self):

fitness = #製作乙個陣列存放每輪的最優值

#在最大迭代數內迭代

for t in range(self.max_iter):

#遍歷粒子數,計算適應度

for i in range(self.pn):

temp = self.function(self.x[i])

#如果所得的適應度比之前得到的個體最優適應度要小,就更新個體最優

if (temp < self.p_fit[i]):

self.p_fit[i] = temp

self.pbest[i] = self.x[i]

#如果更新的個體最優小於全域性最優,那麼就用個體最優更新全域性最優

if (self.p_fit[i] < self.fit): # 更新全域性最優

self.gbest = self.x[i]

self.fit = self.p_fit[i]

#更新完適應度的個體最優和全域性最優後,根據公式更新位置學習和速度學習

for i in range(self.pn):

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.r3*self.v[i]

#將每輪得到的最佳適應度存放在fitness陣列中

print(self.fit) #輸出最優值

return fitness

# ----------------------程式執行-----------------------

my_pso = pso(pn=30, dim=5, max_iter=50)

my_pso.init_population()

fitness = my_pso.iterator()

# -------------------畫圖--------------------

plt.figure(1)

plt.title("figure1")

plt.xlabel("iterators", size=14)

plt.ylabel("fitness", size=14)

t = np.array([t for t in range(0, 50)])

fitness = np.array(fitness)

plt.plot(t, fitness, color='b', linewidth=3)

plt.show()

粒子群(pso)演算法

一 粒子群演算法的概念 粒子群優化演算法 pso particle swarm optimization 是一種進化計算技術 evolutionary computation 源於對鳥群捕食的行為研究。粒子群優化演算法的基本思想 是通過群體中個體之間的協作和資訊共享來尋找最優解 pso的優勢 在於簡...

粒子群演算法 PSO

1995年美國社會心理學家kennedy和電氣工程師eberhart共同提出粒子群優化演算法 particle swarm optimization,pso pso演算法的基本思想利用生物學家heppner的生物群體模型,模擬鳥類覓食過程。鳥類飛行過程相互交流,當乙個鳥飛向棲息地時,其他鳥兒也會跟著...

簡易PSO粒子群演算法(python)

參考csdn上的一些大佬的程式 依葫蘆畫瓢自己編了個玩 coding utf 8 import numpy as np import random import matplotlib.pyplot as plt import math from numpy import pso引數設定 class ...