海鸥优化算法的基础原理¶海鸥优化算法 (Seagull Optimization Algorithm,SOA) 是由 Gaurav Dhiman 等人于 2019 年提出的一种全新的元启发式智能优化算法,它是一种通过模拟海鸥迁徙和肷击行为来求解优化问题的算法。
海鸥是遍布全球的海鸟, 种类繁多且大小和身长各不相同。海鸦是杂食动物, 吃昆虫、 鱼、爬行动物、两栖动物和蚯蚓等。大多数海鸥的身体覆盖着白色的羽毛, 经常用面包屑来吸引鱼群, 用脚发出雨水落下的声音来吸引藏在地下的蚯蚓。海袓可以喝淡水和盐水, 通过眼睛上方的一对特殊腺体, 将盐从它们的体内排出。海鸥以群居方式生活, 利用群体智彗来寻找和攻击猎物。海鸥最重要的特征是迁徙和攻击行为, 迁徙是指动物根据季节更替从一个地方移动到另一个地方, 寻找丰富的食物来源以便获取足够能量。迁徙时每只海鴎的所在位置不同, 以避免相互碰撞。在一个群体中, 海鸥可以朝着最佳位置的方向前进并改变自身所在的位置。海鸥经常会攻击候鸟并在进攻时呈现螺旋形的运动形态。
海鸥迁徙¶在海鸥迁徙过程中, 海鸥优化算法模拟海鸥群体如何从一个位置移动到另一个位置。在这个阶段, 海鸥应该满足避免碰撞这一条件。为了避免与相邻的其他海鸥碰撞, 该算法采用附加变量 $A$ 计算海鸥的新位置, 即
$$
C_{\mathrm{s}}(t)=A \times P_{\mathrm{s}}(t)
$$
其中, $C_{\mathrm{s}}(t)$ 表示不与其他海鸥存在位置冲突的新位置; $P_{\mathrm{s}}(t)$ 为海鸥当前位置; $t$ 表示当前迭 代次数; $A$ 表示海鸥在给定搜索空间中的运动行为, 可表示为
$$
A=f_{\mathrm{c}}-\left(t \times\left(f_{\mathrm{c}} / \mathrm{Max}_{\text {iteration }}\right)\right)
$$
其中, $f_{\mathrm{c}}$ 表示可以控制变量 $A$ 的变化频率, 其值从 2 线性减小到 $0 ; \mathrm{Max}_{\text {iteration }}$ 表示最大迭代 次数; $t$ 表示当前迭代次数。
海鸥在迁徙过程中, 在避免了与其他海鸥的位置重合后, 首先会计算最佳位置的方向, 并向最佳位置移动。
$$
M_{\mathrm{s}}(t)=B \times\left(P_{\mathrm{bs}}(t)-P_{\mathrm{s}}(t)\right)
$$
其中, $M_{\mathrm{s}}(t)$ 表示最佳位置的方向; $P_{\mathrm{bs}}(t)$ 表示当前海鸥最佳位置; $P_{\mathrm{s}}(t)$ 表示海鸥当前位置; $B$ 是平衡全局搜索和局部搜索的随机数, 即
$$
B=2 \times A^2 \times r_{\mathrm{d}}
$$
其中, $r_{\mathrm{d}}$ 为区间 $[0,1]$ 内的随机数。
海鸥在获取最佳位置的方向后, 会向最佳位置移动, 到达新的位置。
$$
D_{\mathrm{s}}(t)=\left|C_{\mathrm{s}}(t)+M_{\mathrm{s}}(t)\right|
$$
其中, $D_{\mathrm{s}}(t)$ 表示海鸧的新位置; $C_{\mathrm{s}}(t)$ 表示不与其他海鸥存在位置冲突的位置; $M_{\mathrm{s}}(t)$ 表示取 佳位置的方向。
海鸥攻击猎物¶海鸥在迁徙过程中可以不断改变攻击角度和速度, 同时用翅膀和重量保持高度。当海鸥攻击猎物时, 它们就在空中进行螺旋运动。将海鸥在 $x, y, z$ 平面中的运动行为描述为
$$
\left\{\begin{array}{l}
x=r \times \cos (\theta) \\
y=r \times \sin (\theta) \\
z=r \times \theta \\
r=u \times \mathrm{e}^{\theta v}
\end{array}\right.
$$
其中, $r$ 是每个螺旋的半径; $\theta$ 为区间 $[0,2 \pi]$ 内的随机角度值; $u$ 和 $v$ 是螺旋形状的相关常数; $\mathrm{e}$ 是自然对数的底数。
当 $u=1, v=0.1, \theta$ 从 0 递增到 $2 \pi$ 时, 以 $x, y, z$ 建立坐标系, 海鸥的运动轨迹如下图所示。
海鸥的运动轨迹¶海鸥攻击猎物后的位置用下式表示。
$$
P_{\mathrm{s}}(t)=D_{\mathrm{s}}(t) \times x \times y \times z+P_{\text {bs }}(t)
$$
其中, $P_{\mathrm{s}}(t)$ 表示海鸥攻击猎物后的位置; $P_{\mathrm{bs}}(t)$ 表示当前海鸥的最佳位置。
$6.1 .3$ 海鸥优化算法流程
海鸥优化算法的流程图如下图所示。
海鸥优化算法步骤如下:
步骤 1:初始化海鸥优化算法的相关参数。
步骤 2: 根据种群数量与边界来初始化种群位置。
步骤 3: 计算适应度值并保留全局最优位置。
步骤 4: 海鸥迁徙。
步骤 5:海鸥攻击猎物。
步骤 6: 判断是否满足算法停止条件, 若满足, 则输出最优位置; 否则重复步骤 3-6。
代码¶import numpy as np
import copy
import numpy as np
from matplotlib import pyplot as plt
def initialization(pop,ub,lb,dim):
''' 种群初始化函数'''
'''
pop:为种群数量
dim:每个个体的维度
ub:每个维度的变量上边界,维度为[dim,1]
lb:为每个维度的变量下边界,维度为[dim,1]
X:为输出的种群,维度[pop,dim]
'''
X = np.zeros([pop,dim]) #声明空间
for i in range(pop):
for j in range(dim):
X[i,j]=(ub[j]-lb[j])*np.random.random()+lb[j] #生成[lb,ub]之间的随机数
return X
def BorderCheck(X,ub,lb,pop,dim):
'''边界检查函数'''
'''
dim:为每个个体数据的维度大小
X:为输入数据,维度为[pop,dim]
ub:为个体数据上边界,维度为[dim,1]
lb:为个体数据下边界,维度为[dim,1]
pop:为种群数量
'''
for i in range(pop):
for j in range(dim):
if X[i,j]>ub[j]:
X[i,j] = ub[j]
elif X[i,j] X[i,j] = lb[j] return X def CaculateFitness(X,fun): '''计算种群的所有个体的适应度值''' pop = X.shape[0] fitness = np.zeros([pop, 1]) for i in range(pop): fitness[i] = fun(X[i, :]) return fitness def SortFitness(Fit): '''适应度值排序''' ''' 输入为适应度值 输出为排序后的适应度值,和索引 ''' fitness = np.sort(Fit, axis=0) index = np.argsort(Fit, axis=0) return fitness,index def SortPosition(X,index): '''根据适应度值对位置进行排序''' Xnew = np.zeros(X.shape) for i in range(X.shape[0]): Xnew[i,:] = X[index[i],:] return Xnew def SOA(pop, dim, lb, ub, MaxIter, fun): '''海鸥优化算法''' ''' 输入: pop:为种群数量 dim:每个个体的维度 ub:为个体上边界信息,维度为[1,dim] lb:为个体下边界信息,维度为[1,dim] fun:为适应度函数接口 MaxIter:为最大迭代次数 输出: GbestScore:最优解对应的适应度值 GbestPositon:最优解 Curve:迭代曲线 ''' fc = 2 #可调 X = initialization(pop,ub,lb,dim) #初始化种群 fitness = CaculateFitness(X,fun) #计算适应度值 fitness,sortIndex = SortFitness(fitness) #对适应度值排序 X = SortPosition(X,sortIndex) #种群排序 GbestScore = copy.copy(fitness[0]) GbestPositon = np.zeros([1,dim]) GbestPositon[0,:] = copy.copy(X[0,:]) Curve = np.zeros([MaxIter,1]) MS = np.zeros([pop,dim]) CS = np.zeros([pop,dim]) DS = np.zeros([pop,dim]) X_new = copy.copy(X) for i in range(MaxIter): print("第"+str(i)+"次迭代") Pbest = X[0,:] for j in range(pop): #计算Cs A = fc - (i*(fc/MaxIter)) CS[j,:]=X[j,:]*A #计算Ms rd=np.random.random() B = 2*(A**2)*rd MS[j,:] = B*(Pbest - X[j,:]) #计算Ds DS[j,:] = np.abs(CS[j,:] + MS[j,:]) #局部搜索 u = 1 v = 1 theta = np.random.random() r = u*np.exp(theta*v) x = r*np.cos(theta*2*np.pi) y = r*np.sin(theta*2*np.pi) z = r*theta #攻击 X_new[j,:] = x*y*z*DS[j,:] + Pbest X = BorderCheck(X_new,ub,lb,pop,dim) #边界检测 fitness = CaculateFitness(X,fun) #计算适应度值 fitness,sortIndex = SortFitness(fitness) #对适应度值排序 X = SortPosition(X,sortIndex) #种群排序 if(fitness[0]<=GbestScore): #更新全局最优 GbestScore = copy.copy(fitness[0]) GbestPositon[0,:] = copy.copy(X[0,:]) Curve[i] = GbestScore return GbestScore, GbestPositon, Curve '''适应度函数''' def fun(X): O=X[0]**2 + X[1]**2 return O '''海鸥优化算法求解x1^2 + x2^2的最小值''' '''主函数 ''' #设置参数 pop = 50 #种群数量 MaxIter = 100 #最大迭代次数 dim = 2 #维度 lb = -10*np.ones(dim) #下边界 ub = 10*np.ones(dim)#上边界 #适应度函数选择 fobj = fun GbestScore,GbestPositon,Curve = SOA(pop,dim,lb,ub,MaxIter,fobj) print('最优适应度值:',GbestScore) print('最优解[x1,x2]:',GbestPositon) #绘制适应度曲线 plt.figure(1) plt.plot(Curve,'r-',linewidth=2) plt.xlabel('Iteration',fontsize='medium') plt.ylabel("Fitness",fontsize='medium') plt.grid() plt.title('SOA',fontsize='large') plt.show() 参考资料: 范旭 编 《Python智能优化算法:从原理到代码实现与应用》