項目背景:
有個大學同學根據導師的要求,想在車道線識别中加入麻雀搜尋算法,求我幫做,項目結果要求不高,隻是要在車道線檢測中加入該算法。我大緻分析了一下,當時我的思路是,使用麻雀算法對捕捉到的每一幀圖像進行自适應灰階化或者自适應圖像增強,然後結合opencv的圖像處理知識進行車道線識别。後查閱資料發現,該算法比較新,是2020年才提出的優化算法,可參考資料比較少而且大部分收費,是以,僅僅是實作了車道檢測和算法的相關驗證,二者并沒有很好的融合,是以項目并沒有完成。不過還是想分享一下自己的研究成果。
麻雀算法的python代碼function.py:
import numpy as np
class funtion():
def __init__(self):
print("starting SSA")
def Parameters(F):
if F=='F1':
# ParaValue=[-100,100,30] [-100,100]代表初始範圍,30代表dim次元
ParaValue = [-100,100,30]
elif F=='F2':
ParaValue = [-10, 10, 30]
elif F=='F3':
ParaValue = [-100, 100, 30]
elif F=='F4':
ParaValue = [-100, 100, 30]
elif F=='F5':
ParaValue = [-30, 30, 30]
elif F=='F6':
ParaValue = [-100,100,30]
return ParaValue
# 标準測試函數采用單峰測試函數(Dim = 30),計算适應度
def fun(F,X): # F代表函數名,X代表資料清單
#print('F的值為:',F,'X的值是:',X)
if F == 'F1':
O = np.sum(X*X)
elif F == 'F2':
O = np.sum(np.abs(X))+np.prod(np.abs(X))
elif F == 'F3':
O = 0
for i in range(len(X)):
O = O+np.square(np.sum(X[0:i+1]))
elif F == 'F4':
O = np.max(np.abs(X))
elif F=='F5':
X_len = len(X)
O = np.sum(100 * np.square(X[1:X_len] - np.square(X[0:X_len - 1]))) + np.sum(np.square(X[0:X_len - 1] - 1))
elif F == 'F6':
O = np.sum(np.square(np.abs(X+0.5)))
return O
# 對超過邊界的變量進行去除
def Bounds(s,Lb,Ub):
temp = s
for i in range(len(s)):
if temp[i]<Lb[0,i]:
temp[i]=Lb[0,i]
elif temp[i]>Ub[0,i]:
temp[i]=Ub[0,i]
return temp
# pop是種群,M是疊代次數,f是用來計算适應度的函數
# pNum是生産者
def SSA(pop,M,c,d,dim,f):
#global fit
P_percent=0.2
pNum = round(pop*P_percent) # 生産者的人口規模占總人口規模的20%
lb = c*np.ones((1,dim)) # 生成1*dim的全1矩陣,并全乘以c;lb是下限
ub = d*np.ones((1,dim)) # ub是上限
X = np.zeros((pop,dim)) # 生成pop*dim的全0矩陣,代表麻雀位置
fit = np.zeros((pop,1)) # 适應度值初始化
for i in range(pop):
X[i,:] = lb+(ub-lb)*np.random.rand(1,dim) # 麻雀屬性随機初始化初始值
fit[i,0] = fun(f,X[i,:]) # 初始化最佳适應度值
pFit = fit #最佳适應度矩陣
pX = X # 最佳種群位置
fMin = np.min(fit[:,0]) # fMin表示全局最優适應值,生産者能量儲備水準取決于對個人适應度值的評估
bestI = np.argmin(fit[:,0])
bestX = X[bestI,:] # bestX表示fMin對應的全局最優位置的變量資訊
Convergence_curve = np.zeros((1,M)) # 初始化收斂曲線
for t in range(M): # 疊代更新
sortIndex = np.argsort(pFit.T) # 對麻雀的适應度值進行排序,并取出下标
fmax = np.max(pFit[:,0]) # 取出最大的适應度值
B = np.argmax(pFit[:,0]) # 取出最大的适應度值得下标
worse = X[B,:] # 最差适應度
r2 = np.random.rand(1) # 預警值
# 這一部位為發現者(探索者)的位置更新
if r2 < 0.8: # 預警值較小,說明沒有捕食者出現
for i in range(pNum):
r1 = np.random.rand(1)
X[sortIndex[0,i],:] = pX[sortIndex[0,i],:]*np.exp(-(i)/(r1*M)) # 對自變量做一個随機變換
X[sortIndex[0,i],:] = Bounds(X[sortIndex[0,i],:],lb,ub) # 對超過邊界的變量進行去除
fit[sortIndex[0,i],0] = fun(f,X[sortIndex[0,i],:]) # 算新的适應度值
elif r2 >= 0.8: # 預警值較大,說明有捕食者出現威脅到了種群的安全,需要去其它地方覓食
for i in range(pNum):
Q = np.random.rand(1) # 也可以替換成 np.random.normal(loc=0, scale=1.0, size=1)
X[sortIndex[0,i],:] = pX[sortIndex[0,i],:]+Q*np.ones((1,dim)) # Q是服從正态分布的随機數。L表示一個1×d的矩陣
X[sortIndex[0,i],:] = Bounds(X[sortIndex[0,i],:],lb,ub)
fit[sortIndex[0,i],0] = fun(f,X[sortIndex[0,i],:])
bestII = np.argmin(fit[:,0])
bestXX = X[bestII,:]
# 這一部位為加入者(追随者)的位置更新
for ii in range(pop-pNum):
i = ii+pNum
A = np.floor(np.random.rand(1,dim)*2)*2-1
if i > pop/2: # 這個代表這部分麻雀處于十分饑餓的狀态(因為它們的能量很低,也就是适應度值很差),需要到其它地方覓食
Q = np.random.rand(1) # 也可以替換成 np.random.normal(loc=0, scale=1.0, size=1)
X[sortIndex[0,i],:] = Q*np.exp(worse-pX[sortIndex[0,i],:]/np.square(i))
else: # 這一部分追随者是圍繞最好的發現者周圍進行覓食,其間也有可能發生食物的争奪,使其自己變成生産者
X[sortIndex[0,i],:] = bestXX+np.dot(np.abs(pX[sortIndex[0,i],:]-bestXX),1/(A.T*np.dot(A,A.T)))*np.ones((1,dim))
X[sortIndex[0,i],:] = Bounds(X[sortIndex[0,i],:],lb,ub)
fit[sortIndex[0,i],0] = fun(f,X[sortIndex[0,i],:])
# 這一部位為意識到危險(注意這裡隻是意識到了危險,不代表出現了真正的捕食者)的麻雀的位置更新
# np.arange()函數傳回一個有終點和起點的固定步長的排列,如[1,2,3,4,5],起點是1,終點是5,步長為1。
# 一個參數時,參數值為終點,起點取預設值0,步長取預設值1
arrc = np.arange(len(sortIndex[0,:]))
#c=np.random.shuffle(arrc)
# 這個的作用是在種群中随機産生其位置(也就是這部分的麻雀位置一開始是随機的,意識到危險了要進行位置移動,
# 處于種群外圍的麻雀向安全區域靠攏,處在種群中心的麻雀則随機行走以靠近别的麻雀)
c = np.random.permutation(arrc) # 随機排列序列
b = sortIndex[0,c[0:20]]
for j in range(len(b)):
if pFit[sortIndex[0,b[j]],0] > fMin:
X[sortIndex[0,b[j]],:] = bestX+np.random.rand(1,dim)*np.abs(pX[sortIndex[0,b[j]],:]-bestX)
else:
X[sortIndex[0,b[j]],:] = pX[sortIndex[0,b[j]],:]+(2*np.random.rand(1)-1)*np.abs(pX[sortIndex[0,b[j]],:]-worse)/(pFit[sortIndex[0,b[j]]]-fmax+10**(-50))
X[sortIndex[0,b[j]],:] = Bounds(X[sortIndex[0,b[j]],:],lb,ub)
fit[sortIndex[0,b[j]],0] = fun(f,X[sortIndex[0,b[j]]])
for i in range(pop):
if fit[i,0] < pFit[i,0]:
pFit[i,0] = fit[i,0]
pX[i,:] = X[i,:]
if pFit[i,0] < fMin:
fMin = pFit[i,0]
bestX = pX[i,:]
Convergence_curve[0,t] = fMin
#print(fMin)
#print(bestX)
return fMin,bestX,Convergence_curve
main.py:
import numpy as np
import function as fun
import sys
import matplotlib.pyplot as plt
def main(argv):
SearchAgents_no=50 # 麻雀數量初始化
Function_name='F4' # 标準測試函數
#Max_iteration=1000 # 最大疊代次數
Max_iteration=100 # 最大疊代次數
[lb,ub,dim]=fun.Parameters(Function_name) # 選擇單峰測試函數為Function_name
[fMin,bestX,SSA_curve]=fun.SSA(SearchAgents_no,Max_iteration,lb,ub,dim,Function_name)
print(['最優值為:',fMin])
print(['最優變量為:',bestX])
thr1=np.arange(len(SSA_curve[0,:]))
plt.plot(thr1, SSA_curve[0,:])
plt.xlabel('num')
plt.ylabel('object value')
plt.title('line')
plt.show()
if __name__=='__main__':
main(sys.argv)
疊代結果:
MATLAB的版本代碼:
代碼内容:
代碼可以去此處下載下傳:matlab_SSA.rar_标準測試函數采用單峰測試函數(Dim=30),計算适應度-網際網路文檔類資源-CSDN下載下傳
運作結果如下: