Python实现人工蜂群算法的示例代码
作者:微小冷
算法简介
ABC,即人工蜂群算法(Artificial Bee Colony Algorithm),由Karaboga等人提出。
在ABC中,有三种不同的蜜蜂,即雇佣蜂、跟随蜂和侦察蜂,这三种蜜蜂的目的都是采蜜,但行为模式并不相同
- 雇佣蜂,一直在采蜜的蜂种,所以与蜜源一一对应。换言之,雇佣蜂的个数,就是蜜源的个数。
- 跟随蜂,依靠雇佣蜂分享情报过活,换言之,雇佣蜂会告诉跟随蜂一些有关蜜源的信息,然后跟随蜂结合自己的理解找蜜。
- 侦察蜂,没有任何蜜源的信息,所以像无头苍蝇一样到处乱找。
接下来就将不同峰种的行为逻辑数学化,首先要初始化蜜源,而从数学上来说,蜜源和雇佣蜂是一回事儿,蜜源在哪、雇佣蜂就在哪;有多少蜜源就有多少雇佣蜂。而蜜蜂的位置,便是待拟合参数,可用向量表示。
其初始化方法就是在搜解范围内设置随机数
x ⃗ i 便是第i只蜜蜂所对应的向量,xij表示第i只蜜蜂的第j维参数。N为蜜源数,即雇佣蜂的个数,也意味着参与竞争的解的个数。
则雇佣蜂的更新方法为
其中,j,k均为随机整数,但k≠j,rij为(−1,1)区间内的随机数。
记跟随蜂的个数为Ns,则其选择第i个蜜源的概率为
如果经过多次循环之后并未得到改善,则雇佣蜂变为侦察蜂,其位置变动为
蜂群的Python实现
首先,要把蜜源表述成一组解。由于在蜂群算法中,蜜源可能会被抛弃,而抛弃的原因则是这个蜜源很长时间没有产生更优秀的解,所以,在描述蜜源的时候,除了一组解之外,还要有一个参数表示这个解多久没有更新了。
所以,用一个二元组表示蜜源中的单个解,即[xs, n],其中,xs为当前最优解,n表示这个解未更新的次数。
而生成蜜源的方法则是
import numpy as np uniform = np.random.uniform srcs = [[uniform(xL, xR), 0] for _ in range(nSrc)]
其中,xL和xR为蜜源位置的最大值和最小值,nSrc为蜜源个数,蜜源个数,也就意味着雇佣蜂的个数。
接下来考虑三种蜜蜂的更新方法,首先考虑雇佣蜂的更新方式
def genX(srcs, index): xs = srcs[index][0] diff = np.delete(np.arange(len(srcs)), index) index = rand.choice(diff) xTest = srcs[index][0] d = randint(0, len(xs) - 1) # 更改的数据维度 r = uniform(-1, 1) # 随机因子 xNew = np.copy(xs) xNew[d] = xs[d] + r * (xs[d] - xTest[d]) return xNew def leadStep(srcs, func, i): food = srcs[i] xNew = genX(srcs, i) if func(xNew) < func(food[0]): srcs[i] = [xNew, 0] else: food[1] += 1
其中,func为优化函数,srcs为所有蜜源,genX实现的是下面这个逻辑
接下来实现跟随蜂,其行为模式与雇佣蜂高度相似,最大的区别是在交换信息的时候不用排除自身,因为所有的信息都在雇佣蜂那里。
def followStep(srcs, func): indRange = range(len(srcs)) fs = [func(food[0]) for food in srcs] ps = np.array(fs)/np.sum(fs) index = rand.choices(indRange, ps)[0] food = srcs[index] xNew = genX(srcs, index) if func(xNew) < func(food[0]): srcs[index] = [xNew, 0] else: food[1] += 1
最后是侦察蜂,其行为最容易实现
def spyStep(srcs, maxTrial, xL, xR, i): if srcs[i][1] > maxTrial: srcs[i] = [uniform(xL, xR), 0]
最后,写一下ABC算法的主流程,ABC算法就算实现了
def ABC(func, nIter, xL, xR, nPop, perEm=0.5, maxTrial=50): nSrc = round(nPop * perEm) # 雇佣/跟随蜂数 nSpy = nPop - nSrc # 侦察蜂数 xL, xR = np.array(xL), np.array(xR) srcs = [[uniform(xL, xR), 0] for _ in range(nSrc)] for _ in range(nIter): for i in range(nSrc): leadStep(srcs, func, i) spyStep(srcs, maxTrial, xL, xR, i) for i in range(nSpy): followStep(srcs, func) best = np.argmax([func(food[0]) for food in srcs]) xs = srcs[best][0] msg = "当前参数:" + ",".join([f"{x:.5f}" for x in xs]) msg += f"\n 最佳值{test(xs)}" print(msg) return srcs[best][0]
测试
又到了激动人心的测试环节,函数还是用各种三角函数组成的坑坑洼洼的高维函数
def test(xs): _sum = 0.0 for i in range(len(xs)): _sum = _sum + np.cos((xs[i]*i)/5)*(i+1) return _sum def main(): xL=np.full(5,-20) xR=np.full(5,20) ABC(test, 49, xL, xR, 30) if __name__ == '__main__': main()
结果为
>python ab_c.py
当前参数:-9.75841,15.18612,-7.31309,-5.40571,43.79218
最佳值-12.342115673734227
以上就是Python实现人工蜂群算法的示例代码的详细内容,更多关于Python人工蜂群算法的资料请关注脚本之家其它相关文章!