文章目录
- 🧡🧡实验内容🧡🧡
- 🧡🧡代码🧡🧡
- 🧡🧡分析结果🧡🧡
- 🧡🧡实验总结🧡🧡
🧡🧡实验内容🧡🧡
编写基于蚁群算法求解 TSP 问题的程序,分别求出 20 个城市之间和 50 个城市之间的最短路径。
🧡🧡代码🧡🧡
%% 清空环境变量
clear
clc
close all%% 导入数据
citys_31 = [ % 内陆的31个主要省会城市,不含港澳台116.407395, 39.904211;117.200983, 39.084158;114.514862, 38.042307;118.180193, 39.630867;112.549248, 37.857014;111.670801, 40.818311;123.431475, 41.805698;125.323544, 43.817071;126.534967, 45.803775;121.473701, 31.230416;118.796877, 32.060255;120.153576, 30.287459;117.227239, 31.820587;119.296494, 26.074508;115.892151, 28.676493;117.120019, 36.651216;113.665412, 34.757975;114.298572, 30.584355;112.938814, 28.228209;113.264434, 23.129162;108.320004, 22.82402;110.33119, 20.031971;104.065735, 30.659462;106.713478, 26.578343;102.712251, 25.040609;108.948024, 34.263161;103.834303, 36.061089;101.778228, 36.617144;91.132212, 29.660361;106.278179, 38.46637;87.617733, 43.792818;
];
citys_50=[110.469286198181 50.4746691410186;92.5266910201309 42.7595185867962;85.8168137464198 33.3510745658952;103.005033088825 37.3718509138302;115.815409819431 32.4287938317344;125.720207837641 42.4575314260683;83.1496903823127 46.5890781381871;86.5692819178498 51.4168621571695;95.8073622632917 48.1280677266756;130.620267741678 45.2905464411555;82.7428601931531 35.0371447515392;124.230437470352 29.5943527737754;108.307261544677 43.8646083607653;105.837300942493 15.7127956890334;126.891027665425 44.3382449137088;109.501233625833 32.4217551748842;114.895073617088 40.9239984204817;115.95881 51.4517223372703;119.640883772243 22.7559646793684;101.482506618948 29.0125930804905;122.579272261262 44.4500855598353;128.423962506030 18.5572682527589;87.3523632932626 20.6025092238485;129.029503867517 33.8399355659161;109.540700690432 26.3141382912873;130.445329656714 23.6507514948169;84.9868745956852 39.5895240262594;103.812894324380 49.5222693078745;73.7535688054273 38.4530364608632;124.603837227041 37.1160006808058;74.9217946493522 35.8982407433328;89.2026003945863 36.0532693055382;107.891311021032 20.5177333856848;104.321662298107 47.3711070688777;80.5936363842351 52.6694785312550;133.111293665466 40.2547112805644;88.3720406809424 25.9026846100506;133.072259309913 25.7819126780322;120.466021232856 19.2388485754945;77.5238676167198 48.1650585535397;76.5154109411933 34.5941955801035;107.205075462786 30.6395114651284;95.2040830320626 23.4266972302777;81.3734952157783 26.2383951416844;80.4755943569925 22.1074033577527;78.2814334811311 24.0545780185756;83.0016130798109 37.5738520876487;113.203798272594 14.2722816613816;122.804520260080 46.8178856055774;116.735480758245 23.4382459106337;
];%% 计算城市间相互距离
citys = citys_31;
n = size(citys,1);
D = zeros(n,n);
for i = 1:nfor j = 1:nif i ~= jD(i,j) = sqrt(sum((citys(i,:) - citys(j,:)).^2));elseD(i,j) = 1e-4;endend
end%% 初始化参数
rng(66) % 随机因子,确保程序每次运行结果相同
m = 35; % 蚂蚁数量
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); % 各代路径的平均长度 tic; % 开始计时
%% 迭代寻找最佳路径
while iter <= iter_max% 随机产生各个蚂蚁的起点城市start = zeros(m,1);for i = 1:mtemp = randperm(n);start(i) = temp(1);endTable(:,1) = start; % 构建解空间citys_index = 1:n;% 逐个蚂蚁路径选择for i = 1:m% 逐个城市路径选择for j = 2:ntabu = 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;endP = P/sum(P);% 轮盘赌法选择下一个访问城市Pc = cumsum(P); target_index = find(Pc >= rand); target = allow(target_index(1));Table(i,j) = target;endend% 计算各个蚂蚁的路径距离Length = zeros(m,1);for i = 1:mRoute = Table(i,:);for j = 1:(n - 1)Length(i) = Length(i) + D(Route(j),Route(j + 1));endLength(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_LengthRoute_best(iter,:) = Table(min_index,:);elseRoute_best(iter,:) = Route_best((iter-1),:);endend% 更新信息素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);
% Delta_Tau(Table(i,j),Table(i,j+1)) = Delta_Tau(Table(i,j),Table(i,j+1)) + Q/D(j,j+1);
% Delta_Tau(Table(i,j),Table(i,j+1)) = Delta_Tau(Table(i,j),Table(i,j+1)) + Q;endDelta_Tau(Table(i,n),Table(i,1)) = Delta_Tau(Table(i,n),Table(i,1)) + Q/Length(i);
% Delta_Tau(Table(i,n),Table(i,1)) = Delta_Tau(Table(i,n),Table(i,1)) + Q/D(n,1);
% Delta_Tau(Table(i,n),Table(i,1)) = Delta_Tau(Table(i,n),Table(i,1)) + Q; endTau = (1-rho) * Tau + Delta_Tau;% 迭代次数加1,清空路径记录表iter = iter + 1;Table = zeros(m,n);
end
elapsedTime = toc;% 结束计时%% 结果显示
[Shortest_Length,index] = min(Length_best);
Shortest_Route = Route_best(index,:);
disp(['最短距离:' num2str(Shortest_Length)]);
disp(['最短路径:' num2str([Shortest_Route Shortest_Route(1)])]);
disp(['程序运行时间:', num2str(elapsedTime), '秒']);%% 绘图
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),' 起点', 'Color', 'red');
text(citys(Shortest_Route(end),1),citys(Shortest_Route(end),2),' 终点', 'Color', 'red');
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('各代最短距离与平均距离对比')
🧡🧡分析结果🧡🧡
为贴合现实情况,并且有利于研究TSP,我采用中国内陆的31个省会城市作为数据1,对于50个城市,我选择随机生成经纬度在一定范围内的城市坐标,然后保持起来,作为数据。
设置参数如下:
31个城市的最短路径图和迭代最佳距离变化图如下
改变为50个城市时:
得到50个城市的最短路径图和迭代最佳距离变化图如下
分析蚁群算法和遗传算法的区别与联系以及蚁群算法的优缺点
区别:
蚁群算法主要是模拟蚂蚁在寻找食物时释放信息素的过程,通过信息素的积累来更新路径,实现优化。
遗传算法主要是利用生物进化的思想,通过种群的选择、交叉、变异等基本操作,不断优化进化得到更好的解。
联系:
蚁群算法和遗传算法都是基于集体智慧的思想,通过群体中个体之间的交互和信息共享来实现全局最优化。
蚁群算法的优缺点:
- 优点:
蚁群算法能够较好地保持全局探索能力,避免陷入局部最优解。- 缺点:
蚁群算法对于问题的参数敏感,需要进行较多的参数设置和实验,才能得到较好的效果。并且算法的收敛速度相对较慢,可能需要较长的时间才能达到最优解(这次实验普遍运行3秒以上,而实验二中用遗传算法求解TSP普遍1秒之内)。
🧡🧡实验总结🧡🧡
理论理解方面:
给我感觉是和粒子群类似,通过定义一些公式,来实现启发式搜索:
简单来说就是对于所有蚂蚁,计算t时刻这只蚂蚁从城市i到城市j的概率,而这个概率与路径上信息素浓度相关,而信息浓度又与路径长度有关,因此让这只蚂蚁不断根据概率选择城市前往,在每一代从能得到这只蚂蚁的路径,也即一个解。对于信息素启发因子α,其值越大,表示信息素的浓度在转移中起的作用越大;β为启发函数重要程度因子,其值越大,表示启发函数在转移中的作用越大,即蚂蚁会以较大的概率转移到距离短的城市。当α=0时,算法就是传统的贪心算法,而当β=0时,就成了纯粹的正反馈的启发式算法。
代码实操方面:
有用到禁忌close表和open表,与BFS、DFS的搜索作用类似,记录哪些城市已经访问,哪些城市还没访问。实验中需要组合调试主要参数,而每次运行的收敛时间都相对来说比较长(也可能与我设置的迭代代数和城市规模过大有关),并且有时得出的解的质量其实并不能有太大差别,不敢保证搜到的就是全局最优,因此,对于城市规模较小的问题,可以先尝试使用其他算法求解理想最优值,以对实验结果进行更好的评估和判断。