天牛须算法BAS
一.算法介绍
天牛须搜索(Beetle Antennae Search-BAS),也叫甲壳虫须搜索,是一种高效的智能优化算法。相比于粒子群算法,天牛须搜索只只要一个个体,即一个天牛,运算量大大降低。
初始化
对一个n
维空间的优化问题,用xl
表示左须坐标,xr
表示右须坐标,x
表示质心坐标,d0
表示两须之间的距离。
用一个随机向量dir=rands(n,1)
,对此归一化:dir=dir/norm(dir)
表示朝向,左须位置xl=x+d0*dir/2
,右须位置xr=x-d0*dir/2
。
比较左右两须的的损失率大小:loss(xl)
,loss(xr)
,更新本体位置:x=x-step*dir*sign(loss(xl) - loss(xr))
。
(注:其中normal是归一化函数)
循环迭代:
迭代判断既可以指定迭代次数也可指定精度:
dir=rands(n,1)
,dir=dir/norm(dir)
更新本体的方向
xl=x+d0*dir/2
,xr=x-d0*dir/2
;更新左右须的坐标
x=x-step*dir*sign(loss(xl) - loss(xr))
更新本体位置
step = step*eta
步长优化
关于步长:
- 每步迭代中采用
step=eta*step
,其中eta在0,1之间靠近1,通常可取eta=0.95(这让我想起了模拟退火的温度) - 引入新变量
temp
和最终分辨率step0
,temp=eta*temp
,step=temp+step0
. - 初始步长可以尽可能大,最好与自变量最大长度相当。
二.代码
import numpy as np
from math import sqrt
def normalize(x): # 单位化向量
return x / sqrt(sum(e ** 2 for e in x))
def sign(a): # 符号函数
if a > 0:
return 1
elif a < 0:
return -1
else:
return 0
# 应用不同问题时主要改这里的参数和函数
eta = 0.95 # 步长调整比例
step = 100 # 初始搜索步长
d0 = 5 # 触须间距
k = 2 # 变量维数
x = np.random.rand(k) # 随机生成天牛质心坐标
xl = x # 左触须坐标
xr = x # 右触须坐标
ex = 1e-15 # 精度
def loss(input): # 计算损失函数,越小越准确
goal = [8.63, 5.11]
return sqrt(pow(input[0] - goal[0], 2) + pow(input[1] - goal[1], 2))
###
while loss(x) > ex: # 开始迭代
dir = normalize(np.random.rand(k))
xl = x + d0 * dir / 2
xr = x - d0 * dir / 2
x = x - step * dir * sign(loss(xl) - loss(xr))
step *= eta
print(x)