计算智能——基于蚁群算法的TSP问题(课堂实验)

一.蚁群算法基本原理

蚁群算法(AG)是一种模拟蚂蚁觅食行为的模拟优化算法,它是由意大利学者Dorigo M等人于1991年首先提出,并首先使用在解决TSP旅行商问题)上。之后,又系统研究了蚁群算法的基本原理和数学模型。

其基本原理:
1、蚂蚁在路径上释放信息素。

2、碰到还没走过的路口,就随机挑选一条路走。同时,释放与路径长度有关的信息素。

3、信息素浓度与路径长度成反比。后来的蚂蚁再次碰到该路口时,就选择信息素浓度较高路径。

4、最优路径上的信息素浓度越来越大。

5、最终蚁群找到最优寻食路径。

二.基于TSP问题的基本蚁群算法

TSP求解中,假设蚁群算法中的每只蚂蚁是具有以下特征的简单智能体:

每次周游,每只蚂蚁在其经过的支路(i,j)上都留下信息素。

‚蚂蚁选择城市的概率与城市之间的距离和当前连接支路上所包含的信息素余量有关。

ƒ为了强制蚂蚁进行合法的周游,直到一次周游完成后,才允许蚂蚁游走已访问过的城市(这可由禁忌表来控制)。

基本蚁群的最重要的两个过程:

(1)状态转移

(2)信息素更新

(1)状态转移

为了避免残留信息素过多而淹没启发信息,在每只蚂蚁走完一步或者完成对所有n个城市的遍历(也即一个循环结束)后,要对残留信息进行更新处理。

由此,t+n时刻在路径(i,j)上的信息量可按如下规则进行调整:
在这里插入图片描述

(2)信息素更新模型

蚁周模型(Ant-Cycle模型)

蚁量模型(Ant-Quantity模型)

蚁密模型(Ant-Density模型)

区别:

1.蚁周模型利用的是全局信息,即蚂蚁完成一个循环后更新所有路径上的信息素;

2.蚁量和蚁密模型利用的是局部信息,即蚂蚁完成一步后更新路径上的信息素。

在这里插入图片描述
下面的代码用的是蚁量模型来更新信息素。

三.代码验证学习

导入数据:随机生成36行2列的数据作为36个点的横坐标和纵坐标
这36个点代表着36个不同的城市。

%% 导入数据
citys=round(1000*rand(36,2));
save citys;
load citys;

重要参数的初始化:

%% 初始化参数
fprintf('Initializing Parameters... \n');
m = 50;                              % 蚂蚁数量
alpha = 1;                           % 信息素重要程度因子
beta = 5;                            % 启发函数重要程度因子 权衡信息素和距离谁更重要  可以探讨这两个如果变化的区别
rho = 0.1;                           % 信息素挥发因子   能经过多少代就能有更少的迭代次数 为什么 三个参数改变和迭代的关系
Q = 1;                               % 常系数
Eta = 1./D;                          % 启发函数
Tau = ones(n,n);                     % 信息素矩阵   记录第i个城市到第j个城市的信息素
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);      % 各代路径的平均长度  

城市间的距离计算:欧式距离

%% 计算城市间相互距离
fprintf('Computing Distance Matrix... \n');
n = size(citys,1);
D = zeros(n,n);
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

迭代寻找最佳路径:

%% 迭代寻找最佳路径
figure;
while iter <= iter_max
    fprintf('迭代第%d次\n',iter);
    % 随机产生各个蚂蚁的起点城市
      start = zeros(m,1);
      for i = 1:m
          temp = randperm(n);
          start(i) = temp(1);
      end
      Table(:,1) = start; 
      % 构建解空间
      citys_index = 1:n;
      % 逐个蚂蚁路径选择
      for i = 1:m
          % 逐个城市路径选择
         for j = 2:n
             tabu = Table(i,1:(j - 1));           % 已访问的城市集合(禁忌表) 访问过的城市不能再访问 保留接下来能访问的城市
             allow_index = ~ismember(citys_index,tabu);
             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; %第k个蚂蚁被选中的概率
             end
             P = P/sum(P); %归一化的概率
             % 轮盘赌法选择下一个访问城市
             Pc = cumsum(P);     %自动帮你做出小格区间 做出有x个区间的0/1分布
            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;  %更新所有边的信息素的过程
    % 迭代次数加1,清空路径记录表

 %   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);

 % end
end

结果显示:

%% 结果显示
[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('各代最短距离与平均距离对比')  %绕玩一圈回到原点的值

结果讨论:

迭代次数:150
信息素重要程度因子:1
启发函数重要程度因子:5
信息素挥发因子:0.1
运行结果:
在这里插入图片描述

图上的标号为随机生成点的编号而非路线的顺序,起点和终点的标出则确定的是起点和终点的顺序。
表示在当前条件下,从第2个点出发再从第12个点回到第2个点的路线总和最短
在这里插入图片描述

该图表示在差不多60多代左右就已经达到最短距离的稳定值。

对四个重要参数的讨论

3.1对信息素挥发因子的探讨

注意这里要保持数据的一致,不要再随机生成新的数据集。
信息素重要程度因子:1
启发函数重要程度因子:5
信息素挥发因子:0.1
运行结果:
在这里插入图片描述

在这里插入图片描述

信息素重要程度因子:1
启发函数重要程度因子:5
信息素挥发因子:0.2
在这里插入图片描述
在这里插入图片描述

信息素重要程度因子:1
启发函数重要程度因子:5
信息素挥发因子:0.3
在这里插入图片描述

在这里插入图片描述

信息素重要程度因子:1
启发函数重要程度因子:5
信息素挥发因子:0.8
在这里插入图片描述
在这里插入图片描述

小结:当信息素重要程度因子为1,启发函数重要程度因子为5,这两个变量固定不变时。改变信息素挥发因子为0.1,0.2,0.3,0.8来观察两幅图的结果对比后发现,当其值为0.1,0.2,0.3的时候其最小值没有变化都是相同的值,只有迭代次数的大小改变了。且当其值在一定区间内越大的时候,收敛速度越快。0.1-0.3相比,0.3的收敛速度明显比0.1快很多。分析其原因,是因为当其值不大的时候,在各路径上残留的信息素过多,导致无效的路径继续被搜索,影响到算法的收敛速度。但当其值等于0.8时,最优值受到了影响,变得比0.3时大了一些,因为当其过大时,无效的路径虽然可能被排除搜索但不能保证有效的路径也被放弃搜索,影响到了最优值的选取。所以这里暂时让其值=0.3因为此时在做的实验中,暂时效果最好。

3.2对信息素重要程度因子的探讨

信息素重要程度因子:1
启发函数重要程度因子:5
信息素挥发因子:0.3
在这里插入图片描述
在这里插入图片描述
信息素重要程度因子:2
启发函数重要程度因子:5
信息素挥发因子:0.3
在这里插入图片描述
在这里插入图片描述

信息素重要程度因子:3
启发函数重要程度因子:5
信息素挥发因子:0.3
在这里插入图片描述
在这里插入图片描述

信息素重要程度因子:8
启发函数重要程度因子:5
信息素挥发因子:0.3
在这里插入图片描述
在这里插入图片描述

小结:当启发函数重要程度因子为5,信息素挥发因子为0.3这两个变量固定不变时。改变信息素重要程度因子为1,2,3,8来观察两幅图的变化。当其值为2时,其最优路径已经比1时变大了,但是差别不是非常大,当其值为3和8时候,最优路径虽然都比其值为1大,但是稳定在了相同的一个值,可见信息素重要程度因子越大,蚂蚁选择之前走过的路径的可能性就越大,搜索路径的随机性减弱。其值越小,蚁群搜索范围就会减少,容易陷入局部最优值。但对比四次实验的第二幅图,当其值改变时,收敛速度的变化没有很大的影响。在我做的实验里选择其值为1时,优化效果最佳,接下来的实验让其保持1值。

3.3对启发函数重要因子的探讨

信息素重要程度因子:1
启发函数重要程度因子:5
信息素挥发因子:0.3
在这里插入图片描述

在这里插入图片描述

信息素重要程度因子:1
启发函数重要程度因子:1
信息素挥发因子:0.3
在这里插入图片描述
在这里插入图片描述
信息素重要程度因子:1
启发函数重要程度因子:2
信息素挥发因子:0.3
在这里插入图片描述
在这里插入图片描述

信息素重要程度因子:1
启发函数重要程度因子:3
信息素挥发因子:0.3
在这里插入图片描述
在这里插入图片描述
信息素重要程度因子:1
启发函数重要程度因子:8
信息素挥发因子:0.3
在这里插入图片描述
在这里插入图片描述

小结:当信息素重要度因子为1,信息素挥发因子为0.3这两个变量固定不变时。改变启发函数重要程度因子为1,2,3,5,8来观察两幅图的变化。发现,当其值为1时,迭代150次的优化效果比之前差。当其值未2,3,5时候,最优值稳定在同一个数值,但是在2,3时,其收敛情况很不稳定,最终收敛的时间长,当其为8时,收敛的速度比之前好一些,但是优化的效果又变差了。可见当其值越大,蚁群就越容易选择局部较短的路径,算法的收敛速度会加快,但是随机性不高,容易得到局部的相对最优解。
所以这里的做过实验的值里面选择其值为5时效果最佳。

3.4对蚁群数量的探讨

根据之前的实验结果,选择以下3个参数不变,来研究蚁群的数量影响“
信息素重要程度因子:1
启发函数重要程度因子:5
信息素挥发因子:0.3
选择蚁群的数量为30,50,80来进行比较
m=30
在这里插入图片描述
在这里插入图片描述

m=50
在这里插入图片描述
在这里插入图片描述
m=80
在这里插入图片描述
在这里插入图片描述

小结:因为这里的距离精度没有保留的那么高,所以蚁群数量的影响在第一幅图中没有办法看出区别,但是对比第二幅图,当蚁群的数量增加,收敛速度会减慢。因为蚁群数量越大,得到的最优解越精确,但是会产生重复解,随着算法接近最优值的收敛,信息正反馈的作用降低,大量的重复工作会消耗时间,增加了收敛的速度。

最后在网上找到四个值的合适选择范围:
在这里插入图片描述

通过我自己的实验得到我的合适选择是:
信息素重要程度因子:1
启发函数重要程度因子:5
信息素挥发因子:0.3
蚁群数:50

发布了12 篇原创文章 · 获赞 3 · 访问量 1273

猜你喜欢

转载自blog.csdn.net/weixin_43822880/article/details/102913822
今日推荐