蚁群算法(ACO)

1、蚁群算法基本内容

1.1 概念

(1)蚂蚁群体寻找食物的过程可以看做是一种启发式搜索过程。蚂蚁之间通过一种称为信息素(Pheromone)的物质实现了相互的间接通信,从而能够合作发现从蚁穴到食物源的最短路径。
(2)通过对这种群体智能行为的抽象建模,研究者提出了蚁群优化算法(Ant Colony Optimization, ACO),为最优化问题,尤其是组合优化问题的求解提供了一种强有力的手段。
(3)最初用于求解旅行商问题,现在已经成功用于许多组合优化问题。

1.2 基本原理

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

1.3 基本流程

从最初的空解开始,通过不断地向部分解添加解的成分而构建出一个完整的解。

2、旅行商问题

2.1 概念

旅行商问题:给定一系列城市位置,求解访问每一座城市一次并回到起始城市的最短回路,又称TSP问题。
TSP问题就是要找到图中的最短哈密尔顿回路。

2.2 基本思想与步骤

在这里插入图片描述
(1)蚂蚁从未访问的城市集中选择下一个要访问的城市,依据有两个:当前城市到下一城市边的信息素和启发式信息值(下面代码中的启发式信息值为两城市之间欧式距离的倒数)。

第 k 只蚂蚁从城市 i 选择下一城市时,选择到城市 j 的概率:

在这里插入图片描述
(2)每次迭代后信息素进行更新:

在这里插入图片描述
(3)参数含义:

在这里插入图片描述

3、旅行商问题代码分析

3.1 随机生成城市位置

由于后面关于蚁群算法的讨论,前提需固定在相同的城市位置,才能进行比较算法的运行效率。此处随机生成城市位置并将其保存到citys.mat内。

%随机生成城市横纵坐标
citys = zeros(40,2);%40个城市
citys(:,1) = randperm(2501,40)+499;%横坐标:产生500-3000范围内的不重复的40个数
citys(:,2) = randperm(2501,40)+499;%纵坐标:产生500-3000范围内的不重复的40个数
save citys.mat%将已经生成的城市位置保存到citys.mat中

randperm()函数:产生不重复的多个随机数。

3.2 计算任意两城市间距离

欧氏距离数学表达式:

在这里插入图片描述
代码:

%% 导入数据
load citys.mat%从citys.mat中读取数据,数据矩阵名为citys 

%% 计算城市间相互距离:欧式距离
fprintf('Computing Distance Matrix... \n');%按指定的格式将变量的值输出到屏幕或指定文件
n = size(citys,1);%城市个数为n
D = zeros(n,n);%城市间距离矩阵:D
for i = 1:n
    for j = 1:n
        if i ~= j
            D(i,j) = sqrt(sum((citys(i,:) - citys(j,:)).^2));
        else
            D(i,j) = 1e-4;      
        end
    end    
end

3.3 迭代寻找最佳路径

%% 初始化参数
fprintf('Initializing Parameters... \n');
m = 50;                              % 蚂蚁数量
alpha = 1;                           % 信息素重要程度因子
beta = 5;                            % 启发函数重要程度因子
rho = 0.1;                           % 信息素挥发因子
Q = 1;                               % 常系数
Eta = 1./D;                          % 启发函数
Tau = ones(n,n);                     % 信息素矩阵
Table = zeros(m,n);                  % 路径记录表:记录每只蚂蚁的路径
iter = 1;                            % 迭代次数初值
iter_max = 150;                      % 最大迭代次数 
Route_best = zeros(iter_max,n);      % 各代最佳路径       
Length_best = zeros(iter_max,1);     % 各代最佳路径的长度  
Length_ave = zeros(iter_max,1);      % 各代路径的平均长度  

%% 迭代寻找最佳路径
figure; 
while iter <= iter_max
    fprintf('迭代第%d次\n',iter);
    
    % 随机产生各个蚂蚁的起点城市:start
      start = zeros(m,1);
      for i = 1:m
          temp = randperm(n);%产生1到n的整数的无重复的随机排列
          start(i) = temp(1);%每只蚂蚁的起点城市
      end
      
      Table(:,1) = start; %更新路径记录表的起点城市
      % 构建解空间
      citys_index = 1:n;%访问1~n这n个城市
      
      % 逐个蚂蚁路径选择
      for i = 1:m
          % 逐个城市路径选择
         for j = 2:n
             tabu = Table(i,1:(j - 1));           % 已访问的城市集合(禁忌表)
             allow_index = ~ismember(citys_index,tabu);%返回与citys_index大小相同的逻辑数组,如果citys_index中的元素不属于tabu,那么citys_index中的相应位置返回1(true),否则返回0(false)。
             allow = citys_index(allow_index);  % 待访问的城市集合
             P = allow;
             % 计算城市间转移概率
             for k = 1:length(allow)
                 P(k) = Tau(tabu(end),allow(k))^alpha * Eta(tabu(end),allow(k))^beta;
             end
             P = P/sum(P);
             % 轮盘赌法选择下一个访问城市:target
             Pc = cumsum(P); %计算一个数组各行的累加值    
            target_index = find(Pc >= rand); 
            target = allow(target_index(1));
            Table(i,j) = target;
         end
      end
      
      % 计算各个蚂蚁的路径距离
      Length = zeros(m,1);
      for i = 1:m
          Route = Table(i,:);
          for j = 1:(n - 1)
              Length(i) = Length(i) + D(Route(j),Route(j + 1));
          end
          Length(i) = Length(i) + D(Route(n),Route(1));%注意:最后还要回到起点城市
      end
      
      % 计算最短路径距离及平均距离
      if iter == 1
          [min_Length,min_index] = min(Length);
          Length_best(iter) = min_Length;  
          Length_ave(iter) = mean(Length);
          Route_best(iter,:) = Table(min_index,:);
      else
          [min_Length,min_index] = min(Length);
          Length_best(iter) = min(Length_best(iter - 1),min_Length);
          Length_ave(iter) = mean(Length);
          if Length_best(iter) == min_Length
              Route_best(iter,:) = Table(min_index,:);
          else
              Route_best(iter,:) = Route_best((iter-1),:);
          end
      end
      
      % 更新信息素
      Delta_Tau = zeros(n,n);
      % 逐个蚂蚁计算
      for i = 1:m
          % 逐个城市计算
          for j = 1:(n - 1)
              Delta_Tau(Table(i,j),Table(i,j+1)) = Delta_Tau(Table(i,j),Table(i,j+1)) + Q/Length(i);
          end
          Delta_Tau(Table(i,n),Table(i,1)) = Delta_Tau(Table(i,n),Table(i,1)) + Q/Length(i);%回到起点城市时的信息素
      end
      Tau = (1-rho) * Tau + Delta_Tau;    
      
 % figure;
 %最佳路径的迭代变化过程
    [Shortest_Length,index] = min(Length_best(1:iter));
    Shortest_Route = Route_best(index,:);
    plot([citys(Shortest_Route,1);citys(Shortest_Route(1),1)],...
    [citys(Shortest_Route,2);citys(Shortest_Route(1),2)],'o-');
    pause(0.3);
    iter = iter + 1;
    Table = zeros(m,n);% 迭代次数加1,清空路径记录表
 % end
end

3.4 绘制结果

%% 结果显示
[Shortest_Length,index] = min(Length_best);
Shortest_Route = Route_best(index,:);
disp(['最短距离:' num2str(Shortest_Length)]);
disp(['最短路径:' num2str([Shortest_Route Shortest_Route(1)])]);

%% 绘图
figure(1)
plot([citys(Shortest_Route,1);citys(Shortest_Route(1),1)],...
     [citys(Shortest_Route,2);citys(Shortest_Route(1),2)],'o-');
grid on
for i = 1:size(citys,1)
    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),citys(Shortest_Route(end),2),'       终点');
xlabel('城市位置横坐标')
ylabel('城市位置纵坐标')
title(['蚁群算法优化路径(最短距离:' num2str(Shortest_Length) ')'])
figure(2)
plot(1:iter_max,Length_best,'b',1:iter_max,Length_ave,'r:')
legend('最短距离','平均距离')
xlabel('迭代次数')
ylabel('距离')
title('各代最短距离与平均距离对比')

3.5 运行结果

(1)

在这里插入图片描述
分析:图中圆圈代表的是城市,圆圈旁边的数字是该城市在原始数据矩阵内的序号。图中展示了哈密顿回路,起点城市的序号为 6 ,终点城市的序号为 12 。

(2)

在这里插入图片描述

分析:最短距离曲线在迭代 80 次左右开始收敛。平均距离曲线变化频率高,呈多峰形态。

(3)

在这里插入图片描述
分析:运行结束在控制台界面输出了最短距离为 13498.506 ,并且输出了构成哈密顿回路的路径。

(4)

在这里插入图片描述
分析:该代码总运行时间为 65.798 s。

4、运行效率的探究

已知参数有:

  • 信息素重要程度因子alpha
  • 启发函数重要程度因子beta
  • 信息素挥发因子rho

由于最短距离不仅受到以上参数的影响,还与起点城市、终点城市的选取有很大关系。而起点城市、终点城市在代码内随机选取,因此最短距离不参与比较。

4.1 alpha与beta固定不变时,rho变化

alpha=1,beta=5:

rho 最短距离 总运行时间 最短距离收敛时迭代数
0.1 13498.506 65.798s 80
0.2 13535.7504 61.231s 47
0.3 13592.2471 60.948s 29
0.4 13609.3693 60.812s 51
0.5 13552.8726 61.294s 68

由表格可看出:当alpha与beta固定不变时,随着rho的增大,总运行时间先减小后维持在[60,61]范围内徘徊;最短距离达到收敛时迭代的次数先减少后增大。当rho取值在[0.1,0.5]内的一位小数时,rho=0.3可达到最理想结果。
(此处的最理想结果并不是在各方面都达到最优,而是处于一种平衡的状态。有的方面达到最优,有的方面处于中等状态,但不存在某方面达到最差。)

4.2 alpha与rho固定不变时,beta变化

alpha=1,rho=0.1:

beta 最短距离 总运行时间 最短距离收敛时迭代数
1 14705.0946 62.247s 118
5 13498.506 65.798s 80
7 13535.7504 60.440s 90
9 13420.8768 61.002s 34
10 13609.3693 61.236s 50
11 13609.3693 61.209s 47
13 13538.0133 60.857s 68

由表格可看出:当alpha与rho固定不变时,随着beta的增大,总运行时间先增大后减少至维持在[60,62]范围内徘徊;最短距离达到收敛时迭代的次数先减少后维持在[30,50]范围内徘徊。当beta取值在[1,13]内的整数时,beta=9可达到最理想结果。

4.3 beta与rho固定不变时,alpha变化

beta=5,rho=0.1:

alpha 最短距离 总运行时间 最短距离收敛时迭代数
1 13498.506 65.798s 80
3 13630.1098 66.437s 71
5 113678.5614 67.093s 48
7 13493.5918 66.672s 38
8 13684.4764 61.761s 43
9 13703.9844 63.069s 45
11 13615.2505 61.799s 43

由表格可看出:当beta与rho固定不变时,随着alpha的增大,总运行时间先增大后维持在[61,64]范围内徘徊;最短距离达到收敛时迭代的次数先减少后维持在[43,45]范围内徘徊。当alpha取值在[1,11]内的整数时,alpha=7可达到最理想结果。

4.4 alpha=7,beta=9,rho=0.3时

(1)
在这里插入图片描述
分析:最短距离为 13531.4545 ,起点城市的序号为 31 ,终点城市的序号为 30。

(2)
在这里插入图片描述
分析:最短距离曲线在迭代 11 次左右开始收敛。平均距离曲线变化频率高,呈多峰形态。

(3)
在这里插入图片描述
(4)
在这里插入图片描述
分析:该代码总运行时间为 61.500 s。

发布了13 篇原创文章 · 获赞 6 · 访问量 2291

猜你喜欢

转载自blog.csdn.net/weixin_44060222/article/details/102916573
今日推荐