文章目录
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。