├── README.md ├── function.py ├── test.py └── test1.py /README.md: -------------------------------------------------------------------------------- 1 | # SSA_python 2 | 麻雀搜索算法(Sparrow Search Algorithm, SSA)是一种新型的群智能优化算法,在2020年提出,主要是受麻雀的觅食行为和反捕食行为的启发 3 | 本项目感谢东南大学博士生呆呆学长所提供的帮助 4 | -------------------------------------------------------------------------------- /function.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | class funtion(): 3 | def __init__(self): 4 | print("starting SSA") 5 | def Parameters(F): 6 | if F=='F1': 7 | # ParaValue=[-100,100,30] [-100,100]代表初始范围,30代表dim维度 8 | ParaValue = [-100,100,30] 9 | 10 | elif F=='F2': 11 | ParaValue = [-10, 10, 30] 12 | 13 | elif F=='F3': 14 | ParaValue = [-100, 100, 30] 15 | 16 | elif F=='F4': 17 | ParaValue = [-100, 100, 30] 18 | 19 | elif F=='F5': 20 | ParaValue = [-30, 30, 30] 21 | 22 | elif F=='F6': 23 | ParaValue = [-100,100,30] 24 | return ParaValue 25 | # 标准测试函数采用单峰测试函数(Dim = 30),计算适应度 26 | def fun(F,X): # F代表函数名,X代表数据列表 27 | if F == 'F1': 28 | O = np.sum(X*X) 29 | 30 | elif F == 'F2': 31 | O = np.sum(np.abs(X))+np.prod(np.abs(X)) 32 | 33 | elif F == 'F3': 34 | O = 0 35 | for i in range(len(X)): 36 | O = O+np.square(np.sum(X[0:i+1])) 37 | 38 | 39 | elif F == 'F4': 40 | O = np.max(np.abs(X)) 41 | 42 | elif F=='F5': 43 | X_len = len(X) 44 | 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)) 45 | 46 | elif F == 'F6': 47 | O = np.sum(np.square(np.abs(X+0.5))) 48 | return O 49 | 50 | 51 | # 对超过边界的变量进行去除 52 | def Bounds(s,Lb,Ub): 53 | temp = s 54 | for i in range(len(s)): 55 | if temp[i]Ub[0,i]: 58 | temp[i]=Ub[0,i] 59 | 60 | return temp 61 | 62 | # pop是种群,M是迭代次数,f是用来计算适应度的函数 63 | # pNum是生产者 64 | def SSA(pop,M,c,d,dim,f): 65 | #global fit 66 | P_percent=0.2 67 | pNum = round(pop*P_percent) # 生产者的人口规模占总人口规模的20% 68 | lb = c*np.ones((1,dim)) # 生成1*dim的全1矩阵,并全乘以c;lb是下限 69 | ub = d*np.ones((1,dim)) # ub是上限 70 | X = np.zeros((pop,dim)) # 生成pop*dim的全0矩阵,代表麻雀位置 71 | fit = np.zeros((pop,1)) # 适应度值初始化 72 | 73 | for i in range(pop): 74 | X[i,:] = lb+(ub-lb)*np.random.rand(1,dim) # 麻雀属性随机初始化初始值 75 | fit[i,0] = fun(f,X[i,:]) # 初始化最佳适应度值 76 | 77 | 78 | pFit = fit #最佳适应度矩阵 79 | pX = X # 最佳种群位置 80 | fMin = np.min(fit[:,0]) # fMin表示全局最优适应值,生产者能量储备水平取决于对个人适应度值的评估 81 | bestI = np.argmin(fit[:,0]) 82 | bestX = X[bestI,:] # bestX表示fMin对应的全局最优位置的变量信息 83 | Convergence_curve = np.zeros((1,M)) # 初始化收敛曲线 84 | for t in range(M): # 迭代更新 85 | sortIndex = np.argsort(pFit.T) # 对麻雀的适应度值进行排序,并取出下标 86 | fmax = np.max(pFit[:,0]) # 取出最大的适应度值 87 | B = np.argmax(pFit[:,0]) # 取出最大的适应度值得下标 88 | worse = X[B,:] # 最差适应度 89 | 90 | r2 = np.random.rand(1) # 预警值 91 | # 这一部位为发现者(探索者)的位置更新 92 | if r2 < 0.8: # 预警值较小,说明没有捕食者出现 93 | for i in range(pNum): 94 | r1 = np.random.rand(1) 95 | X[sortIndex[0,i],:] = pX[sortIndex[0,i],:]*np.exp(-(i)/(r1*M)) # 对自变量做一个随机变换 96 | X[sortIndex[0,i],:] = Bounds(X[sortIndex[0,i],:],lb,ub) # 对超过边界的变量进行去除 97 | fit[sortIndex[0,i],0] = fun(f,X[sortIndex[0,i],:]) # 算新的适应度值 98 | elif r2 >= 0.8: # 预警值较大,说明有捕食者出现威胁到了种群的安全,需要去其它地方觅食 99 | for i in range(pNum): 100 | Q = np.random.rand(1) # 也可以替换成 np.random.normal(loc=0, scale=1.0, size=1) 101 | X[sortIndex[0,i],:] = pX[sortIndex[0,i],:]+Q*np.ones((1,dim)) # Q是服从正态分布的随机数。L表示一个1×d的矩阵 102 | X[sortIndex[0,i],:] = Bounds(X[sortIndex[0,i],:],lb,ub) 103 | fit[sortIndex[0,i],0] = fun(f,X[sortIndex[0,i],:]) 104 | bestII = np.argmin(fit[:,0]) 105 | bestXX = X[bestII,:] 106 | 107 | 108 | # 这一部位为加入者(追随者)的位置更新 109 | for ii in range(pop-pNum): 110 | i = ii+pNum 111 | A = np.floor(np.random.rand(1,dim)*2)*2-1 112 | if i > pop/2: # 这个代表这部分麻雀处于十分饥饿的状态(因为它们的能量很低,也就是适应度值很差),需要到其它地方觅食 113 | Q = np.random.rand(1) # 也可以替换成 np.random.normal(loc=0, scale=1.0, size=1) 114 | X[sortIndex[0,i],:] = Q*np.exp(worse-pX[sortIndex[0,i],:]/np.square(i)) 115 | else: # 这一部分追随者是围绕最好的发现者周围进行觅食,其间也有可能发生食物的争夺,使其自己变成生产者 116 | 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)) 117 | X[sortIndex[0,i],:] = Bounds(X[sortIndex[0,i],:],lb,ub) 118 | fit[sortIndex[0,i],0] = fun(f,X[sortIndex[0,i],:]) 119 | 120 | # 这一部位为意识到危险(注意这里只是意识到了危险,不代表出现了真正的捕食者)的麻雀的位置更新 121 | # np.arange()函数返回一个有终点和起点的固定步长的排列,如[1,2,3,4,5],起点是1,终点是5,步长为1。 122 | # 一个参数时,参数值为终点,起点取默认值0,步长取默认值1 123 | arrc = np.arange(len(sortIndex[0,:])) 124 | #c=np.random.shuffle(arrc) 125 | # 这个的作用是在种群中随机产生其位置(也就是这部分的麻雀位置一开始是随机的,意识到危险了要进行位置移动, 126 | # 处于种群外围的麻雀向安全区域靠拢,处在种群中心的麻雀则随机行走以靠近别的麻雀) 127 | c = np.random.permutation(arrc) # 随机排列序列 128 | b = sortIndex[0,c[0:20]] 129 | for j in range(len(b)): 130 | if pFit[sortIndex[0,b[j]],0] > fMin: 131 | X[sortIndex[0,b[j]],:] = bestX+np.random.rand(1,dim)*np.abs(pX[sortIndex[0,b[j]],:]-bestX) 132 | else: 133 | 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)) 134 | X[sortIndex[0,b[j]],:] = Bounds(X[sortIndex[0,b[j]],:],lb,ub) 135 | fit[sortIndex[0,b[j]],0] = fun(f,X[sortIndex[0,b[j]]]) 136 | for i in range(pop): 137 | 138 | if fit[i,0] < pFit[i,0]: 139 | pFit[i,0] = fit[i,0] 140 | pX[i,:] = X[i,:] 141 | if pFit[i,0] < fMin: 142 | fMin = pFit[i,0] 143 | bestX = pX[i,:] 144 | Convergence_curve[0,t] = fMin 145 | #print(fMin) 146 | #print(bestX) 147 | return fMin,bestX,Convergence_curve 148 | 149 | 150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import function as fun 3 | import sys 4 | import matplotlib.pyplot as plt 5 | def main(argv): 6 | SearchAgents_no=50 # 麻雀数量初始化 7 | Function_name='F4' # 标准测试函数 8 | Max_iteration=1000 # 最大迭代次数 9 | [lb,ub,dim]=fun.Parameters(Function_name) # 选择单峰测试函数为Function_name 10 | [fMin,bestX,SSA_curve]=fun.SSA(SearchAgents_no,Max_iteration,lb,ub,dim,Function_name) 11 | print(['最优值为:',fMin]) 12 | print(['最优变量为:',bestX]) 13 | thr1=np.arange(len(SSA_curve[0,:])) 14 | 15 | plt.plot(thr1, SSA_curve[0,:]) 16 | 17 | plt.xlabel('num') 18 | plt.ylabel('object value') 19 | plt.title('line') 20 | plt.show() 21 | if __name__=='__main__': 22 | main(sys.argv) 23 | -------------------------------------------------------------------------------- /test1.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import function as fun 3 | import sys 4 | import matplotlib.pyplot as plt 5 | def main(argv): 6 | SearchAgents_no=100 7 | Function_name='F1' 8 | Max_iteration=1000 9 | [lb,ub,dim]=fun.Parameters(Function_name) 10 | [fMin,bestX,SSA_curve]=fun.SSA(SearchAgents_no,Max_iteration,lb,ub,dim,Function_name) 11 | print(['最优值为:',fMin]) 12 | print(['最优变量为:',bestX]) 13 | thr1=np.arange(len(SSA_curve[0,:])) 14 | 15 | plt.plot(thr1, SSA_curve[0,:]) 16 | 17 | plt.xlabel('num') 18 | plt.ylabel('object value') 19 | plt.title('line') 20 | plt.show() 21 | if __name__=='__main__': 22 | main(sys.argv) 23 | 24 | 25 | --------------------------------------------------------------------------------