智能算法系列之蚁群算法

2023-10-27

在这里插入图片描述

  本博客封面由ChatGPT + DALL·E 2共同创作而成。

前言

  本篇是智能算法(Python复现)专栏的第五篇文章,主要介绍蚁群算法(Ant Colony Optimization, ACO)的思想,python实现及相关应用场景模拟。

  蚁群优化算法,简称蚁群算法,是一种模拟蚂蚁群体智能行为的随机优化算法,它试图模仿蚂蚁在觅食活动中找到最短路径的过程。

1. 算法思想

  众所周知,蚂蚁是一种群居动物,设想一个蚂蚁觅食的情景,假设蚁巢到食物是一条直线,那么蚂蚁将在这条直线上来回移动搬运食物,如下图所示:

在这里插入图片描述

  如果在蚂蚁的觅食路径上放置一个障碍物,蚂蚁的觅食大队就会一分为二,如下图所示:

在这里插入图片描述
  随着时间的推移,蚁群会在最短的路径上持续进行食物的搬运,而较长的路径将不会有蚂蚁移动,示意图如下:

在这里插入图片描述
  虽然蚂蚁们不具备像人类的视力和智慧,它们无法从远处看到食物源,也无法计划一个合适的路径来搬运食物,但是他们却能够寻找到一条最佳的路线。蚂蚁们采用的方法是全体在周围区域进行地毯式搜索,而它们之间的联系方式是在爬过的路径上分泌化学物质,这种化学物质叫信息素
  大量研究表明,蚂蚁在寻找食物的过程中,会在所经过的路径上释放信息素,当它们碰到一个还没有走过的路口时,会随机地挑选一条路径前行,与此同时释放出与路径长度有关的信息素。路径越长,释放的激素浓度越低。后来的蚂蚁通过感知这种物质以及强度,会倾向于朝信息素浓度高的方向移动,同时移动留下的信息素会对原有的信息素进行加强。
  由于较短路径积累的信息素快、浓度值高,这样经过一段时间后,利用整个群体的自组织就能够发现最短的路径。蚂蚁个体之间就是通过这种间接的通信机制达到协同搜索食物最短路径的目的。

2. 算法流程

  蚁群算法开始随机地选择搜索路径,在寻优过程中通过增强较好解,使搜索过程逐渐变得规律,从而逐渐逼近直至最终达到全局最优解。蚁群算法通过适应阶段和协作阶段这两个阶段进行寻优:
  (1) 在初步的适应阶段,一群人工蚁按照虚拟信息素和启发式信息的指引,在解空间不断地寻求外界信息来构造问题的解,同时它们根据解的质量在其路径上留下相应浓度的信息素;
  (2) 在后期的协作阶段,其他人工蚁选择信息素浓度高的路径前进,同时在这段路径上留下自己的信息素,通过这种正反馈的信息交流机制找到解决问题的高质量的解。
  算法流程图如下:

在这里插入图片描述

3. 细节梳理

  为了避免蚁群算法出现早熟现象,算法利用信息素的挥发实现负反馈机制。但是挥发的强度不能太弱,否则无法防止早熟现象的产生;挥发强度也不能太强,否则将抑制个体间的协作过程。
  信息素的更新公式如下: τ ( t + 1 ) = ( 1 − ρ ) × τ ( t ) + Δ τ ( t ) \tau (t+1) = (1 - \rho) \times \tau (t) + \Delta \tau (t) τ(t+1)=(1ρ)×τ(t)+Δτ(t)  其中, τ \tau τ为信息素, ρ \rho ρ为信息素蒸发系数。

4. 算法实现

4.1 问题场景

  最值问题,求解 f ( x ) = x s i n ( 5 x ) − x c o s ( 2 x ) f(x) = xsin(5x) - xcos(2x) f(x)=xsin(5x)xcos(2x)在定义域[0, 5]上的最小值。我们先手动计算一下:

f ′ ( x ) = 2 x s i n ( 2 x ) + s i n ( 5 x ) − c o s ( 2 x ) + 5 x c o s ( 5 x ) f^\prime (x) = 2 x sin(2 x) + sin(5 x) - cos(2 x) + 5 x cos(5 x) f(x)=2xsin(2x)+sin(5x)cos(2x)+5xcos(5x)  令 f ′ ( x ) = 0 f^\prime (x) = 0 f(x)=0之后,理论上可以求得驻点,但又不太好计算。。。

4.2 代码实现

# -*- coding:utf-8 -*-
# Author:   liyanpeng
# Email:    liyanpeng@tsingmicro.com
# Datetime: 2023/5/6 14:59
# Filename: ant_colony_optimization.py
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

from base_algorithm import BaseAlgorithm


__all__ = ['AntColonyOptimization']


class Ant:
    def __init__(self):
        self.position = None    # 蚂蚁的位置
        self.tau = None         # 蚂蚁的信息素
        self.tran_prob = None   # 状态转移概率


class AntColonyOptimization(BaseAlgorithm):
    def __init__(self, population_size=20, max_iter=200, alpha=1.5, beta=0.8, rho=0.9, q=1.0, p0=0.2, step=0.1, x_range=(0, 5), seed=10086):
        super(AntColonyOptimization, self).__init__()
        self.__population_size = population_size  # 蚂蚁种群大小
        self.__max_iter = max_iter  # 最大迭代次数
        self.__alpha = alpha        # 信息素重要程度因子
        self.__beta = beta          # 启发函数重要程度因子
        self.__rho = rho            # 信息素蒸发系数
        self.__q = q                # 信息素释放增量系数
        self.__p0 = p0              # 转移概率常数
        self.__step = step          # 局部搜索步长
        self.__x_range = x_range    # 变量x的定义域
        self.__population = []      # 蚁群
        self.__best_tau = np.inf
        self.__seed = seed
        self.optimal_solution = None

        np.random.seed(seed)

    def init_population(self):
        for i in range(self.__population_size):
            ant = Ant()
            ant.position = np.random.uniform(*self.__x_range)   # 随机初始化位置
            ant.tau = self.problem_function(ant.position)       # 初始信息素值
            if ant.tau < self.__best_tau:
                self.__best_tau = ant.tau
            self.__population.append(ant)

        for ant in self.__population:
            # 初始蚂蚁的状态转移概率
            ant.tran_prob = (self.__best_tau - ant.tau) / self.__best_tau

    def update_population(self, coef):
        for ant in self.__population:
            if ant.tran_prob < self.__p0:   # 局部搜索
                new_pos = ant.position + (2 * np.random.randn() - 1) * self.__step * coef
            else:                           # 全局搜索
                new_pos = ant.position + (self.__x_range[1] - self.__x_range[0]) * (np.random.randn() - 0.5)
            new_pos = np.clip(new_pos, *self.__x_range)

            if self.problem_function(new_pos) < self.problem_function(ant.position):
                # 更新蚂蚁的位置
                ant.position = new_pos

        for ant in self.__population:
            # 更新蚂蚁的信息素
            ant.tau = (1 - self.__rho) * ant.tau + self.problem_function(ant.position)
            if ant.tau < self.__best_tau:
                self.__best_tau = ant.tau
                self.optimal_solution = (ant.position, self.problem_function(ant.position))

    def solution(self):
        self.init_population()
        for i in range(self.__max_iter):
            coef = 1 / (i+1)
            self.update_population(coef)

        print('the optimal solution is', self.optimal_solution)


if __name__ == '__main__':
    algo = AntColonyOptimization()
    algo.solution()

  得到的最优解如下:

the optimal solution is (3.432996771226036, -6.277079745038137)

代码仓库:IALib[GitHub]

  本篇代码已同步至【智能算法(Python复现)】专栏专属仓库:IALib
  运行IALib库中的ACO算法:

git clone git@github.com:xiayouran/IALib.git
cd examples
python main.py -algo aco
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

智能算法系列之蚁群算法 的相关文章

随机推荐

  • Elasticsearch:替换、更新和删除性能分析

    替换 更新和删除 在使用ES的时候 如果你认真观察了 你会发现 替换 更新和更新都是有蛮大的区别的 虽然说结果是一样的 但是原理还是不同的 这一点一定要明确 一 看一下替换 这个时候替换成功 这个Version是3 再替换一下 这个时候Ve
  • Android音视频 - OpenGL GLSL基础

    上节在绘制三角形的时候 简单讲解了一些着色器 GLSL 的相关概念 可能看的云里雾里的 不要担心 在本节中 我将详细讲解着色语言 GL Shader Language GLSL 的一些基本的概念 PS 无特殊说明 文中的 GLSL 均指 O
  • idea使用笔记

    1 idea service springboot 启动类显示隐藏 隐藏 显示 2 idea导入项目后没有被识别为maven项目的解决办法 如果不行参考 https blog csdn net kt1776133839 article de
  • dart 练习模板自用

    import package flutter material dart main gt runApp const MyApp class MyApp extends StatelessWidget const MyApp super ke
  • QT笔记-QString-string相互转换

    新建头文件 命名为GBK h 内容如下 include
  • linux清空文件内容的三种方法

    1 使用vi vim命令打开文件后 输入 d 清空 后保存即可 但当文件内容较大时 处理较慢 命令如下 vim file name d wq 2 使用cat命令情况 命令如下 推荐 cat dev null gt file name 3 使
  • 【Mysql】取两个查询语句结果的交集

    表结构 订单表 order info id order no price quality 1 PO1001 100 0 10 2 PO1002 200 0 20 3 PO1003 100 0 10 订单扩展表 order ext id or
  • NERFS 与现实捕捉 - 弥合现实世界与数字世界之间的差距

    NERF介绍 近年来 计算机视觉和图形领域取得了显着的进步 催生了革命性的技术 改变了各个行业 NERFS 神经辐射场 和现实捕捉是两项备受关注的重要技术 NERFS 和现实捕捉都是以数字形式捕捉和重建现实世界的强大工具 然而 它们在方法和
  • 考研数二第二讲 数列/函数的极限

    一 数列 无穷多个数按照一定顺序排成一列叫数列 如 二 数列的极限 回到刚才提到的四个数列 我们根据描述性定义 当 n 无限增大时 即 n 可以轻松推出数列 xn 的极限值 实际上我们对描述性定义不算满意 因为它描述说 当 n 无限增大时
  • C#结构体struct和类class的区别与使用场景

    目录 前言 一 结构体的使用 二 结构与类的区别 1 类和结构有以下几个基本的不同点 2 选择使用情况 总结 前言 在我们开发程序中 功能实现可能没有问题 问题是如何将代码变得更优雅 优化程序运行 本文主要区别结构体与类的区别以及什么情况下
  • 算法设计与分析 最长公共子序列(动态规划)Python实现

    问题描述 使用动态规划算法解最长公共子序列问题 具体来说就是 依据其递归式自底向上的方式依次计算得到每个子问题的最优值 输入形式 在屏幕上输入两个序列X和Y 序列各元素数间都以一个空格分隔 输出形式 序列Xi x1 xi 和序列Yj y1
  • Python兼职

    Python能挣到钱吗 靠Python接单月入w假的吧 网上这类话题帖子不少 争议呢也不少 Python能接单挣钱肯定不假 至于能挣多少我说看个人技术 技术到位挣钱不是难事 技术不得行 想靠Python挣钱那就跟你没太大关系 我也是业余自学
  • 选择题_网络

    1 主机甲和乙已建立了TCP连接 甲始终以MSS 1KB大小的段发送数据 并一直有数据发送 乙每收到一个数据段都会发出一个接收窗口为10KB的确认段 若甲在t时刻发生超时时拥塞窗口为8KB 则从t时刻起 不再发生超时的情况下 经过10个RT
  • 制作自己的目标检测数据集

    文章目录 制作自己的目标检测数据集 一 下载Voc数据集 二 安装标注工具labelimg 三 制作图像标签 1 创建一个文件夹 2 在当前文件夹下打开命令提示符 3 打开标注软件 制作自己的目标检测数据集 一 下载Voc数据集 在官网下载
  • mes系统是什么?看完本文你就明白了

    一问 上MES系统有没有必要 答 MES系统通过对现场产品信息的实时采集 可以及时并最大限度地实现对质量的严格管理 另一方面 利用MES系统 可以实现生产计划的严格管控 从而最大限度地保证产品的及时交付 在控制质量和生产进度两方面提供保证
  • 【C/C++】C语言获取键盘输入

    C语言获取键盘输入 C提供的获取键盘输入的常用标准函数有scanf getchar gets 从键盘获取多个字符串 从键盘获取输入的字符串可以使用scanf gets fgets read Linux fread windows scanf
  • 在 Ubuntu 上卸载 Java

    在 Ubuntu 上卸载 Java 可以按照以下步骤进行操作 检查已安装的 Java 版本 打开终端并运行以下命令 查看系统上已安装的 Java 版本 java version 这将显示已安装的 Java 版本信息 卸载 OpenJDK 如
  • 逆向学习篇(一)

    开始学习逆向了 工欲善其事 必先利其器 第一篇 先记录先od的各个功能 这里先借用一张网上偷来的图 反汇编窗口 显示被调试程序的反汇编代码 标题栏上的地址 HEX 数据 反汇编 注释可以通过在窗口中右击出现的菜单 界面选项 gt 隐藏标题
  • java实现微信授权登录

    服务端实现app授权登录 1 导入jar包
  • 智能算法系列之蚁群算法

    本博客封面由ChatGPT DALL E 2共同创作而成 文章目录 前言 1 算法思想 2 算法流程 3 细节梳理 4 算法实现 4 1 问题场景 4 2 代码实现 代码仓库 IALib GitHub 前言 本篇是智能算法 Python复现