蚁群算法求解TSP问题Matlab代码

目录

蚁群算法

自然界蚂蚁觅食行为

蚁群算法原理

举个栗子!通俗理解~

蚁群算法步骤

适用问题

模型评价

模型优缺点

TSP问题

例题:已知敌方 100 个目标的经度、纬度(旅行商问题TSP的变种)

1.主程序文件:

2.create_distance_matrix.m文件:计算距离矩阵D

3.haversine_distance.m文件:计算飞机在圆圆的地球上的飞行距离的函数


蚁群算法

自然界蚂蚁觅食行为

  1. 蚂蚁的觅食路径:蚂蚁在寻找食物时,会随机选择路径。当蚂蚁找到食物后,会在返回巢穴的路上释放信息素
  2. 信息素的作用:信息素是一种化学物质,能够吸引其他蚂蚁。信息素的浓度越高,蚂蚁越有可能选择这条路径。
  3. 信息素的挥发:信息素会随着时间的推移而挥发。较短路径上的信息素浓度会更快增加,因为这些路径被更多蚂蚁频繁使用。

蚁群算法原理

举个栗子!通俗理解~

假设有一群蚂蚁在一个迷宫中寻找最短路径到达食物源,它们的行为可以总结如下:

  1. 起点:蚂蚁从迷宫入口随机出发。
  2. 路径选择:蚂蚁在前进过程中会选择信息素浓度较高的路径,但也有一定概率选择其它路径,这保证了探索新路径的可能性(随机性)。
  3. 信息素沉积:找到食物的蚂蚁返回巢穴,在路上会释放信息素,标记这条路径。
  4. 路径优化:随着更多蚂蚁发现并使用较短路径,该路径上的信息素浓度增加,吸引更多蚂蚁选择这条路径,逐渐找到最短路径。

蚁群算法模拟了上述蚂蚁觅食的过程来解决优化问题。

  1. 初始化:在问题空间上初始化若干蚂蚁和信息素矩阵。
  2. 构建解:每只蚂蚁在搜索过程中根据概率规则(信息素和启发式信息)选择下一步路径,直到构建完整解。
  3. 更新信息素:根据蚂蚁构建的解和路径长度更新信息素矩阵,短路径会有更多的信息素沉积。
  4. 迭代:重复构建解和更新信息素的过程,逐步优化解决方案。

概率规则

  • 蚂蚁选择下一步走哪条路径通常是根据路径上的信息素浓度和路径的吸引力(通常与路径长度成反比)来决定的。
  • 具体选择公式为:每条路径被选择的概率与信息素浓度和路径吸引力的乘积成正比。

蚁群算法步骤

  1. 1. 初始化:初始化信息素矩阵和其他参数。
  2. 2. 解构建:每只蚂蚁构建一个完整解。蚂蚁根据信息素和启发信息选择路径。
  3. 3. 更新信息素:根据蚂蚁构建解的质量更新信息素,较优解会留下更多信息素,同时所有路径上的信息素都会挥发。
  4. 4. 记录最优解:如果本次迭代中的解优于已知的最优解,则更新最优解。
  5. 5. 重复:重复上述步骤直到达到停止条件。

适用问题

  1. 特别适合路径优化问题,如旅行商问题(TSP)、车辆路径问题(VRP)等。
  2. 由于信息素的引导,适合处理具有多个局部最优解的复杂问题。

模型评价

模型优缺点
  • 蚁群算法对初始路线的要求不高,即使初始解较差,也能通过算法的不断迭代和优化找到较好的解,不易受个体影响。
  • 当问题规模较大时,计算每条路径的信息素更新和选择概率可能会变得非常复杂。

对于较小规模的问题,解空间较小,少量蚂蚁就能充分探索;对于较大规模的问题,设置蚂蚁数量为城市数量的2到10倍。适量的蚂蚁数量可以提高算法的收敛速度,但过多的蚂蚁可能会导致算法过早收敛到局部最优解,反而降低了结果质量。


TSP问题

假设有一个旅行商人要拜访n个城市,需选择一条路线,要求所有城市走一遍回到起点,同时使所走路程最短。

例题:已知敌方 100 个目标的经度、纬度(旅行商问题TSP的变种)

经度纬度经度纬度经度纬度经度纬度
53.712115.304622.107518.556924.45096.563452.842327.288
51.17580.03220.121518.872626.721328.566739.949429.5114
46.325328.275348.207716.888937.584816.847447.509924.0664
30.33136.934831.949917.630935.66199.933310.112127.2662
56.543221.41880.77320.465624.46543.164428.781227.6659
10.819816.252947.413423.77830.77756.95768.083127.6705
22.789123.104541.86713.566714.470313.63689.155614.1304
10.158412.481943.54743.906119.86615.122453.79890.2199
20.10515.456253.352426.72563.16164.242833.6490.398
1.94510.205730.816513.459518.524514.35981.349616.8359
26.495122.122127.71335.070658.684927.148549.98166.0828
31.48478.96423.92227.630639.516816.937119.363517.6622
26.241818.17651.961222.851156.508913.70936.954523.0265
44.035613.540112.793815.730752.521115.795715.73219.5697
28.983625.98794.95688.366938.438.464811.511817.3884
38.472220.173121.505124.090951.818123.015944.039816.2635
28.269429.001115.254827.21118.998323.64439.713928.4203
32.1915.86996.2075.144250.115623.78166.990923.1804
36.486329.728449.24316.704413.79091.95138.339219.995
0.971828.147717.116820.035434.057423.39624.654319.6057
8.958624.663534.168822.757123.06248.431936.99824.3992
16.561823.61439.44023.9219.98575.79024.15913.1853
10.559715.117811.581214.567740.880114.297840.1420.303
50.211110.294452.11810.408858.828914.522923.98769.403
8.15199.53259.555911.421918.66356.743641.108427.7149
我方有一个基地,经度和纬度为(70,40)。假设我方飞机的速度为 1000 公里/小时。
我方派一架飞机从基地出发,侦察完敌方所有目标,再返回原来的基地。在敌方每一目
标点的侦察时间不计,求该架飞机所花费的时间(假设我方飞机巡航时间可以充分长)。

1.主程序文件:

clc;clear;
%% 第一步:变量初始化
m=500;         % m 蚂蚁个数
Alpha=1;       % Alpha表征信息素重要程度的参数
Beta=5;        % Beta表征启发式因子重要程度的参数
Rho=0.1;       % Rho信息素蒸发系数
max_iter=150;  % 最大迭代次数
Q=100;         % 信息素增加强度系数
speed=1000;    % 飞机时速

data=[70 40;  % 最终要回到起点,于是将出发点加入总的目标地点中
53.7121 15.3046;51.1758 0.0322;46.3253 28.2753;30.3313 6.9348 ;
56.5432 21.4188 ;10.8198 16.2529 ;22.7891 23.1045;10.1584 12.4819; 
20.1050 15.4562 ;1.9451 0.2057;26.4951 22.1221;31.4847 8.9640 ;
26.2418 18.1760;44.0356 13.5401 ; 28.9836 25.9879 ;38.4722 20.1731; 
28.2694 29.0011 ;32.1910 5.8699; 36.4863 29.7284; 0.9718 28.1477 ;
8.9586 24.6635 ;16.5618 23.6143 ;10.5597 15.1178; 50.2111 10.2944 ;
8.1519 9.5325 ;22.1075 18.5569 ; 0.1215 18.8726 ;48.2077 16.8889 ;
31.9499 17.6309; 0.7732 0.4656 ;47.4134 23.7783; 41.8671 3.5667 ;
43.5474 3.9061 ;53.3524 26.7256  ;30.8165 13.4595 ;27.7133 5.0706 ;
23.9222 7.6306 ;51.9612 22.8511  ;12.7938 15.7307; 4.9568 8.3669 ;
21.5051 24.0909 ;15.2548 27.2111 ; 6.2070 5.1442 ;49.2430 16.7044 ;
17.1168 20.0354; 34.1688 22.7571; 9.4402 3.9200 ;11.5812 14.5677 ;
52.1181 0.4088 ;9.5559 11.4219 ;24.4509 6.5634; 26.7213 28.5667 ;
37.5848 16.8474 ;35.6619 9.9333 ;24.4654 3.1644; 0.7775 6.9576 ;
14.4703 13.6368 ;19.8660 15.1224; 3.1616 4.2428 ;18.5245 14.3598; 
58.6849 27.1485 ;39.5168 16.9371; 56.5089 13.7090; 52.5211 15.7957; 
38.4300 8.4648 ;51.8181 23.0159  ;8.9983 23.6440 ;50.1156 23.7816 ;
13.7909 1.9510 ;34.0574 23.3960 ;23.0624 8.4319 ;19.9857 5.7902 ;
40.8801 14.2978 ;58.8289 14.5229 ;18.6635 6.7436; 52.8423 27.2880; 
39.9494 29.5114 ;47.5099 24.0664; 10.1121 27.2662; 28.7812 27.6659; 
8.0831 27.6705 ;9.1556 14.1304 ;53.7989 0.2199 ;33.6490 0.3980 ;
1.3496 16.8359 ;49.9816 6.0828  ;19.3635 17.6622 ;36.9545 23.0265; 
15.7320 19.5697; 11.5118 17.3884; 44.0398 16.2635 ;39.7139 28.4203; 
6.9909 23.1804 ;38.3392 19.9950 ; 24.6543 19.6057 ;36.9980 24.3992 ;
4.1591 3.1853 ;40.1400 20.3030 ; 23.9876 9.4030 ;41.1084 27.7149
];  % 100个经纬度坐标数据
% R_best 各代最佳路线
% L_best 各代最佳路线的长度
n=size(data,1);  % n=101个目标地点
D=zeros(n,n);    % D表示完全图的赋权邻接矩阵

D = create_distance_matrix(data);
% 此处调用了create_distance_matrix.m文件,计算距离矩阵D

%% 变量
Eta=1./D;          % Eta为启发因子,设为距离的倒数
Tau=ones(n,n);     % Tau为信息素矩阵
Tabu=zeros(m,n);   % 存储并记录路径的生成
n_iter=1;          % 迭代计数器,记录迭代次数
R_best=zeros(max_iter, n);         % 各代最佳路线
L_best=inf .* ones(max_iter, 1);   % 各代最佳路线的长度  % inf正无穷
L_ave=zeros(max_iter, 1);          % 各代路线的平均长度
 
%% 进行蚁群算法 % 第二步:将m只蚂蚁放到n个目标地点上
while n_iter<=max_iter
    Randpos=[];                         %随即存取
    for i=1:(ceil(m/n))
        Randpos=[Randpos,randperm(n)];  %randperm(n)产生1-n的随机数
    end
    Tabu(:,1)=(Randpos(1,1:m))';        %将路径矩阵里面的第一列随机初始到一个地点
    
    %% 第三步:m只蚂蚁按概率函数选择下一个目标地点,完成各自的周游
    for j=2:n     
        for i=1:m
            visited=Tabu(i,1:(j-1));    %记录已访问的地点,避免重复访问
            J=zeros(1,(n-j+1));         %待访问的地点
            P=J;                        %待访问地点的选择概率分布
            Jc=1;
            for k=1:n
                if isempty(find(visited==k, 1))    %开始时置0
                    J(Jc)=k;
                    Jc=Jc+1;                       %访问的地点个数自加1
                end
            end
            %下面计算待选地点的概率分布
            for k=1:length(J)
                P(k)=(Tau(visited(end),J(k))^Alpha)*(Eta(visited(end),J(k))^Beta);
            end
            P=P/(sum(P));
            %按概率原则选取下一个
            Pcum=cumsum(P);          %cumsum,元素累加即求和
            Select=find(Pcum>=rand); %若计算的概率大于原来的就选择这条路线
            to_visit=J(Select(1));
            Tabu(i,j)=to_visit;
        end
    end
    
    if n_iter>=2
        Tabu(1,:)=R_best(n_iter-1,:); 
    end
    
    %% 第四步:记录本次迭代最佳路线
    L=zeros(m,1);                      % 开始距离为0,m*1的列向量
    for i=1:m
        R=Tabu(i,:);
        for j=1:(n-1)
            L(i)=L(i)+D(R(j),R(j+1));  % 原距离加上第j个地点到第j+1个的距离
        end
        L(i)=L(i)+D(R(1),R(n));        % 加上回到起点的距离,得到一轮下来后走过的距离
    end
    L_best(n_iter)=min(L);             % 最佳距离取最小
    pos=find(L==L_best(n_iter));
    R_best(n_iter,:)=Tabu(pos(1),:);   % 此轮迭代后的最佳路线
    L_ave(n_iter)=mean(L);             % 此轮迭代后的平均距离
    n_iter
    L_best(n_iter)
    n_iter=n_iter+1;                   % 迭代继续

    %% 第五步:更新信息素
    Delta_Tau=zeros(n,n);         %开始时信息素为n*n的0矩阵
    for i=1:m
        for j=1:(n-1)
            Delta_Tau(Tabu(i,j),Tabu(i,j+1))=Delta_Tau(Tabu(i,j),Tabu(i,j+1))+Q/L(i);
            %此次循环在路径(i,j)上的信息素增量
        end
        Delta_Tau(Tabu(i,n),Tabu(i,1))=Delta_Tau(Tabu(i,n),Tabu(i,1))+Q/L(i);
        %此次循环在整个路径上的信息素增量
    end
    Tau=(1-Rho).*Tau+Delta_Tau;   %考虑信息素挥发,更新后的信息素
    %% 第六步:禁忌表清零(禁忌表:防止搜索过程中出现循环,避免局部最优)
    Tabu=zeros(m,n);              %直到最大迭代次数
end

%%  第七步:输出结果,可视化
Pos=find(L_best==min(L_best));    %找到最佳路径
Shortest_Route=R_best(Pos(1),:)   %最大迭代次数后最佳路径
Shortest_Length=L_best(Pos(1))    %最大迭代次数后最短距离
figure(1) 
plot(L_best)
xlabel('迭代次数')
ylabel('最短路径长度')
title('每代最短路径长度进化曲线')

figure(2)
%绘制第一个子图形,路线图
subplot(1,2,1)                 
N=length(Shortest_Route);
scatter(data(:,1),data(:,2));     %绘制闪点图
hold on
plot([data(Shortest_Route(1),1),data(Shortest_Route(N),1)],[data(Shortest_Route(1),2),data(Shortest_Route(N),2)],'g');
hold on
for ii=2:N
    plot([data(Shortest_Route(ii-1),1),data(Shortest_Route(ii),1)],[data(Shortest_Route(ii-1),2),data(Shortest_Route(ii),2)],'g')
    hold on
end
title('最短路线结果图 ')

%绘制第二个子图形
subplot(1,2,2)                  
plot(L_best)
hold on                         %保持图形
plot(L_ave,'r')
legend('最短距离','平均距离')
title('平均距离和最短距离')

% 总时长
totaltime=Shortest_Length/speed;
totaltime

2.create_distance_matrix.m文件:计算距离矩阵D

计算目标点与目标点之间的距离。

function D = create_distance_matrix(data) 
    % 目标点之间的距离
    n=101;
    for i = 1:n  
        for j = 1:n  
            D(i, j) = haversine_distance(data(i, 1), data(i, 2), data(j, 1), data(j, 2));
            % 此处又调用了haversine_distance.m文件中的haversine_distance函数
            % 由于地球是圆的,距离的计算并不能简单地用欧氏距离
            D(j, i) = D(i, j); % 矩阵是对称的  
        end  
    end  
end

3.haversine_distance.m文件:计算飞机在圆圆的地球上的飞行距离的函数

% 计算飞机在圆圆的地球上的飞行距离的函数
function dist = haversine_distance(lat1, lon1, lat2, lon2)  
    % 将十进制度数转化为弧度  
    R = 6371; % 地球平均半径,单位千米  
    dLat = deg2rad(lat2 - lat1);  
    dLon = deg2rad(lon2 - lon1);  
    lat1 = deg2rad(lat1);  
    lat2 = deg2rad(lat2);  
  
    % Haversine公式(不懂的可以上网查查科普)
    a = sin(dLat/2).^2 + cos(lat1) .* cos(lat2) .* sin(dLon/2).^2;  
    c = 2 * atan2(sqrt(a), sqrt(1-a));  
    dist = R * c;  
end

运行主程序文件即可得到结果:

巡航路径及路径长度为39433km,总时长为39.4331小时左右。

参考文章:蚁群算法(包含TSP问题的matlab代码实现)_蚁群算法matlab-CSDN博客

  • 26
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
蚁群算法是一种基于模拟蚂蚁觅食行为的启发式算法,可以用于求解TSP问题。在MATLAB中,可以通过以下步骤实现: 1. 定义城市距离矩阵,即TSP问题的输入数据。 2. 初始化蚂蚁的位置和信息素矩阵。 3. 迭代搜索过程中,每只蚂蚁按照一定的概率选择下一个城市,并更新信息素矩阵。 4. 记录每次迭代中最优路径和路径长度。 5. 输出最优路径和路径长度。 以下是一个简单的MATLAB代码示例: ```matlab % 定义城市距离矩阵 dist = [...]; % 初始化参数 num_ant = 50; % 蚂蚁数量 num_city = size(dist, 1); % 城市数量 pheromone = ones(num_city, num_city); % 信息素矩阵 alpha = 1; % 信息素重要程度因子 beta = 5; % 启发式因子 rho = 0.5; % 信息素挥发因子 Q = 100; % 信息素增加强度因子 % 开始迭代搜索 best_path = []; best_length = Inf;for iter = 1:100 % 初始化蚂蚁位置 ant_pos = randi(num_city, num_ant, 1); for i = 1:num_city-1 % 计算每只蚂蚁的下一个城市概率 prob = (pheromone(ant_pos(:,i),:) .^ alpha) .* ((1./dist(ant_pos(:,i),:)) .^ beta); prob(:, ant_pos(:,1:i-1)) = 0; % 已经访问过的城市概率为0 prob = prob ./ sum(prob, 2); % 按照概率选择下一个城市 [~, next_city] = max(rand(num_ant, 1) <= cumsum(prob, 2), [], 2); ant_pos(:,i+1) = next_city; end % 计算每只蚂蚁的路径长度 path_length = sum(dist(sub2ind([num_city, num_city], ant_pos(:,end), ant_pos(:,1))), 1); for i = 1:num_ant-1 path_length(i+1) = sum(dist(sub2ind([num_city, num_city], ant_pos(i,:), ant_pos(i+1,:))), 2); end % 更新信息素矩阵 delta_pheromone = zeros(num_city, num_city); for i = 1:num_ant for j = 1:num_city-1 delta_pheromone(ant_pos(i,j), ant_pos(i,j+1)) = delta_pheromone(ant_pos(i,j), ant_pos(i,j+1)) + Q/path_length(i); end delta_pheromone(ant_pos(i,end), ant_pos(i,1)) = delta_pheromone(ant_pos(i,end), ant_pos(i,1)) + Q/path_length(i); end pheromone = (1-rho) * pheromone + delta_pheromone; % 记录最优路径和路径长度 if min(path_length) < best_length best_path = ant_pos(path_length == min(path_length), :); best_length = min(path_length); end end % 输出结果 disp(['Best path: ', num2str(best_path)]); disp(['Best length: ', num2str(best_length)]); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

时长一年半

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

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

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

打赏作者

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

抵扣说明:

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

余额充值