智慧演算法整合測試平臺V0.1實戰開發
theme: channing-cyan highlight: a11y-light
前言
兜兜轉轉了一圈,想要和其他的粒子群演算法做個對比測試,結果發現,木有程式碼,python沒有也就算了,matlab都找不到,找到了還要錢,好傢伙!雖然有一些python的智慧演算法庫,但是要麼就是整合的太多,沒有專門針對PSO的一些變體進行整合,雖然有一個專門搞PSO的庫,但是,那玩意就集成了一個演算法,核心檔案就一個PSO。
所以,既然沒有,那麼我就自己造個輪子先看看,而且真的要吐槽一波,有些論文不給程式碼也就算了,做對比實驗的時候還不給引數,就很迷,還得自己手動調參。而且發現一個很有意思的事情,在論文作者自己提出的演算法裡面,做實驗效果很好,在別人引用對比的時候,連標準PSO都不要一定幹得過,
目前先搞一個最簡單的版本,不過目前是隻有整合到PSO的,而且目前是針對單目標平臺的,多目標的話有PlatEMO,所以基本上不太需要我再寫一個,只是單目標的話我是沒找到合適的,那些論文的作者也沒給程式碼,網上資源也少,不知道是太簡單了還是怕露餡了,毫無開源精神。
版權
鄭重提示:本文版權歸本人所有,任何人不得抄襲,搬運,使用需徵得本人同意!
2022.7.4
日期:2022.7.4
整合演算法
目前的話,這個玩意是集成了PSO的演算法,其中PSO的演算法分為兩大類,一個是基於引數優化的演算法,另一個是多種群策略,本來我還想搞幾個優化拓撲結構的來的,但是一方面是實現的問題,另一方面是論文沒說明白(中文的)英文的要時間,我沒那麼多時間搞這個破玩意,因為自己的演算法還沒做完,我只是想要一個對比測試的東東。
專案結構
基本粒子群演算法SPSO
資料結構
為了後面統一方便管理,也是專門定義了一個數據類。
```python import random from ALGSet.Config.PSO.SPSO import * class SBird(object):
#這個是從1開始的
ID = 1
Y = None
X = None
V = None
PbestY = None
PBestX = None
GBestX = None
GBestY = None
def __init__(self,ID):
self.ID = ID
self.V = [random.random() *(V_max-V_min) + V_min for _ in range(DIM)]
self.X = [random.random() *(X_up-X_down) + X_down for _ in range(DIM)]
def __str__(self):
return "ID:"+str(self.ID)+" -Fintess:%.2e:"%(self.Y)+" -X"+str(self.X)+" -PBestFitness:%.2e"%(self.PbestY)+" -PBestX:"+str(self.PBestX)+\
"\n -GBestFitness:%.2e"%(self.GBestY)+" -GBestX:"+str(self.GBestX)
```
相關配置
配置也是和演算法的名稱對應的,在上面的圖也能夠看出來。
```python
coding=utf-8
相關引數的設定通過配置中心完成
import sys import os sys.path.append(os.path.abspath(os.path.dirname(os.getcwd()))) C1=1.458 C2=1.458 W = 0.72 m = 3 DIM = 10 PopulationSize=30
執行1000次(可以理解為訓練1次這個粒子群要跑一千次)
IterationsNumber = 3000 X_down = -10.0 X_up = 10
V_min = -5.0 V_max = 5
Wmax = 0.9 Wmin = 0.4 def LinearW(iterate): #傳入迭代次數
w = Wmax-(iterate*((Wmax-Wmin)/IterationsNumber))
return w
def Dw(iterate): w = Wmax-((iterate2)*((Wmax-Wmin)/(IterationsNumber2))) return w def Nw(iterate): w = Wmin+(Wmax-Wmin)(((IterationsNumber-iterate)m)/(IterationsNumber*m)) return w ```
實現程式碼
```python
coding=utf-8
這個是最基礎的PSO演算法SPSO演算法
import sys import os
from ALGSet.Alg.PSO.Bird.SBird import SBird
sys.path.append(os.path.abspath(os.path.dirname(os.getcwd()))) from ALGSet.Target.Target import Target from ALGSet.Config.PSO.SPSO import * import random import time class SPso(object):
Population = None
Random = random.random
target = Target()
W = W
def __init__(self):
#為了方便,我們這邊直接先從1開始
self.Population = [SBird(ID) for ID in range(1,PopulationSize+1)]
def ComputeV(self,bird):
#這個方法是用來計算速度滴
NewV=[]
for i in range(DIM):
v = bird.V[i]*self.W + C1*self.Random()*(bird.PBestX[i]-bird.X[i])\
+C2*self.Random()*(bird.GBestX[i]-bird.X[i])
#這裡注意判斷是否超出了範圍
if(v>V_max):
v = V_max
elif(v<V_min):
v = V_min
NewV.append(v)
return NewV
def ComputeX(self,bird:SBird):
NewX = []
NewV = self.ComputeV(bird)
bird.V = NewV
for i in range(DIM):
x = bird.X[i]+NewV[i]
if(x>X_up):
x = X_up
elif(x<X_down):
x = X_down
NewX.append(x)
return NewX
def InitPopulation(self):
#初始化種群
GBestX = [0. for _ in range(DIM)]
Flag = float("inf")
for bird in self.Population:
bird.PBestX = bird.X
bird.Y = self.target.SquareSum(bird.X)
bird.PbestY = bird.Y
if(bird.Y<=Flag):
GBestX = bird.X
Flag = bird.Y
#便利了一遍我們得到了全域性最優的種群
for bird in self.Population:
bird.GBestX = GBestX
bird.GBestY = Flag
def Running(self):
#這裡開始進入迭代運算
for iterate in range(1,IterationsNumber+1):
#這個算的GBestX其實始終是在算下一輪的最好的玩意
GBestX = [0. for _ in range(DIM)]
Flag = float("inf")
for bird in self.Population:
x = self.ComputeX(bird)
y = self.target.SquareSum(x)
bird.X = x
bird.Y = y
if(bird.Y<=bird.PbestY):
bird.PBestX=bird.X
bird.PbestY = bird.Y
#個體中的最優一定包含了全域性經歷過的最優值
if(bird.PbestY<=Flag):
GBestX = bird.PBestX
Flag = bird.PbestY
for bird in self.Population:
bird.GBestX = GBestX
bird.GBestY=Flag
if name == 'main':
start = time.time()
sPSO = SPso()
sPSO.InitPopulation()
sPSO.Running()
end = time.time()
print("Y: ",sPSO.Population[0].GBestY)
print("X: ",sPSO.Population[0].GBestX)
print("花費時長:",end-start)
```
目標函式
目標函式的話其實都在Target裡面
目前的話其實還是在做演算法的整合,裡面的很多東西其實壓根沒怎麼架構,不過這個後面改起來很快。現在先把一些演算法塞進去。
```python import math import sys import os sys.path.append(os.path.abspath(os.path.dirname(os.getcwd()))) class Target(object): def SquareSum(self,X): res = 0 for x in X:
res+=x*x
return res
```
引數優化(單種群)PSO系列演算法
我們在這邊其實是集成了三個
LPSO
這個其實就是線性變化權重。
```python """ LPSO:這個玩意其實還只是對W進行優化了 """ import time
from ALGSet.Alg.PSO.SPSO import SPso from ALGSet.Config.PSO.SPSO import * class LPso(SPso):
def Running(self):
# 這裡開始進入迭代運算
for iterate in range(1, IterationsNumber + 1):
# 這個算的GBestX其實始終是在算下一輪的最好的玩意
GBestX = [0. for _ in range(DIM)]
Flag = float("inf")
w = LinearW(iterate)
self.W = w
for bird in self.Population:
x = self.ComputeX(bird)
y = self.target.SquareSum(x)
bird.X = x
bird.Y = y
if (bird.Y <= bird.PbestY):
bird.PBestX = bird.X
bird.PbestY = bird.Y
# 個體中的最優一定包含了全域性經歷過的最優值
if (bird.PbestY <= Flag):
GBestX = bird.PBestX
Flag = bird.PbestY
for bird in self.Population:
bird.GBestX = GBestX
bird.GBestY = Flag
if name == 'main': start = time.time() lPSO = LPso() lPSO.InitPopulation() lPSO.Running() end = time.time()
print("Y: ",lPSO.Population[0].GBestY)
print("X: ",lPSO.Population[0].GBestX)
print("花費時長:",end-start)
```
DPSO
這個其實就是把線性權重變成了這個玩意
```python
def Dw(iterate): w = Wmax-((iterate2)*((Wmax-Wmin)/(IterationsNumber2))) return w ```
程式碼其實就是把剛剛的WLinear變成了Dw
NPSO
同理,w函式變成這個了。
python
def Nw(iterate):
w = Wmin+(Wmax-Wmin)*(((IterationsNumber-iterate)**m)/(IterationsNumber**m))
return w
自適應PSO(VCAPSO)
這個演算法的實現相對複雜一點,其實也不難。 具體資料的話自己感興趣可以去查查,我這裡還沒整理好,就不發了。
引數配置
這個的話也是在Config那個包下面的 ```python
coding=utf-8
相關引數的設定通過配置中心完成
import sys import os sys.path.append(os.path.abspath(os.path.dirname(os.getcwd()))) C1=1.458 C2=1.458
K1 = 0.72 K2 = 0.9
DIM = 10 PopulationSize=30
IterationsNumber = 3000 X_down = -10.0 X_up = 10
V_min = -5.0 V_max = 5
Wmax = 0.9 Wmin = 0.4 ```
核心程式碼
```python """ 這個演算法其實也是關於引數進行了優化的 基於雲自適應演算法進行適應的(什麼叫做雲我也不懂,不過公式給我就好了) """ import math import time import random
from ALGSet.Alg.PSO.SPSO import SPso
from ALGSet.Config.PSO.VCAPSO import *
class VCAPso(SPso):
F_avg = 0.
F_avg1=0.
F_avg2=0.
En = 0.
He = 0.
def InitPopulation(self):
#初始化種群
GBestX = [0. for _ in range(DIM)]
Flag = float("inf")
for bird in self.Population:
bird.PBestX = bird.X
bird.Y = self.target.SquareSum(bird.X)
bird.PbestY = bird.Y
self.F_avg+=bird.Y
if(bird.Y<=Flag):
GBestX = bird.X
Flag = bird.Y
#便利了一遍我們得到了全域性最優的種群
for bird in self.Population:
bird.GBestX = GBestX
bird.GBestY = Flag
self.F_avg/=PopulationSize
self.En = (self.F_avg-Flag)/C1
self.He = self.En/C2
self.En = random.uniform(self.En,self.He)
self.F_avg1,self.F_avg2 = self.__GetAvg2(self.Population)
def ComputeV(self,bird):
#這個方法是用來計算速度滴
NewV=[]
if(bird.Y<=self.F_avg1):
w = K1
elif(bird.Y>=self.F_avg2):
w = K2
else:
w = Wmax-Wmin*(math.exp(-((bird.Y-self.En)**2)/(2*(self.En**2))))
for i in range(DIM):
v = bird.V[i]*w + C1*self.Random()*(bird.PBestX[i]-bird.X[i])\
+C2*self.Random()*(bird.GBestX[i]-bird.X[i])
#這裡注意判斷是否超出了範圍
if(v>V_max):
v = V_max
elif(v<V_min):
v = V_min
NewV.append(v)
return NewV
def __GetAvg2(self,Population):
F_avg1 = 0.
F_avg2 = 0.
F_avg1_index = 0
F_avg2_index = 0
for bird in Population:
if(bird.Y<self.F_avg):
F_avg1_index+=1
F_avg1+=bird.Y
elif(bird.Y>self.F_avg):
F_avg2_index+=1
F_avg2+=bird.Y
if (not F_avg1_index == 0):
F_avg1 /= F_avg1_index
else:
F_avg1 = float("inf")
if (not F_avg2_index == 0):
F_avg2 /= F_avg2_index
else:
F_avg2 = float("inf")
return F_avg1,F_avg2
def Running(self):
# 這裡開始進入迭代運算
for iterate in range(1, IterationsNumber + 1):
# 這個算的GBestX其實始終是在算下一輪的最好的玩意
GBestX = [0. for _ in range(DIM)]
Flag = float("inf")
F_avg = 0.
for bird in self.Population:
x = self.ComputeX(bird)
y = self.target.SquareSum(x)
bird.X = x
bird.Y = y
F_avg += bird.Y
if (bird.Y <= bird.PbestY):
bird.PBestX = bird.X
bird.PbestY = bird.Y
# 個體中的最優一定包含了全域性經歷過的最優值
if (bird.PbestY <= Flag):
GBestX = bird.PBestX
Flag = bird.PbestY
for bird in self.Population:
bird.GBestX = GBestX
bird.GBestY = Flag
self.F_avg = F_avg
self.F_avg /= PopulationSize
self.En = (self.F_avg - Flag) / C1
self.He = self.En / C2
self.En = random.uniform(self.En, self.He)
self.F_avg1, self.F_avg2 = self.__GetAvg2(self.Population)
if name == 'main': start = time.time() vcaPso = VCAPso() vcaPso.InitPopulation() vcaPso.Running() end = time.time()
print("Y: ", vcaPso.Population[0].GBestY)
print("X: ", vcaPso.Population[0].GBestX)
print("花費時長:", end - start)
```
綜合粒子群演算法(CLPSO)
這個演算法是在原來那篇論文裡面提到的,先去復現的時候也是復現了的其實,現在只是單獨提取出來罷了。 值得一提的是,這個玩意其實設計出來主要是應對多峰函式的,收斂也較慢。
```python import math import time
from ALGSet.Target.Target import Target from ALGSet.Config.PSO.CLPSO import * from ALGSet.Alg.PSO.Bird.CLBird import CLBird import random class CLPso(object):
Population = None
Random = random.random
target = Target()
W = 0.
Math = math
def __init__(self):
#為了方便,我們這邊直接先從1開始
self.Population = [CLBird(ID) for ID in range(1,PopulationSize+1)]
def __PCi(self,i,ps):
"""
論文當中的PCi的運算元
:return:
"""
pci = 0.05+0.45*((self.Math.exp(10*(i-1)/(ps-1)))/(self.Math.exp(10)-1))
return pci
def NewComputeV(self, bird):
"""
:param bird:
:param params: 傳入的資料格式為:[[w,c1,c2,c3],[],[],[],[]] 這裡一共是5組共設定100個粒子
:return:
這裡按照ID的順序來呼叫不同的引數
"""
NewV = []
for i in range(DIM):
v = bird.V[i] * self.W
if (self.Random() < self.__PCi((i + 1), PopulationSize)):
pbestfi = bird.Follow.PBestX[i]
else:
pbestfi = bird.PBestX[i]
v = v + C1 * self.Random() * (pbestfi - bird.X[i])
if (v > V_max):
v = V_max
elif (v < V_min):
v = V_min
NewV.append(v)
return NewV
def NewComputeX(self, bird: CLBird):
NewX = []
NewV = self.NewComputeV(bird)
bird.V = NewV
for i in range(DIM):
x = bird.X[i] + NewV[i]
if (x > X_up):
x = X_up
elif (x < X_down):
x = X_down
NewX.append(x)
return NewX
def InitPopulation(self):
#初始化種群,不過是給ENV呼叫的,因為這個裡面有一個CLPSO的思想
GBestX = [0. for _ in range(DIM)]
Flag = float("inf")
for bird in self.Population:
bird.PBestX = bird.X
bird.Y = self.target.SquareSum(bird.X)
bird.PbestY = bird.Y
if(bird.Y<=Flag):
GBestX = bird.X
Flag = bird.Y
#便利了一遍我們得到了全域性最優的種群
self.GBestY = Flag
for bird in self.Population:
bird.GBestX = GBestX
bird.GBestY = Flag
#現在是初始化,所以這個這樣算是沒問題的
self.GBestYLast = Flag
#給每一個粒子找到一個追隨者
self.ChangeBird(bird,self.Population)
def ChangeBird(self,bird,Population):
#這個主要是實現錦標賽法來對粒子的跟蹤物件進行更新
while True:
#被跟蹤的粒子不能和自己一樣,也不能和上一個一樣
a,b = random.sample(range(PopulationSize),2)
a = Population[a];b=Population[b]
follow = a
if(a.PbestY>b.PbestY):
follow = b
if(follow.ID!=bird.ID):
if(bird.Follow):
if(bird.Follow.ID !=follow.ID):
bird.Follow = follow
return
else:
bird.Follow = follow
return
def Running(self):
for iterate in range(1,IterationsNumber+1):
#這個算的GBestX其實始終是在算下一輪的最好的玩意
GBestX = [0. for _ in range(DIM)]
Flag = float("inf")
self.W = LinearW(iterate)
for bird in self.Population:
x = self.NewComputeX(bird)
y = self.target.SquareSum(x)
bird.X = x
bird.Y = y
if(bird.Y<=bird.PbestY):
bird.PBestX=bird.X
bird.PbestY = bird.Y
elif (bird.Y == bird.PbestY):
bird.NoChange += 1
if (bird.NoChange == M_follow):
self.ChangeBird(bird, self.Population)
bird.NoChange = 0
#個體中的最優一定包含了全域性經歷過的最優值
if(bird.PbestY<=Flag):
GBestX = bird.PBestX
Flag = bird.PbestY
for bird in self.Population:
bird.GBestX = GBestX
bird.GBestY=Flag
if name == 'main':
start = time.time()
clPSO = CLPso()
clPSO.InitPopulation()
clPSO.Running()
end = time.time()
print("Y: ",clPSO.Population[0].GBestY)
print("X: ",clPSO.Population[0].GBestX)
print("花費時長:",end-start)
```
多種群演算法
MPSO 演算法
這個演算法就是分三個種群,然後,一個執行LPSO,一個執行SPSO,還一個執行VCAPSO。
這個就是整合三個演算法,然後改了一些速度方程。
python
v = bird.V[i] * w + C1 * self.Random() * (bird.PBestX[i] - bird.X[i]) \
+ C2*self.Random()*(bird.CBestX[i]-bird.X[i])\
+C3*self.Random()*(self.GBestX[i]-bird.X[i])
HPSO演算法
這個就是混合多種群PSO。也是程式碼很簡單,而且是目前測試效果最好的。
```python import random import time
from ALGSet.Alg.PSO.Bird.Hbird import HBird from ALGSet.Config.PSO.HPSO import * from ALGSet.Target.Target import Target
class HPso():
rand = random.random
miu = miu
target = Target()
def __init__(self):
self.Population = [HBird(ID) for ID in range(1,PopulationSize+1)]
self.Divide()
def Divide(self):
#我們這邊直接通過ID進行分類
CID = 0
for bird in self.Population:
bird.CID=CID
if(bird.ID % ClusterSize==0):
if(CID<=ClusterNumber):
CID+=1
def ComputeV(self,bird):
#這個方法是用來計算速度滴
NewV=[]
for i in range(DIM):
v1 = bird.V[i] * self.W + C1 * self.rand() * (bird.PBestX[i] - bird.X[i]) \
+ C2 * self.rand() * (bird.GBestX[i] - bird.X[i])
v2 = bird.V[i] * self.W + C1 * self.rand() * (bird.PBestX[i] - bird.X[i]) \
+ C2 * self.rand() * (bird.CBestX[i] - bird.X[i])
v = v1*self.miu+(1-self.miu)*v2
if(v>V_max):
v = V_max
elif(v<V_min):
v = V_min
NewV.append(v)
return NewV
def ComputeX(self,bird):
NewX = []
NewV = self.ComputeV(bird)
bird.V = NewV
for i in range(DIM):
x = bird.X[i]+NewV[i]
if (x > X_up):
x = X_up
elif (x < X_down):
x = X_down
NewX.append(x)
return NewX
def InitPopulation(self):
#初始化種群
#這個是記錄全域性最優解的
GBestX = [0. for _ in range(DIM)]
Flag = float("inf")
#還有一個是記錄Cluster最優解的
CBest = {}
CFlag = {}
for i in range(ClusterNumber):
CFlag[i]=float("inf")
for bird in self.Population:
bird.PBestX = bird.X
bird.Y = self.target.SquareSum(bird.X)
bird.PbestY = bird.Y
bird.CBestX = bird.X
bird.CBestY = bird.Y
if(bird.Y<=Flag):
GBestX = bird.X
Flag = bird.Y
if(bird.Y<=CFlag.get(bird.CID)):
CBest[bird.CID]=bird.X
CFlag[bird.CID] = bird.Y
#便利了一遍我們得到了全域性最優的種群
for bird in self.Population:
bird.GBestX = GBestX
bird.GBestY = Flag
bird.CBestY=CFlag.get(bird.CID)
bird.CBestX=CBest.get(bird.CID)
def Running(self):
#這裡開始進入迭代運算
for iterate in range(1,IterationsNumber+1):
w = LinearW(iterate)
#這個算的GBestX其實始終是在算下一輪的最好的玩意
GBestX = [0. for _ in range(DIM)]
Flag = float("inf")
CBest = {}
CFlag = {}
for i in range(ClusterNumber):
CFlag[i] = float("inf")
for bird in self.Population:
#更改為線性權重
self.W = w
x = self.ComputeX(bird)
y = self.target.SquareSum(x)
bird.X = x
bird.Y = y
if(bird.Y<=bird.PbestY):
bird.PBestX=bird.X
bird.PbestY = bird.Y
#個體中的最優一定包含了全域性經歷過的最優值
if(bird.PbestY<=Flag):
GBestX = bird.PBestX
Flag = bird.PbestY
if (bird.Y <= CFlag.get(bird.CID)):
CBest[bird.CID] = bird.X
CFlag[bird.CID] = bird.Y
for bird in self.Population:
bird.GBestX = GBestX
bird.GBestY=Flag
bird.CBestY = CFlag.get(bird.CID)
bird.CBestX = CBest.get(bird.CID)
if name == 'main': start = time.time() hPso = HPso() hPso.InitPopulation() hPso.Running() end = time.time()
print("Y: ", hPso.Population[0].GBestY)
print("X: ", hPso.Population[0].GBestX)
print("花費時長:", end - start)
```
後續工作
搞視覺化測試,後面,不過,這個要後面在做,程式碼後面上傳。 - 我正在參與掘金技術社群創作者簽約計劃招募活動,點選連結報名投稿。
- 還在調API寫所謂的AI“女友”,嘮了嘮了,教你基於python咱們“new”一個(深度學習)
- Java前後端分離實戰Auto2.0使用者登入註冊--基本的使用者登入 郵箱驗證
- 卡爾曼濾波器(目標跟蹤一)(上)
- 手把手教你如何自制目標檢測框架(從理論到實現)
- 基於Python深度圖生成3D點雲
- Pandas基礎使用(機器學習基礎)
- CEC2017基礎函式說明Python版本
- 全國空氣質量爬取實戰
- 智慧演算法整合測試平臺V0.1實戰開發
- DDPG神經網路實戰(基於強化學習優化粒子群演算法)
- 關於強化學習優化粒子群演算法的論文解讀(全)
- 關於強化學習優化粒子群演算法的論文解讀(上)
- 基於多種群機制的PSO演算法(優化與探索三 *混合種群思想優化多種群與廣義PSO求解JSP)
- 基於多種群機制的PSO演算法Python實現(優化與探索二)
- 基於多種群機制的PSO演算法Python實現
- 520桌面手勢告白
- 嘿~瞎話一下,為啥要用Sigmoid?!