数学建模:matlab蚁群算法解决TSP问题

蚁群算法的来源

很久以前,生物学家就对蚂蚁捕食行为很好奇。因为,可能大家不知道,蚂蚁的视力特别差,你可以把它当成瞎子,可是每次却都能找到食物,并且从它所找到的路径,还是从洞穴到食物的最短路径。大家可以想一想,每次你的桌子上有掉一颗糖,过不了多久,就立马有蚂蚁出现了,而且还是一成群的蚂蚁沿着同一条线路过来的。这是为什么呢?难道是蚂蚁的鼻子很灵敏吗?

后来生物学家们经过长时间的研究发现,并不是蚂蚁的鼻子很灵敏,而是他们之间有一种很特别的信息传递方式——信息素,正是这种特别的信息传递方式,使得蚂蚁这种生物,不会迷路。

言归正传,这个信息素是怎么用的呢?其实是这样的,蚂蚁在行走的过程会释放一种化学物质,这种化学物质就叫“信息素”,这是用来标识自己的行走路径。而在寻找食物的过程中,蚂蚁根据这个信息素的浓度来选择行走的方向,最终就到达了食物的所在地。

更形象的理解一下蚁群算法

在这里插入图片描述
假设蚂蚁们在A点,食物在B点,蚂蚁要去食物有两条路径,即路径a和路径b。现在A点有两只蚂蚁要去取食物,假设两只蚂蚁分别名字分别为蚂蚁a和蚂蚁b,即蚂蚁a沿a路径走,蚂蚁b沿b路径走。

现在咱们假设两只蚂蚁的速率、留下信息素速率和信息素挥发速率是一样的。

那么显然蚂蚁a比蚂蚁b更快到达B点,即a路径的信息素已经布满a路径(假设在a路径最开始端的信息素没有挥发完),那么b路径的信息素目前只分布到一半(可能到红叉之前),那么现在蚂蚁a开始取上食物往回走。
在这里插入图片描述
蚂蚁a往回走会选择信息素浓度高的路径,即a路径,那么蚂蚁a沿原路径回到A点的路上时,蚂蚁b到达B点,蚂蚁b也要取上食物往回走,也要沿信息素浓度最高的路径走,因为a路径蚂蚁a走过两次,所以信息素浓度比b路径高,那么蚂蚁b也会沿着a路径往回走,那么此时a路径的浓度又会增加。

那么,每当以后有蚂蚁要从A点去B点取食物,便会沿着信息素浓度高的路径,即a路径,那么a路径的信息素浓度也会越来越高。那么信息素最多的路径即为最短路径。

蚁群算法与TSP问题的关系

蚁群算法就是蚂蚁寻找食物的过程,而把多个食物放在不同的地方,就是著名的TSP(Traveling Salesman Problem)问题,而信息素分布最的路线就是最短的路径。

蚂蚁算法的基本原理

  1. 每只蚂蚁从一个城市走到另一个城市的过程中都会在路径上释放信息素,并且蚂蚁选择下一个城市的依据是一个概率公式,如下:
    P i j k ( t ) = { τ i j α ( t ) η i j β ( t ) ∑ s ∉ t a b u k τ i s α ( t ) ⋅ η i s β ( t ) , j ∉ t a b u k 0                      , o t h e r s P^k_{ij}(t)= \left\{ \begin{aligned} \frac {\tau^\alpha_{ij}(t)\eta^\beta_{ij}(t)}{\sum_{s\notin tabu_k}\tau ^\alpha _{is}(t)·\eta ^\beta_{is}(t) }, j \notin tabu_k\\0~~~~~~~~~~~~~~~~~~~~,others \end{aligned} \right. Pijk(t)=s/tabukτisα(t)ηisβ(t)τijα(t)ηijβ(t),j/tabuk0                    ,others
      上式中,各个符号的意义如下:

α − − 信 息 素 启 发 式 因 子 , 它 反 映 了 信 息 素 对 蚂 蚁 路 径 选 择 的 作 用 ; β − − 期 望 启 发 式 因 子 , 它 反 映 了 信 息 素 在 蚂 蚁 选 择 路 径 时 被 重 视 的 程 度 ; d i j − − 城 市 i 和 j 之 间 的 距 离 ; η i j ( t ) − − 启 发 函 数 , 表 达 式 为 η i j ( t ) = 1 d i j ; t a b u k − − 禁 忌 表 , 记 录 蚂 蚁 k 当 前 所 走 过 的 城 市 ; τ i j − − 城 市 i 到 城 市 j 的 路 径 上 的 信 息 素 的 量 ; \alpha-- 信息素启发式因子,它反映了信息素对蚂蚁路径选择的作用;\\ \beta -- 期望启发式因子,它反映了信息素在蚂蚁选择路径时被重视的程度;\\ d_{ij} -- 城市i和j之间的距离;\\ \eta_{ij}(t)-- 启发函数,表达式为\eta_{ij}(t)=\frac{1}{d_{ij}};\\ tabu_k -- 禁忌表,记录蚂蚁k当前所走过的城市;\\ \tau_{ij} -- 城市i到城市j的路径上的信息素的量;\\ αβdijij;ηij(t)ηij(t)=dij1tabukkτijij

2. 蚂蚁留下的信息素,因为是化学物质,因此随着时间的过去信息素也应该要以一定的速率挥发。根据不同的规则我们可以将蚁群算法分为三种模型——蚁周模型(Ant-Cycle)、蚁量模型(Ant-Quantity)和蚁密模型(Ant-Density)。
 
区别:
(1).蚁周模型利用的是全局信息,即蚂蚁完成一个循环后更新所有路径上的信息素;
(2).蚁量和蚁密模型利用的是局部信息,即蚂蚁完成一步后更新路径上的信息素。

通常使用的是蚁周模型,故本文只介绍蚁周模型。
 
根据上面所提供的信息,我们可以知道,当所有的蚂蚁完成一次路径循环后,才更新信息素。因此路径上的信息素应该分为两部分:之前未挥发所残留的信息素 + 经过当前循环所有蚂蚁在经过该路径后所留下的信息素。用公式表述如下:
τ ( t + n ) = ( 1 − ρ ) ⋅ τ i j ( t ) + Δ τ i j ( t , t + n ) Δ τ i j ( t , t + n ) = ∑ k = 1 m Δ τ i j k ( t , t + n ) \tau (t+n)=(1-\rho)·\tau_{ij}(t)+\Delta \tau_{ij}(t,t+n)\\ \Delta \tau_{ij}(t,t+n)=\sum^m_{k=1} \Delta \tau^k_{ij}(t,t+n) τ(t+n)=(1ρ)τij(t)+Δτij(t,t+n)Δτij(t,t+n)=k=1mΔτijk(t,t+n)
其 中 , ρ − − 信 息 素 挥 发 因 子 , ρ ∈ [ 0 , 1 ) ρ ∈ [ 0 , 1 ) ; Δ τ i j ( t , t + n ) − − 经 过 一 次 循 环 后 城 市 i 到 城 市 j 的 路 径 上 的 信 息 素 的 增 量 ;     ( t , t + n ) − − 走 过 n 步 以 后 蚂 蚁 即 完 成 一 次 循 环 ; Δ τ i j k ( t , t + n ) − − 表 示 经 过 一 次 循 环 后 蚂 蚁 k 在 它 走 过 的 路 上 的 信 息 素 增 量 。 其中, \rho -- 信息素挥发因子,ρ∈[0,1)ρ∈[0,1);\\ Δτ_{ij}(t,t+n) -- 经过一次循环后城市i到城市j的路径上的信息素的增量;  \\ (t,t+n) -- 走过n步以后蚂蚁即完成一次循环;\\ Δτ_{ij}^k(t,t+n) -- 表示经过一次循环后蚂蚁k在它走过的路上的信息素增量。\\ ρρ[0,1)ρ[0,1)Δτij(t,t+n)ij  (t,t+n)nΔτijk(t,t+n)k
 好了,现在我们的未挥发所残留的信息素很好解,定义一个信息素挥发因子ρρ便能解决。但是,经过一次循环所有蚂蚁留下的信息素该怎么定义?在蚁周模型中,它被定义如下:
Δ τ i j k ( t , t + n ) = { Q L k                     A n t k w a l k t h o u g h p a t h ( i , j ) 0                                                            o t h e r \Delta \tau^k_{ij}(t,t+n)= \left\{ \begin{aligned} \frac {Q}{L_k} ~~~~~~~~~~~~~~~~~~~Ant k walk though path (i,j)\\0~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ other \end{aligned} \right. Δτijk(t,t+n)=LkQ                   Antkwalkthoughpath(i,j)0                                                          other
  它表明,蚂蚁留下的信息素跟它走过的完整路径的总长度有关。越长则留下的信息素越少,这个应该很好理解。为了找到更短的路径,就应该让短的路径信息素浓度高些。

3.蚁群算法基本步骤
(1) 参数初始化:

通常可以按照以下策略来进行参数组合设定:

确定蚂蚁数目
参数粗调:即调整取值范围较大的α,β及Q;
参数微调:即调整取值范围较小的ρ;
(2) 随机将蚂蚁放于不同出发点,对每只蚂蚁计算其下个访问城市,直到所有蚂蚁访问完所有城市。
(3)计算蚂蚁经过的路径长度
(4) 判断是否达到最大迭代次数,若否,返回步骤2;是,结束程序。
(5) 输出结果,并根据需要输出寻优过程中的相关指标,如运行时间、收敛迭代次数等。

matlab解决TSP问题的代码

下面是各个地方的xy坐标

1304 2312
3639 1315
4177 2244
3712 1399
3488 1535
3326 1556
3238 1229
4196 1004
4312 790
4386 570
3007 1970
2562 1756
2788 1491
2381 1676
1332 695
3715 1678
3918 2179
4061 2370
3780 2212
3676 2578
4029 2838
4263 2931
3429 1908
3507 2367
3394 2643
3439 3201
2935 3240
3140 3550
2545 2357
2778 2826
2370 2975

%% 蚁群算法求解TSP问题


%% 清空环境变量
clear 
clc

%% 导入数据
load citys_data.mat

%% 计算城市间相互距离
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

%% 初始化参数
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 = 200;                      % 最大迭代次数 
Route_best = zeros(iter_max,n);      % 各代最佳路径       
Length_best = zeros(iter_max,1);     % 各代最佳路径的长度  
Length_ave = zeros(iter_max,1);      % 各代路径的平均长度  

%% 迭代寻找最佳路径
while iter <= iter_max
    % 随机产生各个蚂蚁的起点城市
      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;
             end
             P = P/sum(P);
             % 轮盘赌法选择下一个访问城市
             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;
    % 迭代次数加1,清空路径记录表
    iter = iter + 1;
    Table = zeros(m,n);
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('各代最短距离与平均距离对比')

最短距离:15601.9195
最短路径:14  12  13  11  23  16   5   6   7   2   4   8   9  10   3  18  17  19  24  25  20  21  22  26  28  27  30  31  29   1  15  14
>> 

在这里插入图片描述在这里插入图片描述
转载请标明出处,谢谢!。

如果感觉本文对您有帮助,请留下您的赞,您的支持是我坚持写作最大的动力,谢谢!

  • 16
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的MATLAB蚁群算法求解TSP问题的代码示例: ```matlab % TSP问题求解的蚁群算法 % 假设城市数为10 % 城市坐标数据保存在一个10 x 2的矩阵中,第i行表示第i个城市的横纵坐标 city = [20 20; 30 40; 50 100; 60 20; 80 80; 90 60; 110 10; 120 100; 130 50; 140 70]; num_city = size(city, 1); % 城市数 num_ant = 20; % 蚂蚁数 alpha = 1; % 信息素重要程度因子 beta = 5; % 启发式因子 rho = 0.1; % 信息素挥发因子 Q = 1; % 常系数 iter_num = 200; % 迭代次数 % 计算城市间距离矩阵 dist = zeros(num_city, num_city); for i = 1:num_city for j = 1:num_city if i ~= j dist(i, j) = sqrt(sum((city(i,:) - city(j,:)).^2)); end end end % 初始化信息素矩阵和启发式因子矩阵 pheromone = ones(num_city, num_city); eta = ones(num_city, num_city)./dist; % 开始迭代 best_route = []; % 最佳路径 best_length = Inf; % 最短路径长度 for iter = 1:iter_num % 每只蚂蚁随机选择起点城市 ant_pos = randi(num_city, num_ant, 1); route = zeros(num_ant, num_city); % 记录每只蚂蚁的路径 length_route = zeros(num_ant, 1); % 记录每只蚂蚁的路径长度 for k = 1:num_ant % 开始走路 for i = 2:num_city % 计算当前城市到其他城市的转移概率 prob = pheromone(ant_pos(k),:).^alpha .* eta(ant_pos(k),:).^beta; prob(ant_pos(k)) = 0; % 当前城市不可再次访问 prob = prob ./ sum(prob); % 归一化概率 % 轮盘选择下一个城市 cum_prob = cumsum(prob); next_city = find(cum_prob >= rand, 1); % 记录路径和路径长度 route(k, i) = next_city; length_route(k) = length_route(k) + dist(ant_pos(k), next_city); ant_pos(k) = next_city; end % 回到起点城市,形成环路 length_route(k) = length_route(k) + dist(ant_pos(k), route(k,1)); end % 更新信息素 delta_pheromone = zeros(num_city, num_city); for k = 1:num_ant for i = 1:num_city-1 delta_pheromone(route(k,i), route(k,i+1)) = delta_pheromone(route(k,i), route(k,i+1)) + Q/length_route(k); delta_pheromone(route(k,i+1), route(k,i)) = delta_pheromone(route(k,i+1), route(k,i)) + Q/length_route(k); end delta_pheromone(route(k,num_city), route(k,1)) = delta_pheromone(route(k,num_city), route(k,1)) + Q/length_route(k); delta_pheromone(route(k,1), route(k,num_city)) = delta_pheromone(route(k,1), route(k,num_city)) + Q/length_route(k); end pheromone = (1-rho).*pheromone + delta_pheromone; % 更新最佳路径 [min_length, min_idx] = min(length_route); if min_length < best_length best_length = min_length; best_route = [route(min_idx, :), route(min_idx, 1)]; end % 输出当前迭代结果 fprintf('Iteration: %d, Best Length: %f\n', iter, best_length); end % 画出最佳路径 figure; plot(city(:,1), city(:,2), 'ro'); hold on; plot(city(best_route,1), city(best_route,2), 'b-'); ``` 这个代码中,我们使用了一个10 x 2的矩阵存储了10个城市的坐标信息。在计算城市间距离矩阵之后,我们使用了一个蚂蚁数为20的蚁群算法来求解TSP问题。在每次迭代中,每只蚂蚁都随机选择一个起点城市,然后按照概率转移规则走完所有城市,并回到起点城市形成环路。在每次迭代结束后,我们根据蚂蚁的路径更新信息素矩阵,并记录最短路径和最佳路径。最后,我们使用MATLAB的绘图功能画出了最佳路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值