蚁群算法
一、蚁群算法
蚁群算法是在20世纪90年代由澳大利亚学者Marco Dorigo等人通过观察蚁群觅食的过程,发现众多蚂蚁在寻找食物的过程中,总能找到一条从蚂蚁巢穴到食物源之间的最短路径。随后他们在蚂蚁巢穴到食物源之间设置了一个障碍,一段时间以后发现蚂蚁又重新走出了一条到食物源最短的路径。通过对这种现象的不断研究,最后提出了蚁群算法。蚁群算法在解决旅行商问题(即TSP问题)时,取得了比较理想的结果。
二、基本人工蚁群算法原理
运用人工蚁群算法求解TSP问题时的基本原理是:将m个蚂蚁随机地放在多个城市,让这些蚂蚁从所在的城市出发,n步(一个蚂蚁从一个城市到另外一个城市为1步)之后返回到出发的城市。如果m个蚂蚁所走出的m条路经对应的中最短者不是TSP问题的最短路程,则重复这一过程,直至寻找到满意的TSP问题的最短路径为止。为了说明这一个算法下面用一个算法流程图来表示一下:
三、 蚁群算法中涉及到的参数及其符号:
:蚂蚁数量,约为城市数量的1.5倍。如果蚂蚁数量过大,则每条路径上的信息素浓度趋于平均,正反馈作用减弱,从而导致收敛速度减慢;如果过小,则可能导致一些从未搜索过的路径信息素浓度减小为0,导致过早收敛,解的全局最优性降低
:信息素因子,反映了蚂蚁运动过程中积累的信息量在指导蚁群搜索中的相对重要程度,取值范围通常在[1, 4]之间。如果信息素因子值设置过大,则容易使随机搜索性减弱;其值过小容易过早陷入局部最优
:启发函数因子,反映了启发式信息在指导蚁群搜索中的相对重要程度,取值范围在[3, 4.5]之间。如果值设置过大,虽然收敛速度加快,但是易陷入局部最优;其值过小,蚁群易陷入纯粹的随机搜索,很难找到最优解
:信息素挥发因子,反映了信息素的消失水平,相反的反映了信息素的保持水平,取值范围通常在[0.2, 0.5]之间。当取值过大时,容易影响随机性和全局最优性;反之,收敛速度降低
:信息素常数,表示蚂蚁遍历一次所有城市所释放的信息素总量。越大则收敛速度越快,但是容易陷入局部最优;反之会影响收敛速度
:城市数量
:城市i到城市j之间的距离
:t时刻,城市i与城市j之间的信息素浓度
:t时刻,蚂蚁k从城市i向城市j转移的概率
:启发函数,表示蚂蚁从城市i转移到城市j的期望程度,这里我们取值为
:蚂蚁k待访城市的集合,初始时刻中有个元素,即排除掉蚂蚁一开始所在城市以外的其他城市,随着时间推移,其中的城市越来越少,直到为空,表示遍历完所有的城市
:表示在所有蚂蚁遍历完所有城市时,第k只蚂蚁对城市i与城市j之间信息素浓度总增加量的贡献量
:表示所有蚂蚁遍历完所有城市时,城市i与城市j之间信息素浓度的累积增加量
:表示蚂蚁k遍历完所有城市后经历的总路程长度
接下来给出三个公式:
公式一:
从公式中可以看出信息素因子为信息素浓度的指数,启发函数因子为启发函数的指数,这样便很好理解这两个参数所起到的作用了,分别决定了信息素浓度以及转移期望对于蚂蚁k从城市i转移到城市j的可能性的贡献程度。
公式二:
这个公式反映了信息素浓度的迭代更新规律,可以看出,所有蚂蚁遍历完一次所有城市后,当前信息素浓度由两部分组成,第一部分即上次所有蚂蚁遍历完所有城市后路径上信息素的残留,第二部分为本次所有蚂蚁遍历完所有城市后每条路径上的信息素的新增量。
公式三:
公式三反映了每只蚂蚁对于自己经过的城市之间路径上信息素浓度的贡献量,可以看出,其经历的路程越长,则对于沿途上信息素浓度的贡献量也就越低,如果尽力的路程越短,则对于沿途上信息素浓度的贡献量也就越高
四、代码及其实现
citys_data里面储存着35个城市的坐标
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
3211 2975
1479 3665
2646 2556
2830 3140
1072 1700
代码部分:
%% 旅行商问题(TSP)优化
%% 清空环境变量
clear all
clc
%% 导入数据
load citys_data.mat
%% 计算城市间相互距离
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
%% 初始化参数
fprintf('Initializing Parameters... \n');
m = 50; % 蚂蚁数量
alpha = 0.9; % 信息素重要程度因子
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 = 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,清空路径记录表
% 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('各代最短距离与平均距离对比')
五、α,β,ρ对该实验的影响
1.α对实验的影响
在m=50,β=5,ρ=0.1恒定的情况下
α=0.7
α=0.8
α=0.9
α=1
启发因子α的数值的改变,所求得最短路径也随之变化,它表现的是蚂蚁在搜索路径的运动过程中对所积累的信息量指导蚁群搜索当中的相对重要度,对算法的随机性有影响,并且可以导致算法过早陷入局部最优中。α过小,收敛速度慢,且容易陷入局部最优中;α过大,局部最短路径上正反馈作用强,过早收敛。α=0.8时,最短距离最短,算法性能最佳。
2.β对实验的影响
在m=50,α=0.8,ρ=0.1恒定的情况下
β=4
β=4.3
β=4.5
β=4.8
β=5
期望启发因子β的数值的改变,所求得得最短路径随之变化,它表现的是启发式信息在指导蚁群搜索过程之中相对重要的程度,它的大小影响着蚁群在整个寻短过程中的先验性和确定性。β过小,蚁群陷入纯粹的随机搜索,很难找到最优解;β过大时,收敛速度增快。β=4.5时,最短距离最短,算法性能最佳。
3.ρ对实验的影响
当m=50,α=0.8,β=5恒定不变时
ρ=0.1
ρ=0.2
ρ=0.3
ρ=0.4
ρ=0.5
ρ对蚁群算法的搜索能力和收敛速度有影响。ρ过小时,在各路径上残留的信息素过多,导致无效的路径继续被搜索,影响到算法的收敛速率;ρ过大时,无效的路径虽然可以被排除搜索,但是不能保证有效的路径也会被放弃搜索,影响到最优质的搜索,使收敛速度降低,并且影响到算法的全局搜索能力。ρ=0.1时,最短距离最大,算法性能最佳。
六、总结
通过多次实验分析,验证和确定了数值范围,由以上实验结果可以看出,参数的初始设置对算法的影响非常之大。