蚁群算法简要介绍及算法实现解决TSP问题

蚁群算法简介和算法实现

  1. 蚁群算法背景及实现方法简要介绍

    1. 背景

      ​ 单只蚂蚁的行为及其简单,行为数量在10种以内,但成千上万只蚂蚁组成的蚁群却能拥有巨大的智慧,这离不开它们信息传递的方式——信息素。
      ​ 蚂蚁在行走过程中会释放一种称为“信息素”的物质,用来标识自己的行走路径。在寻找食物的过程中,根据信息素的浓度选择行走的方向,并最终到达食物所在的地方。
      信息素会随着时间的推移而逐渐挥发。
      ​ 在一开始的时候,由于地面上没有信息素,因此蚂蚁们的行走路径是随机的。蚂蚁们在行走的过程中会不断释放信息素,标识自己的行走路径。随着时间的推移,有若干只蚂蚁找到了食物,此时便存在若干条从洞穴到食物的路径。由于蚂蚁的行为轨迹是随机分布的,因此在单位时间内,短路径上的蚂蚁数量比长路径上的蚂蚁数量要多,从而蚂蚁留下的信息素浓度也就越高。这为后面的蚂蚁们提供了强有力的方向指引,越来越多的蚂蚁聚集到最短的路径上去。
      ​ (1)高度结构化的组织——虽然蚂蚁的个体行为极其简单,但由个体组成的蚁群却构成高度结构化的社会组织,蚂蚁社会的成员有分工,有相互的通信和信息传递。
      ​ (2)自然优化——蚁群在觅食过程中,在没有任何提示下总能找到从蚁巢到食物源之间的最短路径;当经过的路线上出现障碍物时,还能迅速找到新的最优路径。
      ​ (3)信息正反馈——蚂蚁在寻找食物时,在其经过的路径上释放信息素(外激素)。蚂蚁基本没有视觉,但能在小范围内察觉同类散发的信息素的轨迹,由此来决定何去何从,并倾向于朝着信息素强度高的方向移动。
      ​ (4)自催化行为——某条路径上走过的蚂蚁越多,留下的信息素也越多(随时间蒸发一部分),后来蚂蚁选择该路径的概率也越高。

    2. 实现方法

      (1)根据具体问题设置多只蚂蚁,分头并行搜索。
      (2)每只蚂蚁完成一次周游后,在行进的路上释放信息素,信息素量与解的质量成正比。
      (3)蚂蚁路径的选择根据信息素强度大小(初始信息素量设为相等),同时考虑两点之间的距离,采用随机的局部搜索策略。这使得距离较短的边,其上的信息素量较大,后来的蚂蚁选择该边的概率也较大。
      (4)每只蚂蚁只能走合法路线(经过每个城市1次且仅1次),为此设置禁忌表来控制。
      (5)所有蚂蚁都搜索完一次就是迭代一次,每迭代一次就对所有的边做一次信息素更新,原来的蚂蚁死掉,新的蚂蚁进行新一轮搜索。
      (6)更新信息素包括原有信息素的蒸发和经过的路径上信息素的增加。
      (7)达到预定的迭代步数,或出现停滞现象(所有蚂蚁都选择同样的路径,解不再变化),则算法结束,以当前最优解作为问题的最优解。

  2. 用途

    主要用来解决路径优化问题!!!

  3. 参数

    • m:蚂蚁数量;

    • k:蚂蚁编号;

    • t:时刻;

    • n:城市数;

    • d i,j d_\text{i,j} di,j:城市(i,j)之间的距离;

    • η i,j \eta_\text{i,j} ηi,j:启发式因子(能见度)反应蚂蚁由城市i转移到城市j的启发程度;
      η i,j = 1 d i,j \displaystyle\eta_\text{i,j}=\frac{1}{d_\text{i,j}} ηi,j=di,j1

    • τ i,j \tau_\text{i,j} τi,j:边(i,j)上的信息素;
      τ i,j ( t + n ) = ( 1 − ρ ) ⋅ τ i,j ( t ) + Δ τ i,j τ i,j ( 0 ) = C \tau_\text{i,j}(t+n)=(1-\rho)\cdot\tau_\text{i,j}(t)+\Delta\tau_\text{i,j}\\ \tau_\text{i,j}(0)=C τi,j(t+n)=(1ρ)τi,j(t)+Δτi,jτi,j(0)=C

    • Δ τ i,j \Delta\tau_\text{i,j} Δτi,j:本次迭代边(i,j)上的信息素增量;
      Δ τ i,j = ∑ k = 1 m Δ τ i,j k Δ τ i,j ( 0 ) = 0 \Delta\tau_\text{i,j}=\sum_{k=1}^m\Delta\tau_\text{i,j}^k\\ \Delta\tau_\text{i,j}(0)=0 Δτi,j=k=1mΔτi,jkΔτi,j(0)=0

    • Δ τ i,j k \Delta\tau_\text{i,j}^k Δτi,jk:第k只蚂蚁在本次迭代中留在边(i,j)上的信息素量;
      Δ τ i,j k = { Q L k   ,   若 蚂 蚁 在 本 次 周 游 中 经 过 变 ( i , j ) 0   ,   其 他 \Delta\tau_\text{i,j}^k= \left\{ \begin{array}{l} \displaystyle\frac{Q}{L_k}\ ,\ 若蚂蚁在本次周游中经过变(i,j)\\ 0\ ,\ 其他 \end{array} \right. Δτi,jk=LkQ , (i,j)0 , 

      Q — — 正 常 数 ; L k — — 蚂 蚁 k 在 本 次 周 游 中 所 走 的 路 径 的 长 度 。 \begin{array}{l} Q——正常数;\\ L_k——蚂蚁k在本次周游中所走的路径的长度。 \end{array} QLkk

    • ρ \rho ρ:信息素蒸发(或挥发)系数;

    • 1 − ρ 1-\rho 1ρ:持久性(或残留)系数,0< ρ \rho ρ<1;

    • P i,j k ( t ) P_\text{i,j}^k(t) Pi,jk(t):时刻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 ) ] β P_\text{i,j}^k(t)= \left\{ \begin{array}{l} \displaystyle\frac{[\tau_\text{i,j}(t)]^{\alpha}\cdot[\eta_\text{i,j}(t)]^\beta}{\displaystyle\sum_{s\in J_k(i)}[\tau_\text{i,s}(t)]^{\alpha}\cdot[\eta_\text{i,s}(t)]^\beta} \end{array} \right. Pi,jk(t)=sJk(i)[τi,s(t)]α[ηi,s(t)]β[τi,j(t)]α[ηi,j(t)]β

      α — — 信 息 素 的 相 对 重 要 程 度 ; β — — 启 发 式 因 子 的 相 对 重 要 程 度 ; J k ( i ) — — 蚂 蚁 k 下 一 步 允 许 选 择 的 城 市 合 集 \begin{array}{l} \alpha——信息素的相对重要程度;\\ \beta——启发式因子的相对重要程度;\\ J_k(i)——蚂蚁k下一步允许选择的城市合集 \end{array} αβJk(i)k

    • t a b o o k taboo_k tabook:蚂蚁k的禁忌表

  4. 算法流程

    1. 所有参数的初始化(包括城市距离表、各种系数等)

    2. 寻找每次迭代下的最佳路径

      1. 确定每只蚂蚁的初始位置和终点位置

      2. 计算每只蚂蚁该次迭代下的路径

        1. 确定在该城市下的禁忌表 ⟹ \Longrightarrow 进而确定下一步可以选择的城市
        2. 计算可选城市中每一座的转移概率
        3. 依据转移概率,按照轮盘赌法确认下一座城市
        4. 通过一次重复上述过程,确认一只蚂蚁的运动路径
      3. 计算每只蚂蚁走过的路程

      4. 按照当前计算出的路径更新各城市间道路的信息素

      5. 计算出该次迭代下所走路程最小的蚂蚁及其走过的路径和路程

    3. 在计算出的所有迭代次数中的最优路径寻找长度最小的一条

    4. 将结果进行打印展示

  5. 流程总结
    在这里插入图片描述
    6.示例代码(解决TSP问题)

%% I. 清空环境变量
clear
clc
close all

%% II. 导入数据
x = [2, 4, 7, 13, 18, 18, 22, 24, 25, 25, 37, 41, 41, 44, 45, 54, 54, 58, 58, 62, 64, 68, 71, 71, 74, 82, 83, 83, 87, 91];
y = [99, 50, 64, 40, 40, 54, 60, 42, 38, 62, 84, 26, 94, 35, 21, 62, 67, 35, 69, 32, 60, 58, 44, 71, 78, 7, 46, 69, 76, 38];

citys = [];

for i = 1:length(x)
    citys = [citys; [x(i), y(i)]];
end

%% III. 获得城市距离地图表

n = length(citys); % 城市个数
CitysDistanceTable = zeros(n, n); % 各城市之间距离矩阵
CitysNameList = 1:n; % 城市名称索引(主要给下面禁忌表构建使用)
% 计算个城市之间距离,构建距离矩阵表
for i = 1:n

    for j = 1:n

        if i ~= j
            CitysDistanceTable(i, j) = sqrt(sum((citys(i, :) - citys(j, :)).^2));
        else
            CitysDistanceTable(i, j) = 0;
        end

    end

end

%% IV. 初始化参数

m = 200; % 蚁群数量
eta = 1 ./ CitysDistanceTable; % 可见度
tau = ones(n, n); % 信息素浓度矩阵
rho = 0.1; % 信息素挥发系数
Q = 1; % 一常数,与信息素浓度有关(个人感觉取任何数都可以)
alpha = 1; % 信息素相对重要程度
beta = 5; % 能见度相对重要程度
iter_Max = 200; % 最大迭代次数
Thre = 0.1; % 当所求最优解不变次数超过iter_Max*Thre时,终止迭代
waitbarjiange = iter_Max / 100; % 和进度条有关的一个数据
RouteBest = zeros(iter_Max, n + 1); % 每次迭代最优路径合集
LengthBest = zeros(iter_Max, 1); % 每次迭代路径最小值合集

%% V. 迭代寻找最佳路径
tic
% 添加进度条
h = waitbar(0, ['已完成:0%   搜索中...   已用时:', num2str(toc)]);

i = 1; % 迭代次数初始化
ConstantNumberOfTimes = 0; % 最优解不变次数计数初始化
% 开始迭代,迭代有两个限制条件
% 1. 迭代次数达到iter_Max
% 2. 连续iter_Max*Thre次最优解不出现变化
while (i <= iter_Max) && (ConstantNumberOfTimes < iter_Max * Thre)
    RouteTable = zeros(m, n + 1); % 当前迭代次数下路径存放表初始化
    RouteStart = zeros(m, 1); % 蚁群初始位置
    % 初始化蚁群初始位置
    for j = 1:m
        temp = randperm(n);
        RouteStart(j) = temp(1);
    end

    % 确认蚁群初始位置和最终位置
    RouteTable(:, 1) = RouteStart;
    RouteTable(:, end) = RouteStart;

    % 计算该次迭代下,每只蚂蚁的路径
    for j = 1:m
        % 第j只蚂蚁的情况
        for k = 2:n
            % 计算第j只蚂蚁经过的第k的城市
            % 计算的依据转移概率
            TabooList = RouteTable(j, 1:k - 1); % 第j只蚂蚁经过了k-1座城市后的禁忌表
            % 计算第j只蚂蚁第k个城市的可选项
            RouteAllow_temp = ~ismember(CitysNameList, TabooList);
            RouteAllow = CitysNameList(RouteAllow_temp);
            % 计算第j只蚂蚁每个可选城市的转移概率
            P = zeros(1, length(RouteAllow));

            for l = 1:length(P)
                P(l) = (tau(TabooList(end), RouteAllow(l)))^alpha * (eta(TabooList(end), RouteAllow(l)))^beta;
            end

            P = P ./ sum(P);
            % 依据轮盘赌法确定第j只蚂蚁的下一个城市
            % 为什么用轮盘赌法不清楚,但是实际证明,该方法效果明显优于寻找最大转移概率
            P = cumsum(P);
            target_index = find(P >= rand);
            NextTarget = RouteAllow(target_index(1));
            RouteTable(j, k) = NextTarget;
        end

    end

    % 计算每只蚂蚁走过的路程
    Length = zeros(m, 1);

    for j = 1:m

        for k = 1:n
            Length(j) = Length(j) + CitysDistanceTable(RouteTable(j, k), RouteTable(j, k + 1));
        end

    end

    % 寻找该迭代次数下,蚁群中所走过的最短路径
    if i == 1
        [MinLength, MinLengthRouteIndex] = min(Length);
        RouteBest(i, :) = RouteTable(MinLengthRouteIndex, :);
        LengthBest(i) = MinLength;
    else
        [MinLength, MinLengthRouteIndex] = min(Length);
        % 该处判断的目的:让第二个迭代限制条件能够生效;同时使得画出的图像更加美观
        if LengthBest(i - 1) < MinLength
            RouteBest(i, :) = RouteBest(i - 1, :);
            LengthBest(i) = LengthBest(i - 1);
            ConstantNumberOfTimes = ConstantNumberOfTimes + 1;
        else
            RouteBest(i, :) = RouteTable(MinLengthRouteIndex, :);
            LengthBest(i) = MinLength;
            ConstantNumberOfTimes = 0;
        end

    end

    % 更新信息素
    Delta_Tau = zeros(n, n);

    for j = 1:m

        for k = 1:n
            Delta_Tau(RouteTable(j, k), RouteTable(j, k + 1)) = ...
                Delta_Tau(RouteTable(j, k), RouteTable(j, k + 1)) + ...
                Q / Length(j);
        end

    end

    tau = (1 - rho) * tau + Delta_Tau;
    % 生成进度条
    if mod(i, waitbarjiange) == 0
        waitbar(i / iter_Max, h, ['已完成:', num2str(i / iter_Max * 100), '%   搜索中...   已用时:', num2str(toc)]);
    end

    i = i + 1;
end

close(h)
%% VI. 绘图与打印结果

% 打印最短路径和最短距离
Shortest_Length = LengthBest(i - 1);
Shortest_Route = RouteBest(i - 1, :);
disp(['最短距离', num2str(Shortest_Length)]);
disp(['最短路径', num2str(Shortest_Route)]);
% 绘制路径最优解
figure(1)
plot(citys(Shortest_Route, 1), citys(Shortest_Route, 2), 'o-');

for i = 1:n
    text(citys(i, 1), citys(i, 2), ['   ' num2str(i)]);
end

text(citys(Shortest_Route(1), 1), citys(Shortest_Route(1), 2), '       起点');
text(citys(Shortest_Route(end - 1), 1), citys(Shortest_Route(end - 1), 2), '       终点');
xlabel('城市位置横坐标')
ylabel('城市位置纵坐标')
title(['蚁群算法优化路径(最短距离:' num2str(Shortest_Length) ')'])

% 绘制最短路径长度变化曲线
figure(2)
plot(1:i - 1, LengthBest(1:i - 1), 'b')
legend('最短距离')
xlabel('迭代次数')
ylabel('距离')
title('各代最短距离')

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 非常感谢您的提问!算法是一种优化算法,可以用来解决TSP问题。以下是使用Python实现算法解决TSP问题的步骤: 1. 构建TSP问题的图形模型,即将所有城市看作节点,将它们之间的距离看作边权,建立一个完全图。 2. 初始化蚂的位置,可以随机或指定。 3. 计算每只蚂在当前位置的信息素浓度和距离信息,根据这些信息计算蚂的转移概率。 4. 按照转移概率选择下一个节点,并更新蚂的位置。 5. 当所有蚂都走完一遍后,更新信息素。 6. 重复执行步骤3-5,直到满足终止条件。 Python中可以使用numpy、pandas等库来实现这个过程。代码实现可以参考以下的示例: ```python import numpy as np import pandas as pd # TSP问题的图形模型 graph = [[0, 10, 15, 20], [10, 0, 35, 25], [15, 35, 0, 30], [20, 25, 30, 0]] # 初始化参数 num_ants = 10 # 蚂数量 alpha = 1 # 信息素重要程度因子 beta = 2 # 启发式信息因子 rho = 0.5 # 信息素挥发因子 Q = 1 # 信息素增量常数 max_iter = 50 # 最大迭代次数 num_cities = len(graph) # 城市数量 # 初始化信息素矩阵 pheromone = np.ones((num_cities, num_cities)) / num_cities # 初始化最佳路径和距离 best_path = None best_distance = np.inf # 开始迭代 for i in range(max_iter): # 初始化蚂位置 ants = np.zeros((num_ants, num_cities), dtype=int) for ant in range(num_ants): ants[ant, 0] = np.random.randint(num_cities) # 蚂走路 for j in range(1, num_cities): for ant in range(num_ants): # 计算每只蚂在当前位置的信息素浓度和距离信息,根据这些信息计算蚂的转移概率 cur_city = ants[ant, j - 1] unvisited_cities = [city for city in range(num_cities) if city not in ants[ant, :j]] p = np.zeros(len(unvisited_cities)) for k, city in enumerate(unvisited_cities): p[k] = pheromone[cur_city, city] ** alpha * (1 / graph[cur_city][city]) ** beta p = p ### 回答2: 算法(Ant Colony Optimization)是一种启发式搜索算法,广泛应用于解决组合优化问题,其中包括旅行商问题(Traveling Salesman Problem,TSP)。在TSP问题中,旅行商需要找到一条最短路径经过所有城市并返回起点城市。 在Python中实现算法解决TSP问题的步骤如下: 1. 创建一个城市距离矩阵,用于存储各个城市之间的距离信息。 2. 初始化一群蚂和它们的起始位置,每只蚂都将选择一条路径。 3. 对于每只蚂,根据一定的概率选择下一个要访问的城市。这个概率与蚂到达城市的距离以及城市的信息素浓度相关。 4. 当所有蚂都完成一次路径选择后,更新城市之间的信息素浓度。 5. 重复步骤3和4,直到满足停止条件(达到最大迭代次数或找到最优解)为止。 6. 从所有迭代中选择出最优路径作为最终解。 在Python中可以使用numpy库来处理城市距离矩阵的计算和更新,可以使用random库生成随机数来模拟蚂的行为选择。使用matplotlib库可以可视化算法的执行过程和结果。 总结一句话:算法是一种基于蚂行为模拟的启发式搜索算法,通过概率选择城市路径和信息素的更新来解决TSP问题,Python中可以使用numpy和matplotlib库来实现。 ### 回答3: 算法是一种模拟群行为的优化算法,广泛应用于解决旅行商问题TSP)等优化问题。以下是一种使用Python实现算法解决TSP问题简要步骤。 首先,我们需要定义城市之间的距离矩阵。假设有N个城市,则可以使用一个N×N的矩阵来表示城市间的距离。 接下来,我们需要定义蚂的行为规则。每个蚂从一个城市出发,选择下一个要访问的城市,直到所有城市都被访问过。蚂的选择依赖于两个因素:启发式信息和信息素浓度。启发式信息是城市间距离的倒数,用来指导蚂选择最近的城市。信息素浓度是蚂走过的路径上留下的信息素的浓度,具有正向反馈的作用,引导蚂选择已经经过的路径。 然后,我们需要初始化蚂和信息素。蚂可以随机选择一个城市作为起点,信息素通常初始化为一个较小的常数。 接下来,进行群的迭代。每一次迭代,蚂按照行为规则选择下一个城市进行移动,直到所有城市都被访问一遍。在每次移动后,更新城市间的信息素浓度,增加经过路径上的信息素。 最后,选择蚂走过的路径中总长度最短的路径作为最优解。 需要注意的是,在每次迭代过程中,我们可以引入一些控制参数,如信息素挥发因子和信息素释放强度,以调节信息素的更新速度。 以上是一个简要的描述,实际实现过程可能还需要考虑更多细节。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RivenRussell

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值