基于蚁群算法的TSP问题建模求解(Python)

基于蚁群算法的TSP问题建模求解

  • 一、蚁群优化算法(Ant Colony Optimization,ACO)
    • 1.1 蚁群算法的起源——“双桥实验”
    • 1.2 蚁群优化算法思想
    • 1.3 蚁群算法应用于求解组合优化问题
  • 二、基于蚁群算法的TSP问题建模求解
    • 2.1 旅行商问题(Travelling salesman problem,TSP)
    • 2.2 蚁群算法求解TSP问题思想、步骤、流程图
    • 2.3 实例分析
    • 2.4 完整代码
    • 2.5 运行结果
  • 三、蚁群算法的改进
    • 3.1 精华蚂蚁系统(Elitist Ant System,EAS)
    • 3.2 基于排列的蚂蚁系统(rank-based Ant System,AS_rank)
    • 3.3 最大-最小蚂蚁系统(max-min ant system, MMAS)
    • 3.4 蚁群系统(Ant Colony System,ACS)
    • 3.5 连续正交蚁群算法(Continuous Orthogonal Ant Colony, COAC)

一、蚁群优化算法(Ant Colony Optimization,ACO)

蚁群系统(Ant System或Ant Colony System(是由意大利学者Dorigo、Maniezzo等人于20世纪90年代(1992年)首先提出来的。他们在研究蚂蚁觅食的过程中,发现单个蚂蚁的行为比较简单,但是蚁群整体却可以体现一些智能的行为。例如蚁群可以在不同的环境下,寻找最短到达食物源的路径。这是因为蚁群内的蚂蚁可以通过某种信息机制实现信息的传递。后又经进一步研究发现,蚂蚁会在其经过的路径上释放一种可以称之为“信息素”的物质,蚁群内的蚂蚁对“信息素”具有感知能力,它们会沿着“信息素”浓度较高路径行走,而每只路过的蚂蚁都会在路上留下“信息素”,这就形成一种类似正反馈的机制,这样经过一段时间后,整个蚁群就会沿着最短路径到达食物源了。

1.1 蚁群算法的起源——“双桥实验”

双桥实验在研究蚂蚁觅食行为过程中,人们发现,尽管单只蚂蚁的能力十分有限,但整个蚁群却在觅食过程中可以发现从蚁巢到食物源的最短路径。在觅食过程中,蚂蚁通过“媒介质”来协调它们之间的行动。所谓“媒介质”指的是一种以环境的变化为媒介的间接通信方式。蚂蚁在寻找食物时,以其产生的被称为信息素的化学物质作为媒介而间接的传递信息。当蚂蚁从蚁穴走到食物源,从而形成了含有信息素的路径。

蚂蚁从A点出发,随机选择路线ABD或ACD。经过9个时间单位时:走ABD的蚂蚁到达终点,走ACD的蚂蚁刚好走到C点。

经过18个时间单位时:走ABD的蚂蚁到达终点后得到食物又返回了起点A,而走ACD的蚂蚁刚好走到D点。

最后的极限是所有的蚂蚁只选择ABD路线。(正反馈过程)

1.2 蚁群优化算法思想

蚁群优化算法思想:蚁群的自组织行为通过遗留在来往路径的信息素Pheromone)挥发的化学性物质来进行通信和协调。

  • 蚁群算法是对自然界蚂蚁的寻径方式进行模似而得出的一种仿生优化算法:蚂蚁在运动过程中,能够在它所经过的路径上留下信息素(pheromone)的物质进行信息传递,而且蚂蚁在运动过程中能够感知这种物质,并以此指导自己的运动方向。
  • 由大量蚂蚁组成的蚁群集体行为便表现出一种信息正反馈现象:某一路径上走过的蚂蚁越多,则后来者选择该路径的概率就越大。

1.3 蚁群算法应用于求解组合优化问题

将蚁群算法应用于解决优化问题的基本思路为:用蚂蚁的行走路径表示待优化问题的可行解,整个蚂蚁群体的所有路径构成待优化问题的解空间。路径较短的蚂蚁释放的信息素量较多,随着时间的推进,较短的路径上累积的信息素浓度逐渐增高,选择该路径的蚂蚁个数也愈来愈多。最终,整个蚂蚁会在正反馈的作用下集中到最佳的路径上,此时对应的便是待优化问题的最优解。

二、基于蚁群算法的TSP问题建模求解

2.1 旅行商问题(Travelling salesman problem,TSP)

刘兴禄 -《运筹优化常用模型、算法及案例实战:Python+Java实现》总结了TSP问题共有3种数学模型,本文采用DFJ模型,见基于模拟退火算法的TSP问题建模求解(Python)

2.2 蚁群算法求解TSP问题思想、步骤、流程图

蚂蚁通过信息素指导寻优过程,每次迭代更新信息素,不断寻优。
蚂蚁在运动过程中,能够在它所经过的路径上留下信息素(pheromone)的物质进行信息传递,对应于求解TSP中
每只蚂蚁根据路径上的信息素和启发式信息(两城市间距离)独立地选择下一座城市,在时刻t,蚂蚁k从城市i转移到城市j的概率为:
p i j k ( t ) = { [ τ i j ( t ) ] α [ η i j ( t ) ] β ∑ s ∈ J k ( i ) [ τ i s ( t ) ] α [ η i s ( t ) ] β , j ∈ J k ( i ) 0 , j ∉ J k ( i ) \begin{align} p_{i j}^{k}(t)=\left\{\begin{array}{ll} \frac{\left[\tau_{i j}(t)\right]^{\alpha}\left[\eta_{i j}(t)\right]^{\beta}}{\sum_{s \in J_{k}(i)}\left[\tau_{i s}(t)\right]^{\alpha}\left[\eta_{i s}(t)\right]^{\beta}}, & j \in J_{k}(i) \\ 0, & j \notin J_{k}(i) \end{array}\right.\end{align} pijk(t)={sJk(i)[τis(t)]α[ηis(t)]β[τij(t)]α[ηij(t)]β,0,jJk(i)j/Jk(i)
其中:

  • α \alpha α β \beta β分别表示信息素和启发式银子的相对重要程度。
  • τ i j \tau_{ij} τij表示城市i到j的信息素。
  • η i j = 1 / d i j \eta_{ij}=1/d_{ij} ηij=1/dij d i j d_{ij} dij为城市间距离矩阵。
  • J k ( i ) = { 1 , 2 , ⋯   , n } − t a b u k J_k(i)=\{1,2,\cdots,n\}- {tabu_k} Jk(i)={1,2,,n}tabuk t a b u k {tabu_k} tabuk是蚂蚁k已经访问过城市。

蚂蚁在运动过程中能够感知信息素,并以此指导自己的运动方向
当所有蚂蚁完成一次周游后,各路径上的信息素将进行更新:
τ i j ( t + n ) = ( 1 − ρ ) τ i j + Δ τ i j \begin{align} \tau_{ij}(t+n)=(1-\rho)\tau_{ij}+\Delta\tau_{ij}\end{align} τij(t+n)=(1ρ)τij+Δτij

Δ τ i j = ∑ k = 1 m Δ τ i j k \begin{align}\Delta\tau_{ij}=\sum_{k=1}^{m} \Delta\tau_{ij}^{k}\end{align} Δτij=k=1mΔτijk
Δ τ i j k = { Q L k ,  if 蚂蚁 k  在本次周游中经过边  i j 0 ,  otherwise  \begin{align} \Delta \tau_{i j}^{k}=\left\{\begin{array}{ll} \frac{Q}{L_{k}}, & \text { if 蚂蚁}k\text{ 在本次周游中经过边 } ij \\ 0, & \text { otherwise } \end{array}\right. \end{align} Δτijk={LkQ,0, if 蚂蚁k 在本次周游中经过边 ij otherwise 
其中:

  • ρ \rho ρ 0 < ρ < 1 0<\rho<1 0<ρ<1)表示路径上信息素的蒸发系数;
  • Q为正常数;
  • L k L_k Lk表示第k只蚂蚁在本次周游中所走过路径的长度。

蚁群算法求解TSP问题步骤如下:

  1. 初始化。问题相关参数(城市数量、城市间距离矩阵)、算法参数(蚂蚁数量、 α \alpha α β \beta β ρ \rho ρ Q Q Q m a x g e n maxgen maxgen)。
  2. 为每只蚂蚁构建路径。随机初始化蚂蚁路径的起点城市,根据式(1)计算每个城市的选择概率,通过轮盘赌选择下一个城市,直至路径蚂蚁路径形成一条TSP回路。
  3. 根据式(2)更新信息素矩阵。
  4. 检查终止条件
  5. 输出最优值

蚁群算法求解TSP问题算法流程图:

2.3 实例分析

在这里插入图片描述
在这里插入图片描述

2.4 完整代码

采用TSP问题标准测试函数att48,城市数量48进行测试,

# -*- coding: utf-8 -*-
import itertools
import random
import copy
import numpy as np
from scipy.spatial import distance
from typing import List, Dict, Tuple
from matplotlib import pyplot as plt
from numpy import ndarray

np.set_printoptions(threshold=np.inf, linewidth=np.inf)

# 参数
'''
ALPHA:信息启发因子,值越大,则蚂蚁选择之前走过的路径可能性就越大,值越小,则蚁群搜索范围就会减少,容易陷入局部最优
BETA:Beta值越大,蚁群越就容易选择局部较短路径,这时算法收敛速度会加快,但是随机性不高,容易得到局部的相对最优
'''


# 城市距离和信息素
class AntColonyOpt:
    def __init__(self, problem):
        self.problem = problem
        self.num_city = problem.num_city
        self.city_coord = problem.city_coord
        self.city_list = problem.city_list
        self.distance = None
        self.pheromone = None
        self.num_ant = 48
        self.alpha = 1.
        self.beta = 2.
        self.rho = .5  # 信息素的蒸发率
        self.Q = 100.
        self.tau = np.ones(shape=(self.num_city, self.num_city))  # 信息素
        self.eta = None
        self.ant_list = []
        self.best_ant = None

        self.gen = 0  # 初始化迭代次数
        self.max_gen = 1e3
        self.initialize()

    # 初始化
    def initialize(self):
        # 初始化城市之间的距离
        city_coord = np.asarray(list(self.city_coord.values()))
        self.distance = distance.cdist(city_coord, city_coord, 'euclidean')
        self.eta = 1 / self.distance

        # 初始城市之间的信息素
        self.pheromone = np.ones(shape=(self.num_city, self.num_city), dtype=np.float64)
        # self.pheromone = [[1.0 for col in range(num_city)] for raw in range(num_city)]
        for i in range(self.num_ant):
            ant = {
                "id": i,
                "path": [i],
                "path_length": 1 << 31,
                "tabu": {i},
                "allow": [True if city != i else False for city in self.city_list],
                "move_count": 0
            }

            self.ant_list.append(ant)
        self.best_ant = {
            "id": -1,
            "path": [0],
            "path_length": 1 << 31,
            "tabu": set(),
            "allow": [True] * self.num_city,
            "move_count": 0
        }  # 初始最优解

    def build_path(self, ant):
        while ant["move_count"] < self.num_city - 1:
            # 移动到下一个城市
            next_city = self.select(ant)
            self.move(ant, next_city)

    def select(self, ant):

        # 计算选择概率: i 当前城市, j 遍历allow中j城市
        ant_path = ant["path"]
        i = ant_path[-1]  # 当前城市
        numerator = np.array([(self.tau[i][j] ** self.alpha) * (self.eta[i][j] ** self.beta) if ant["allow"][j] is True else 0 for j in self.city_list])
        denominator = np.sum(numerator)

        p_select = numerator / denominator
        p_cum = np.cumsum(p_select)
        # 轮盘赌选择
        select = None
        r = np.random.uniform(0, 1)
        for city in self.city_list:
            if ant["allow"][city] is True:
                if r < p_cum[city]:
                    select = city
                    break
        return select

    # 移动操作
    def move(self, ant, next_city):
        ant["path"].append(next_city)
        ant["allow"][next_city] = False
        ant["tabu"].add(next_city)
        ant["move_count"] += 1

    def clear(self):
        self.ant_list = []
        random_city = np.random.randint(low=0, high=self.num_city)
        for i in range(self.num_ant):
            ant = {
                "id": random_city,
                "path": [random_city],
                "path_length": 1 << 31,
                "tabu": {random_city},
                "allow": [True if city != random_city else False for city in self.city_list],
                "move_count": 0
            }
            self.ant_list.append(ant)

    # 运行蚁群优化算法
    def run(self):
        trace = []
        while self.gen <= self.max_gen:
            # 遍历每一只蚂蚁

            for ant in self.ant_list:
                # 搜索一条路径

                self.build_path(ant)
                ant["path_length"] = self.calc_path_length(ant["path"])
                # 与当前最优蚂蚁比较, 更新最优解
                if ant["path_length"] < self.best_ant["path_length"]:
                    self.best_ant = copy.deepcopy(ant)
                # print(ant)
            # 更新信息素
            self.update_pheromone()
            print(u"迭代次数:", self.gen, u"最佳路径总距离:", int(self.best_ant["path_length"]))
            self.gen += 1
            trace.append((self.best_ant['path'], self.best_ant['path_length']))
            self.clear()

        self.draw([(self.best_ant["path"], self.best_ant["path_length"])])

    # 计算路径总距离
    def calc_path_length(self, path):
        total_distance = 0.
        for i, j in itertools.pairwise(path):
            total_distance += self.distance[i][j]
        i = path[-1]
        j = path[0]
        total_distance += self.distance[i][j]
        return total_distance

    def draw(self, trace: List[Tuple[List, float]]) -> None:
        """
        最优路径可视化
        :param trace:每次迭代过程中最优路径及路径长度,trace是一个list,len(trace)=max_gen
        :return:
        """
        iteration = np.arange(len(trace))
        obj_value = [trace[i][1] for i in range(len(trace))]
        plt.plot(iteration, obj_value)
        plt.show()
        final_solution, final_obj_value = trace[-1]
        x = []
        y = []
        for city in final_solution:
            city_x, city_y = self.city_coord[city]
            x.append(city_x)
            y.append(city_y)
        city_x, city_y = self.city_coord[final_solution[0]]
        x.append(city_x)
        y.append(city_y)
        plt.plot(x, y, 'o-', alpha=1, linewidth=2)

        plt.savefig("ACO-TSP.png", bbox_inches="tight")

    def update_pheromone(self):
        """
        更新信息素
        :return:
        """
        delta_tau = np.zeros(shape=(self.num_city, self.num_city))
        for ant in self.ant_list:
            for i in range(1, self.num_city):
                start, end = ant["path"][i - 1], ant["path"][i]
                # 在路径上的每两个相邻城市间留下信息素,与路径总距离反比
                delta_tau[start][end] += self.Q / ant["path_length"]
                delta_tau[end][start] = delta_tau[start][end]
        for i in range(self.num_city):
            for j in range(self.num_city):
                self.tau[i][j] = (1 - self.rho) * self.tau[i][j] + delta_tau[i][j]


class TSP(object):
    num_city: int = None  # 城市数量
    city_coord: Dict[int, Tuple[int, int]] = None  # 城市标号及对应坐标,示例 1:(23,312)
    distance: ndarray = None  # 城市间距离矩阵
    pheromone: List = None

    def __init__(self, city_coord):
        self.num_city = len(city_coord)
        self.city_coord = city_coord
        self.city_list = city_coord.keys()
        self.distance = np.empty(shape=(self.num_city, self.num_city), dtype=np.float64)


if __name__ == '__main__':
    city_coord_att48 = {
        0: (6734, 1453),
        1: (2233, 10),
        2: (5530, 1424),
        3: (401, 841),
        4: (3082, 1644),
        5: (7608, 4458),
        6: (7573, 3716),
        7: (7265, 1268),
        8: (6898, 1885),
        9: (1112, 2049),
        10: (5468, 2606),
        11: (5989, 2873),
        12: (4706, 2674),
        13: (4612, 2035),
        14: (6347, 2683),
        15: (6107, 669),
        16: (7611, 5184),
        17: (7462, 3590),
        18: (7732, 4723),
        19: (5900, 3561),
        20: (4483, 3369),
        21: (6101, 1110),
        22: (5199, 2182),
        23: (1633, 2809),
        24: (4307, 2322),
        25: (675, 1006),
        26: (7555, 4819),
        27: (7541, 3981),
        28: (3177, 756),
        29: (7352, 4506),
        30: (7545, 2801),
        31: (3245, 3305),
        32: (6426, 3173),
        33: (4608, 1198),
        34: (23, 2216),
        35: (7248, 3779),
        36: (7762, 4595),
        37: (7392, 2244),
        38: (3484, 2829),
        39: (6271, 2135),
        40: (4985, 140),
        41: (1916, 1569),
        42: (7280, 4899),
        43: (7509, 3239),
        44: (10, 2676),
        45: (6807, 2993),
        46: (5185, 3258),
        47: (3023, 1942),
    }
    problem = TSP(city_coord_att48)
    aco = AntColonyOpt(problem)
    aco.run()

2.5 运行结果

采用TSP问题标准测试函数att48,城市数量48,最优解为33523)本文迭代次数:1000最佳路径总距离:35408,其他文章基于禁忌搜索的TSP问题建模求解(Java)结果为34974.67245297696。本文求解结果如下图:

三、蚁群算法的改进

1992年,意大利学者M. Dorigo在其博士论文中提出蚂蚁系统(Ant System)。

3.1 精华蚂蚁系统(Elitist Ant System,EAS)

精华蚂蚁系统(Elitist Ant System,EAS)是对基础AS的第一次改进,它在原AS信息素更新原则的基础上增加了一个对至今最优路径的强化手段。每次迭代完成后,对全局最优解更进一步地进行利用;信息素更新策略:
τ i j ( t + 1 ) = ( 1 − ρ ) τ i j ( t ) + Δ τ i j + Δ τ i j ∗ \tau_{ij}(t+1)=(1-\rho)\tau_{ij}(t)+\Delta\tau_{ij}+\Delta\tau_{ij}^* τij(t+1)=(1ρ)τij(t)+Δτij+Δτij
τ i j ∗ = { σ Q L gb , if边 i j 是最优解的一部分 0 , otherwise \tau_{ij}^*=\left\{\begin{array}{lr} \sigma \frac{Q} { L^{\text {gb}}}, & \text {if边} ij\text{是最优解的一部分} \\ 0, & \text {otherwise} \end{array}\right. τij={σLgbQ,0,ifij是最优解的一部分otherwise
该策略能够以更快的速度获得最好解,但是如果选择的精英过多则算法会由于较早收敛于局部次优解而导致搜索的过早停滞。

3.2 基于排列的蚂蚁系统(rank-based Ant System,AS_rank)

每次迭代完成后,蚂蚁所经路径按从小到大的顺序排列,并对它们赋予不同权值,路径越短权值越大。全局最优解权值为 w w w,第 r r r个最优解的权值为 max ⁡ { 0 , w − r } \max\{0,w-r\} max{0,wr}。基于排序的蚂蚁系统信息素更新为:
τ i j ( t + 1 ) = ( 1 − ρ ) τ i j ( t ) + ∑ r = 1 w − 1 ( w − r ) Δ τ i j r ( t ) + w Δ τ i j g b ( t ) \tau_{ij}(t+1)=(1-\rho)\tau_{ij}(t)+\sum_{r=1}^{w-1}(w-r)\Delta\tau_{ij}^r(t)+w\Delta\tau_{ij}^{gb}(t) τij(t+1)=(1ρ)τij(t)+r=1w1(wr)Δτijr(t)+wΔτijgb(t)
Δ τ i j r ( t ) = 1 L r ( t ) \Delta\tau_{ij}^r(t)=\frac{1}{L^r(t)} Δτijr(t)=Lr(t)1
Δ τ i j g b ( t ) = 1 L g b ( t ) \Delta\tau_{ij}^{gb}(t)=\frac{1}{L^{gb}(t)} Δτijgb(t)=Lgb(t)1
权值 ( ω − r ) (ω−r) (ωr)对不同路径的信息素浓度差异起到了一个放大的作用,AS_rank能更有力度地指导蚂蚁搜索。

3.3 最大-最小蚂蚁系统(max-min ant system, MMAS)

最大最小蚂蚁系统(MAX-MIN Ant System,MMAS)在基本AS算法的基础上进行了四项改进:

  1. 只允许迭代最优蚂蚁(在本次迭代构建出最短路径的蚂蚁),或者至今最优蚂蚁释放信息素。(迭代最优更新规则和至今最优更新规则在MMAS中会被交替使用。)

    如果只使用至今最优更新规则进行信息素的更新,搜索的导向性很强,算法会很快收敛到T_b附近;反之,如果只使用迭代最优更新规则,则算法的探索能力会得到增强,但收敛速度会下降。实验结果表明,对于小规模的TSP问题,仅仅使用迭代最优信息素更新方式即可。随着问题规模的增大,至今最优信息素规则的使用变得越来越重要。
    τ i j ( t + 1 ) = ( 1 − ρ ) τ i j ( t ) + Δ τ i j best  ( t ) , ρ ∈ ( 0 , 1 ) Δ τ i j best  = { 1 / L best  , if  边 i j 包含在最优路径中  0 , otherwise \begin{array}{l} \tau_{i j}(t+1)=(1-\rho) \tau_{i j}(t)+\Delta \tau_{i j}^{\text {best }}(t), \quad \rho \in(0,1) \\ \Delta \tau_{i j}^{\text {best }}= \left\{\begin{array}{lr} 1 / L^{\text {best }}, & \text {if \quad 边} ij\text{包含在最优路径中 } \\ 0, & \text {otherwise} \end{array}\right. \end{array} τij(t+1)=(1ρ)τij(t)+Δτijbest (t),ρ(0,1)Δτijbest ={1/Lbest ,0,if ij包含在最优路径中 otherwise

  2. 信息素量大小的取值范围被限制在一个区间 [ τ m i n , τ m a x ] [\tau_{min}, \tau_{max}] [τmin,τmax]内。

    当信息素浓度也被限制在一个范围内以后,位于城市i的蚂蚁k选择城市j作为下一城市的概率也将被限制在一个区间内。算法有效避免了陷入停滞状态(所有蚂蚁不断重复搜索同一条路径)的可能性。

  3. 信息素初始值为信息素取值区间的上限,并伴随一个较小的信息素蒸发速率。

    增强算法在初始阶段的探索能力,有助于蚂蚁“视野开阔地”进行全局范围内的搜索,随后蚂蚁逐渐缩小搜索范围。

  4. 每当系统进入停滞状态,问题空间内所有边上的信息素量都会被重新初始化。(通常对各条边上信息素量大小的统计或是观察算法在指定次数的迭代内至今最优路径有无被更新来判断算法是否停滞)。

3.4 蚁群系统(Ant Colony System,ACS)

1997年,蚁群算法的创始人Dorigo在“Ant colony system: a cooperative learning approach to the traveling salesman problem”一文中提出了一种具有全新机制的ACO算法——蚁群系统(Ant Colony System,ACS),进一步提高了ACO算法的性能。

  1. 使用一种伪随机比例规则(pseudorandom proportional)选择下城市节点,建立开发当前路径与探索新路径之间的平衡。
    j = { arg max ⁡ j ∈ J k ( i ) { [ τ ( i , j ) ] , [ η ( i , j ) ] β } , if q ≤ q 0 S , otherwise j= \left\{\begin{array}{lr} \argmax_{j \in J_k(i)}\{[\tau(i,j)],[\eta(i,j)]^\beta\}, & \text {if}\quad q \leq q_0 \\ S, & \text{otherwise} \end{array}\right. j={argmaxjJk(i){[τ(i,j)],[η(i,j)]β},S,ifqq0otherwise
    其中:

    • q为0~1的随机数。
    • q 0 q_0 q0是一个 [ 0 , 1 ] [0, 1] [0,1]区间内的参数,当产生的随机数 q ≤ q 0 q≤q_0 qq0时,蚂蚁直接选择使启发式信息与信息素量的指数乘积最大的下城市节点,我们通常称之为利用(exploitation);反之,当产生的随机数 q > q 0 q>q_0 q>q0时,ACS将和各种AS算法一样使用轮盘赌选择策略,我们称之为偏向探索(bias exploration)。通过调整 q 0 q_0 q0,我们能有效调节“开发”与“探索”之间的平衡,以决定算法是集中开发最优路径附近的区域,还是探索其它的区域。
    • S为一随机变量
  2. 使用信息素全局更新规则,每轮迭代中所有蚂蚁都已构建完路径后,在属于至今最优路径的边上蒸发和释放信息素。
    τ i j = ( 1 − ρ ) τ i j + ρ Δ τ i j g b \tau_{ij}=(1-\rho)\tau_{ij}+\rho\Delta\tau_{ij}^{gb} τij=(1ρ)τij+ρΔτijgb
    Δ τ i j = { 1 / L g b , if i j 在最优路径中 0 , otherwise \Delta\tau_{ij}= \left\{\begin{array}{lr} 1/L^{gb}, & \text {if}\quad ij在最优路径中 \\ 0, & \text{otherwise} \end{array}\right. Δτij={1/Lgb,0,ifij在最优路径中otherwise
    其中 Δ τ i j g b \Delta\tau_{ij}^{gb} Δτijgb,不论是信息素的蒸发还是释放,都只在属于至今最优路径的边上进行,这里与AS有很大的区别。因为AS算法将信息素的更新应用到了系统的所有边上,信息素更新的计算复杂度为 O ( n 2 ) O(n^2) On2,而ACS算法的信息素更新计算复杂度降低为 O ( n ) O(n) On。参数ρ代表信息素蒸发的速率,新增加的信息素被乘上系数 ρ ρ ρ后,更新后的信息素浓度被控制在旧信息素量与新释放的信息素量之间,用一种隐含的又更简单的方式实现了MMAS算法中对信息素量取值范围的限制。

  3. 引入信息素局部更新规则,在路径构建过程中,对每一只蚂蚁,每当其经过一条边(i, j)时,它将立刻对这条边进行信息素的更新。
    τ i j = ( 1 − ξ ) τ i j + ξ τ 0 \tau_{ij}=(1-\xi)\tau_{ij}+\xi\tau_0 τij=(1ξ)τij+ξτ0
    其中:

    • ξ \xi ξ是信息素局部挥发速率, 0 < ξ < 1 0<\xi<1 0<ξ<1
    • τ 0 \tau_0 τ0是信息素的初始值

    实验发现 ξ = 0.1 \xi=0.1 ξ=0.1 τ 0 = 1 / n C n n \tau_0=1/nC^{nn} τ0=1/nCnn,算法对绝大多数实例有着非常好的性能。其中n是城市数量, C n n C^{nn} Cnn是贪婪算法构造的路径长度。

    信息素局部更新规则作用于某条边上会使得这条边被其他蚂蚁选中的概率减少。这种机制大大增加了算法的探索能力,后续蚂蚁倾向于探索未被使用过的边,有效地避免了算法进入停滞状态。

  4. 在ACS中通常我们选择让所有蚂蚁并行地工作。顺序构建和并行构建。顺序构建是指当一只蚂蚁完成一轮完整的构建并返回到初始城市之后,下一只蚂蚁才开始构建;并行构建是指所有蚂蚁同时开始构建,每次所有蚂蚁各走一步(从当前城市移动到下一个城市)。对于ACS,要注意到两种路径构建方式会造成算法行为的区别。

3.5 连续正交蚁群算法(Continuous Orthogonal Ant Colony, COAC)

近年来,将应用领域扩展到连续空间的蚁群算法也在发展,连续正交蚁群就是其中比较优秀的一种。COAC通过在问题空间内自适应地选择和调整一定数量的区域,并利用蚂蚁在这些区域内进行正交搜索、在区域间进行状态转移、并更新各个区域的信息素来搜索问题空间中的最优解。
COAC的基本思想是利用正交试验的方法将连续空间离散化。
参考:

  • 蚁群算法(Ant Colony Optimization)
  • 一文搞懂什么是蚁群优化算法(Ant Colony Optimization, ACO)【附应用举例】
  • 蚁群算法原理及其实现(python)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/317433.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软件测试|web自动化测试神器playwright教程(三十八)

简介 在我们使用selenium时&#xff0c;我们可以获取元素的属性&#xff0c;元素的文本值&#xff0c;以及输入框的内容等&#xff0c;作为比selenium更为强大的web自动化测试神器&#xff0c;playwright也可以实现对元素属性&#xff0c;文本值和输入框内容的抓取&#xff0c…

Mysql事务的处理

1、事务&#xff0c;就是一组命令的操作。 不过这一组命令&#xff0c;我们有时候需要使用手动提交&#xff1b; 1、使用这组命令可以查询出来现在的提交方式&#xff1a;自动提交&#xff08;就是命令输入&#xff0c;点击enter后&#xff0c;会不会直接对表格产生修改&#x…

重温经典struts1之自定义全局异常处理类处理异常以及<exeception>标签的配置

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 前面的文章&#xff0c;我们学习了&#xff0c;Action类中调用Service&#xff0c;通过try…catch代码块&#xff0c;catch自定义异常类&#xff0c;通过ActionMessage…

metrics安装异常原因【doesn‘t contain any IP SANs】

1、问题背景 安装好k8s后&#xff0c;安装metrics-server后发现对应的pod一直无法启动。 apiVersion: v1 kind: ServiceAccount metadata:labels:k8s-app: metrics-servername: metrics-servernamespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: Cl…

05.neuvector网络学习与管控实现

原文链接&#xff0c;欢迎大家关注我的github 一、网络的策略学习 1.1.非主机模式的网络连接学习 agent进程侧&#xff1a; 调用taskAddContainer->taskInterceptContainer->programDP->DPCtrlAddTapPort为所有非host模式的容器向dp传送 DPAddTapPortReq对象数据.&…

成就动机测试

成就动机测试广泛应用在职业发展领域&#xff0c;如&#xff1a;企业Hr人力资源管理部门&#xff0c;用于评估分析员工的潜能和价值&#xff0c;适用场景有人才招聘&#xff0c;岗位晋升&#xff0c;绩效考评等等。在大学生做职业规划&#xff0c;求职应聘中&#xff0c;应用成…

数据结构与算法(十一) 排序算法一

int nArray[] { 8,5,3,2,7 };如下一个数组&#xff0c;现对其进行从小到大排序 选择排序 选择排序&#xff1a;将小的依次放在前面 具象化如下&#xff1a; void swap(int *nSValue,int *nDValue) 交换函数 { int nTempValue 0; nTempValue *nSValue; *nSVal…

Spring Boot 整合支付宝实现在线支付方案(沙箱环境)

文章目录 1.理解沙箱环境2.沙箱环境接入准备2.1 访问开发者控制台2.2 获取重要信息2.3 处理秘钥 3.接入支付宝支付的流程4.实现支付4.1 添加 SDK 依赖4.2 创建配置类4.3 支付宝订单管理接口实现流程4.4 支付宝支付接口实现流程 5.支付宝支付功能演示7.总结 TIP&#xff1a;对于…

分享一个好用的免费在线扣图网址

具体效果 附地址 https://cutout.aiwave.cc/

【python】基础知识类的语法功能讲解

Python代码定义了一个名为Calculation的类&#xff0c;用于执行基础的数学运算&#xff08;加法、减法、乘法、除法和取模&#xff09;。下面我将详细解释各个部分的功能&#xff0c;并以列表形式总结&#xff1a; 类定义&#xff1a; class Calculation: 定义了一个名为Cal…

iOS Universal Links(通用链接)详细教程

一&#xff1a;Universal Links是用来做什么的&#xff1f; iOS9.0推出的用于应用之间跳转的一种机&#xff0c; 通过一个https的链接启动app。如果手机有安装需要启动的app&#xff0c;可实现无缝跳转。如果没有安装&#xff0c;会打开网页。 实现场景&#xff1a;微信链接无…

Flink窗口(2)—— Window API

目录 窗口分配器 时间窗口 计数窗口 全局窗口 窗口函数 增量聚合函数 全窗口函数&#xff08;full window functions&#xff09; 增量聚合和全窗口函数的结合使用 Window API 主要由两部分构成&#xff1a;窗口分配器&#xff08;Window Assigners&#xff09;和窗口函…

Memcache简介与运维

开源、高性能、高并发的分布式内存缓存系统。 作用 缓存关系型数据库的结果&#xff0c;减少数据库自身访问的次数。 常见内存缓存服务软件对比 memcache 纯内存 redis、memcachedb 可持久化存储&#xff0c;同时会使用磁盘存 …

Typora使用及Markdow学习笔记1

编程如画&#xff0c;我是panda&#xff01; 最近有在学习Markdown&#xff0c;所以这次分享一下我的Markdown学习笔记 目录 前言 一、标题 二、段落 1.换行 2.分割线 三、文字显示 1.字体 2.上下标 四、列表 1.无序列表 2.有序列表 3.任务列表 五、区块 六、代…

外包干了5个月,感觉技术退步明显......

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入武汉某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01; 而我已经在一个企业干了四…

深入理解Spring IOC

1. IOC 理论 IOC 全称控制反转&#xff0c;英文名为 Inversion of Control&#xff0c;它还有一个别名为 DI&#xff08;Dependency Injection&#xff09;,即依赖注入。 在我们刚接触Spring的时候&#xff0c;我们就听说了IOC&#xff0c;但是对于IOC的理解&#xff0c;貌似…

ubuntu 20.04下 Tesla P100加速卡使用

1.系统环境&#xff1a;系统ubuntu 20.04, python 3.8 2.查看cuDNN/CUDA与tensorflow的版本关系如下&#xff1a; Build from source | TensorFlow 从上图可以看出&#xff0c;python3.8 对应的tensorflow/cuDNN/CUDA版本。 3.安装tensorflow #pip3 install tensorflow 新版…

ZooKeeper初探:分布式世界的守护者

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 ZooKeeper初探&#xff1a;分布式世界的守护者 前言Zookeeper的概述分布式系统中的角色和作用&#xff1a; Zookeeper的数据模型Znode的概念和层次结构&#xff1a;Znode的类型和应用场景&#xff1a;…

如何给AI下达精准的指令,哪些提示词对于AI是有效的?

刚上手那会&#xff0c;我倾向于将 prompt 翻译为“指令”&#xff0c;但这并不精确。“指令”通常对应instructions&#xff0c;属于 prompt 中的纯指令部分&#xff0c;通常是一个动宾结构&#xff08;做什么&#xff09;。剩下的部分更多是描述&#xff08;describe&#xf…

【从零开始学习微服务 | 第一篇】什么是微服务

目录 前言&#xff1a; 架构风格&#xff1a; 单体架构&#xff1a; 分布式架构&#xff1a; 微服务&#xff1a; 总结&#xff1a; 前言&#xff1a; 在当今快速发展的软件开发领域&#xff0c;构建大型应用程序已经成为一项巨大的挑战。传统的单体应用架构往往难以满足…