基于蚁群算法(ACO)的函数寻优代码详解

本文介绍蚁群算法的基本原理及应用,通过求解函数最大值问题,详细解释算法流程与核心算子,展示算法收敛过程。

前言

  蚁群算法与遗传算法一并属于启发式算法,其原理有一定的相似性。
  蚁群算法的仿生原理可以这样举例:在不远处的地上有一块奶糖,这时候你用手放个蚂蚁在地上,在无其他因素影响的情况下,这只蚂蚁会爬到奶糖那边干饭,蚂蚁从你手里出去到奶糖之间走过的路径就是一个解
  这时候问题来了,如果你想知道从自己在的位置到奶糖的最短路径(最优解)是什么,该怎么办?显然光凭那一只蚂蚁太为难人了。于是你会想到,在地上放一大把蚂蚁,这些蚂蚁在无其他因素影响的情况下,应该都会爬过去干饭,这个时候观察一下他们的路径就好了。
  现在又来个问题,怎么去观察哪个路径最短呢。幸亏蚂蚁在觅食的时候会在路上留下信息素(荷尔蒙),当路径很短的时候,路径上的信息素会残留的更多,会吸引其他的蚂蚁也过来走。这样,信息素浓度最高的路径就成了蚂蚁最多的路径,也就是最短路径(最优解)。
  由上可见,蚁群算法是非常适合解决TSP问题(旅行商问题)的。实际上,原始的蚁群算法就是用来解决TSP问题,不过稍加改进之后可以像遗传算法一样解决函数寻优问题。

函数寻优

  问题本身很简单,四个变量x1,x2,x3,x4组成方程y = x1平方+x2平方+x3平方+x4平方,四个变量取值范围都是[1,30],求最大值。

源代码

  代码扒至网络,作为学习资料,并加上了很多注释(原先代码就几句注释,难以快速上手)。

import numpy as np
import matplotlib.pyplot as plt
#每一个个体就是一个蚂蚁
#一个种群就是一个蚁群
 
class ACO:
    def __init__(self, parameters):
        """
        Ant Colony Optimization
        parameter: a list type, like [NGEN, pop_size, var_num_min, var_num_max]
        """
        # 初始化
        self.NGEN = parameters[0]  #迭代的代数
        self.pop_size = parameters[1]  #种群大小
        self.var_num = len(parameters[2])  #变量个数
        self.bound = []  #变量的约束范围
        self.bound.append(parameters[2]) #加入变量约束范围
        self.bound.append(parameters[3]) #加入变量约束范围,加入两个列表,bound成为2维的
 
        self.pop_x = np.zeros((self.pop_size, self.var_num))  # 所有蚂蚁的位置,pop_x是2维的
        self.g_best = np.zeros((1, self.var_num))  # 全局蚂蚁最优的位置,大小等于一个个体
 
        # 初始化第0代初始全局最优解
        temp = -1
        for i in range(self.pop_size):
            for j in range(self.var_num):#对2维列表pop_x做遍历,每一行可以视作一个个体,每个个体里面含一组完整的解
                self.pop_x[i][j] = np.random.uniform(self.bound[0][j], self.bound[1][j])#为每一个个体的每一个解随机生成一个答案
            fit = self.fitness(self.pop_x[i])#为每个个体计算适应度
            if fit > temp:#寻找当前种群的最优个体
                self.g_best = self.pop_x[i]#gbest为最优位置列表更新最大值,即最优个体
                temp = fit#同时刷新最大值的比较标准
 
    def fitness(self, ind_var):
        """
        个体适应值计算,计算每个蚂蚁的适应度,并进一步用来计算蚂蚁个体的信息素
        """
        x1 = ind_var[0]
        x2 = ind_var[1]
        x3 = ind_var[2]
        x4 = ind_var[3]
        y = x1 ** 2 + x2 ** 2 + x3 ** 3 + x4 ** 4
        return y
 
    def update_operator(self, gen, t, t_max):
        """
        更新算子:根据概率更新下一时刻的位置和信息素,挑选最好的位置保存
        gen是当前的代数,t是信息素列表,t_max是当前信息素列表中信息素最大的值
        每个个体都对应一个信息素量,当信息素相对少时该个体便大概率进行行动,迭代次数多了之后个体的优度整体提升
        """
        rou = 0.8   # 信息素挥发系数
        Q = 1       # 信息释放总量,蚂蚁们工作循环一次释放的信息总量
        lamda = 1 / gen #lamda随着代数增加而减小,用于局部搜索
        pi = np.zeros(self.pop_size)#概率表,存储每个个体的转移概率
        for i in range(self.pop_size):#对每一个变量做遍历
            for j in range(self.var_num):
                pi[i] = (t_max - t[i]) / t_max #计算行动概率,信息素越少行动概率越大
                # 更新蚂蚁们位置
                if pi[i] < np.random.uniform(0, 1):#进行局部搜索
                    self.pop_x[i][j] = self.pop_x[i][j] + np.random.uniform(-1, 1) * lamda
                else:#进行全局搜索
                    self.pop_x[i][j] = self.pop_x[i][j] + np.random.uniform(-1, 1) * (
                                s
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值