人工蜂群算法代码实现 python

首先声明,本代码参考了https://www.cnblogs.com/biaoyu/p/4857904.html,但它的实现逻辑上有些bug,我对其进行了完善和简化,并加了注释,理解起来很简单,效果也更好。

代码基于python2.7,python 3上应该也可以运行,不过没测试。

import numpy as np
import random, math, copy
import matplotlib.pyplot as plt

def GrieFunc(data):             #目标函数
    s1 = 0.
    s2 = 1.
    for k, x in enumerate(data):
        s1 = s1 + x ** 2
        s2 = s2 * math.cos(x / math.sqrt(k+1))
    y = (1. / 4000.) * s1 - s2 + 1
    return  1. / (1. + y)

class ABSIndividual:
    def __init__(self,  bound):
        self.score = 0.
        self.invalidCount = 0                      #无效次数(成绩没有更新的累积次数)
        self.chrom = [random.uniform(a,b) for a,b in zip(bound[0,:],bound[1,:])]   #随机初始化

        self.calculateFitness()        

    def calculateFitness(self):
        self.score = GrieFunc(self.chrom)          #计算当前成绩
        
class ArtificialBeeSwarm:
    def __init__(self, foodCount, onlookerCount, bound, maxIterCount=1000, maxInvalidCount=200):
        self.foodCount = foodCount                  #蜜源个数,等同于雇佣蜂数目
        self.onlookerCount = onlookerCount          #观察蜂个数 
        self.bound = bound                          #各参数上下界
        self.maxIterCount = maxIterCount            #迭代次数
        self.maxInvalidCount = maxInvalidCount      #最大无效次数
        self.foodList = [ABSIndividual(self.bound) for k in range(self.foodCount)]   #初始化各蜜源
        self.foodScore = [d.score for d in self.foodList]                             #各蜜源最佳成绩
        self.bestFood = self.foodList[np.argmax(self.foodScore)]                      #全局最佳蜜源

    def updateFood(self, i):                                                  #更新第i个蜜源
        k = random.randint(0, self.bound.shape[1] - 1)                         #随机选择调整参数的维度
        j = random.choice([d for d in range(self.bound.shape[1]) if d !=i])   #随机选择另一蜜源作参考,j是其索引号
        vi = copy.deepcopy(self.foodList[i])
        vi.chrom[k] += random.uniform(-1.0, 1.0) * (vi.chrom[k] - self.foodList[j].chrom[k]) #调整参数
        vi.chrom[k] = np.clip(vi.chrom[k], self.bound[0, k], self.bound[1, k])               #参数不能越界
        vi.calculateFitness()
        if vi.score > self.foodList[i].score:           #如果成绩比当前蜜源好
            self.foodList[i] = vi
            if vi.score > self.foodScore[i]:            #如果成绩比历史成绩好(如重新初始化,当前成绩可能低于历史成绩)
                self.foodScore[i] = vi.score
                if vi.score > self.bestFood.score:      #如果成绩全局最优
                    self.bestFood = vi
            self.foodList[i].invalidCount = 0
        else:
            self.foodList[i].invalidCount += 1
            
    def employedBeePhase(self):
        for i in xrange(0, self.foodCount):              #各蜜源依次更新
            self.updateFood(i)            

    def onlookerBeePhase(self):
        foodScore = [d.score for d in self.foodList]  
        maxScore = np.max(foodScore)        
        accuFitness = [(0.9*d/maxScore+0.1, k) for k,d in enumerate(foodScore)]        #得到各蜜源的 相对分数和索引号
        for k in xrange(0, self.onlookerCount):
            i = random.choice([d[1] for d in accuFitness if d[0] >= random.random()])  #随机从相对分数大于随机门限的蜜源中选择跟随
            self.updateFood(i)

    def scoutBeePhase(self):
        for i in xrange(0, self.foodCount):
            if self.foodList[i].invalidCount > self.maxInvalidCount:                    #如果该蜜源没有更新的次数超过指定门限,则重新初始化
                self.foodList[i] = ABSIndividual(self.bound)
                self.foodScore[i] = max(self.foodScore[i], self.foodList[i].score)

    def solve(self):
        trace = []
        trace.append((self.bestFood.score, np.mean(self.foodScore)))
        for k in range(self.maxIterCount):
            self.employedBeePhase()
            self.onlookerBeePhase()
            self.scoutBeePhase()
            trace.append((self.bestFood.score, np.mean(self.foodScore)))
        print(self.bestFood.score)
        self.printResult(np.array(trace))

    def printResult(self, trace):
        x = np.arange(0, trace.shape[0])
        plt.plot(x, [(1-d)/d for d in trace[:, 0]], 'r', label='optimal value')
        plt.plot(x, [(1-d)/d for d in trace[:, 1]], 'g', label='average value')
        plt.xlabel("Iteration")
        plt.ylabel("function value")
        plt.title("Artificial Bee Swarm algorithm for function optimization")
        plt.legend()
        plt.show()

if __name__ == "__main__":
    random.seed()
    vardim = 25
    bound = np.tile([[-600], [600]], vardim)
    abs = ArtificialBeeSwarm(30, 30, bound, 1000, 200)
    abs.solve()

 

下面是收敛曲线:

  • 2
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值