智能算法系列之蚁群算法

智能算法系列之蚁群算法_第1张图片

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

文章目录

    • 前言
    • 1. 算法思想
    • 2. 算法流程
    • 3. 细节梳理
    • 4. 算法实现
      • 4.1 问题场景
      • 4.2 代码实现
    • 代码仓库:IALib[GitHub]

前言

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

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

1. 算法思想

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

智能算法系列之蚁群算法_第2张图片

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

智能算法系列之蚁群算法_第3张图片
  随着时间的推移,蚁群会在最短的路径上持续进行食物的搬运,而较长的路径将不会有蚂蚁移动,示意图如下:

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

2. 算法流程

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

智能算法系列之蚁群算法_第5张图片

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:    [email protected]
# 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 [email protected]:xiayouran/IALib.git
cd examples
python main.py -algo aco

你可能感兴趣的:(智能算法(Python复现),机器学习,算法,人工智能,python,智能算法,蚁群算法)