蚁群算法(Ant Colony Optimization,ACO)由Marco Dorigo于1992年提出,ACO算法模拟了蚁群寻找食物的过程,在这个过程中最核心的两点在于路径的长短和信息素的浓度,在处理最优化问题中,蚁群算法是最成功的智能算法之一。ACO算法自提出以来许多学者对其做过改进,1996年Dorigo等人对蚁群系统进行了改进,强化了发现最优路径蚂蚁的影响力即精英策略;德国学者Stuetzle等人针对ACO算法在迭代过程中易提前出现停滞的现象对算法进行了改进提出了最大最小蚁群算法(MMAS);我国李士勇针对ACO算法的相关缺点也提出“最优最差蚂蚁更新信息素”,即增强最优解虚弱最差解,以此增大两个解之间信息素浓度的差距。这些学者的研究也提升了ACO算法的优化问题的能力。
在自然界中蚁群可以从零开始找到食物与巢穴之间的最短路径真实蚁群觅食过程如下。
一开始,在没有任何提示条件下,对于路径的选择蚂蚁们只能通过随机猜测选择,但经过一段时间之后蚂蚁就能通过整个蚁群在经过的路径上所释放的一种信息激素(信息素)的浓度来判断哪条路径更优并作出选择。这种由蚁群释放的信息素会随着时间的流逝逐渐淡化消失,所以被更多蚂蚁走过的路径上的信息素必然会更浓就会吸引更多的蚂蚁来走,并且蚁群在食物与巢穴之间来回搬运食物,在较短路径上所花费的时间更短,所以在较短路径上的所留下的信息素会更浓,在蚁群经过一定时间行走搬运食物后,就可以得到一条唯一最短的路径。
蚁群觅食模拟过程如图所示:
如上图蚁群从蚁巢到食物区域有三条路径可选,路径2是最短路径,设每一条路径只分配一只蚂蚁,从A出发,第一个时间单位后,蚂蚁2到达食物B区域时蚂蚁1到达C点即1/2路径1处,蚂蚁3到达D点即1/3路径3处,以此类推在第六个时间单位后蚂蚁3走完1趟,蚂蚁2走完趟,蚂蚁1走完1.5趟。若在不考虑信息素挥发的条件下,各路径上的信息素之比为:
路径1:路径2:路径3 = 3:6:2
显然短路径上的信息素浓度更高,若考虑信息素的挥发,相同时间内路径越短,信息素残留的浓度会越高。
蚁群算法是模仿自然界中蚂蚁寻找食物的过程,提取要素,一个基本的蚁群算法应该具备以下几个要素:
(1) 信息素的正反馈机制;
(2) 信息素的更新策略;
(3) 算法停止准则。
什么是信息素的正反馈机制,蚂蚁根据路径上信息素的反馈选择路径,即信息素在哪条路径的浓度越高,哪条路径被选择的概率将会越大,这也是蚂蚁之间协同工作的影响。具体正反馈机制如何实现需要根据实际问题建立相应的数学模型,后文会以TSP旅行商问题为例建立数学模型来说明正反馈机制如何为选择路径导向。
信息素的正反馈机制离不开信息素因子、启发式因子。在下文会介绍这两个参数。
信息素会随着时间的流逝而逐渐消失(挥发),所以首先蚁群算法会有一个信息素挥发系数,在每经历一个单位时间之后各个路径上之前留下的信息素会根据信息素挥发系数适量减少,然后会加上刚经过一次蚂蚁留下的信息素,一般在实际问题中,这个单位时间会取一次迭代。
信息素的更新策略离不开信息素挥发因子、信息素增加系数。在下文会介绍这两个参数。
(1) 实际使用蚁群算法优化问题时,都会经历一定次数的迭代,所以一般算法的停止准则取适当的迭代次数也就是外循环次数,表明蚂蚁已经工作足够长的时间了;
(2) 当连续N次迭代解都没有变化时,可以认为算法已经收敛,可以结束算法了。
在实际问题的应用中,一般先使用蚁群算法对该问题经行建模,与遗传算法相比,遗传算法为了实现选择交叉变异的操作,必须先建立抽象的染色体编码,染色体在算法中是存在的,然后对染色体经行操作。蚁群算法中强调的是蚂蚁走过的路径和路径上的信息素增减。所以记录了蚂蚁的路径信息和留下的信息素即相当于蚂蚁存在过。所以对蚂蚁个体建模的过程即是对蚂蚁经过路径节点记录和信息素更新的过程。
(1) 蚂蚁数量
在解决实际问题中,蚂蚁数量的选择会直接影响算法执行的效率,蚁群算法起初在路径选择上是依靠随机选择,到后期信息素将发挥主导作用。倘若蚁群数量过大,可能导致在各个路径上的信息素浓度差别不明显或趋于平均,短路径的优势会显现得更加缓慢;蚂蚁数量过少,所能覆盖的路径状态太少,容易使未被搜索的路径信息素快速缩小到零,导致算法过早收敛。所以一般对于蚂蚁数量的设置一般取略大于可以覆盖最开始已知解方向的个数或者可以理解为路径中节点的个数,根据实际问题可以多次测试取一个合适的值。
(2) 信息素的重要程度(信息素因子)
信息素因子即信息素对整个蚁群算法搜索路径的影响程度或对指导蚂蚁选择路径有多大的影响程度。
可以试想,当它的值过大即更加强调信息素的影响力,择蚂蚁可能更偏向于选择以前走过的路,而削弱了算法的随机性,可能导致算法过早收敛,难以搜索到新的解;若其值过小,或者假设它为0,信息素没有影响力,那么蚂蚁只可能会以就近原则选择路径,算法演变为局部搜索即爬山算法,算法会很容易达到局部最优。根据研究学者实验表明信息素因子取值在1~2更合适。
(3) 启发函数的重要程度(启发式因子)
启发函数类似于遗传算法的适应度函数,只不过适应度函数主导遗传算法搜索方向,蚁群算法的搜索方向由信息素和启发函数共同指导。启发式因子即启发函数对整个蚁群算法搜索路径的影响程度。
相比于信息素,启发函数其实是一个确定性因素,而信息素则是一个辅助的不确定性因素,所以启发式因子也可以看作是蚁群算法确定性因素的作用强度。其值过大就好比信息素因子过小,同样容易导致算法收敛过快出现局部最优;其值过小却并不与强化信息素因子作用相同,反而会使得算法陷入随机过多,难以找到最优解,因为这相当于削弱了算法的确定性因素。根据研究学者实验表明启发式因子取值在2~5更合适。
(4) 信息素挥发系数
信息素挥发系数即信息素随随时间的流失消散的速度,它的大小也会影响到算法的搜索能力和收敛速度,因为一方面防止了信息素的无限积累,另一方面使算法更有利于搜索到更好解,根据研究学者实验表明信息素挥发系数取小于1的正数,其值在0.2~0.5更合适。
(5) 信息素增加系数
信息素增加系数即,蚂蚁每经过一段路径所留下的信息素的量,其值越大,路径上信息素累积越快蚁群算法的正反馈机制会增强。根据研究学者实验表明信息素增加系数在100~1000更合适。
(6) 最大迭代次数
算法的最大迭代次数直接决定算法运行时间,当然不是越小越好,其值过小导致算法未充分收敛,过大直接浪费时间浪费资源。这个值需要根据具体问题具体分析,多次实验找到算法对于该问题的收敛轨迹,再确定最合适的迭代次数。
下图蚁群算法的流程,分内外两层循环,外循环控制算法迭代次数,内层循环是对每只蚂蚁的循环,根据实际问题可能还会有路径和路径节点的循环。
(1) 首先蚁群算法为何高效率:
第一因为信息素的正反馈机制,蚂蚁在选择路径的概率受信息素的正反馈影响会不断变化,所以路径的选择概率使动态的,并且越在算法运行后期这种概率的增大越偏向于优秀的解,同时也使得算法更容易收敛。
第二因为启发函数的确定性影响,启发函数一般都是解映射的,所以它是唯一可以确定一个解好坏的标准。
蚁群算法在这两个因素共同指导下搜索不仅会缩小算法的收敛长度,还会提高算法搜索最优解的精度。充分利用了随机与精确的优化思想,即不容易陷入局部最优也能提高搜索效率。
(2) 蚁群觅食从自然界来看是群体行为,是一种分布式搜索,并行计算提高了算法的计算能力和运行效率。
(1) 由于在蚁群算法搜索初期,每个路径的信息素浓度平均,搜索过程完全依靠蚂蚁随机选择路径,导致算法搜索靠近最优值的速度非常慢;
(2) 蚁群算法的信息素正反馈机制可以使算法更容易收敛,但到了后期也有导致局部最优的可能,信息素在较好解上的浓度越来越高,该解被选择的概率也会增大,削弱了随机选择,就容易引起局部最优。
组合优化问题,TSP问题见遗传算法(GA)分析总结
设有 n 个城市,城市坐标为:;
两个城市 i 和 j 之间相距简化为直线距离:;
为了记录每只蚂蚁访问过的城市每只蚂蚁都设置一个禁忌表,禁忌表的长度为 n+1,蚂蚁选择城市过程中会忽略禁忌表内的城市,当禁忌表满时即蚂蚁完成一次周游,设城市 i 与城市 j 之间在 t 时刻的信息素的量为则当 t = 0 时:
若从 t 开始到在 t+n 时刻所有蚂蚁都经过了 n 个城市完成一次周游,令 ρ 为信息素挥发系数,则城市 i 与城市 j 之间信息素浓度为:;
令为第 k 只蚂蚁在此次周游中留在城市 i 与城市 j 之间的信息素的量,为此次周游最佳路径长度 Q 为信息素增加系数,根据 ant-cycle 模型可知:;
时段内城市 i 与城市 j 之间信息素的增量:;
令表示蚂蚁从城市 i 转移到城市 j 的期望程度。 表示在城市 i 处蚂蚁 k 可以选择走的城市的集合。α,β表示信息素因子和期望启发式因子的影响程度。则第 k 只蚂蚁从城市 i 处选择城市 j 作为下一个周游城市的概率为:;
使用Matlab语言实现,参数设置如下:
蚂蚁数量:50;信息素挥发系数:0.25;信息素增加系数:100;信息素因子:1;启发式因子:5;城市数据:att48.txt;迭代次数分别取:30、50、100、150。不同迭代次数分别运行5次后取最短路径长度,所得数据结果如表3-2所示(注:括号内为收敛于第多少代):
最优结果路线及收敛信息如图所示:
由以上结果可以看出蚁群算法收敛很快一般在50代以内可以完成收敛。
见遗传算法(GA)分析总结3.1.1
见遗传算法(GA)分析总结3.1.2
见遗传算法(GA)分析总结3.1.3
aco.m(注释的代码可忽略)
clear all;
close all;
clc;
C=[3245.00 3305.00;
3484.00 2829.00;
3023.00 1942.00;
3082.00 1644.00;
1916.00 1569.00;
1633.00 2809.00;
1112.00 2049.00;
10.00 2676.00;
23.00 2216.00;
401.00 841.00;
675.00 1006.00;
2233.00 10.00;
3177.00 756.00;
4608.00 1198.00;
4985.00 140.00;
6107.00 669.00;
6101.00 1110.00;
5530.00 1424.00;
5199.00 2182.00;
4612.00 2035.00;
4307.00 2322.00;
4706.00 2674.00;
5468.00 2606.00;
5989.00 2873.00;
6347.00 2683.00;
6271.00 2135.00;
6898.00 1885.00;
6734.00 1453.00;
7265.00 1268.00;
7392.00 2244.00;
7545.00 2801.00;
7509.00 3239.00;
7462.00 3590.00;
7573.00 3716.00;
7541.00 3981.00;
7608.00 4458.00;
7762.00 4595.00;
7732.00 4723.00;
7555.00 4819.00;
7611.00 5184.00;
7280.00 4899.00;
7352.00 4506.00;
7248.00 3779.00;
6807.00 2993.00;
6426.00 3173.00;
5900.00 3561.00;
5185.00 3258.00;
4483.00 3369.00;
];
[M,N] = size(C); %M为问题的规模M个城市
distance = zeros(M,M); %用来记录任意两个城市之间的距离
% 求任意两个城市之间的距离
for m=1:M
for n=1:M
distance(m,n) = sqrt(sum((C(m,:)-C(n,:)).^2));
end
end
m = 50; %蚂蚁的个数,一般取10-50
alpha = 1; %信息素的重要程度,一般取【1,4】
beta = 5; %启发式因子的重要程度,一般取【3,5】
rho = 0.25; %信息素蒸发系数
G = 150;
Q = 100; %信息素增加系数
Eta = 1./distance; %启发式因子
Tau = ones(M,M); %信息素矩阵 存储着每两个城市之间的信息素的数值
Tabu = zeros(m,M); %禁忌表,记录每只蚂蚁走过的路径
gen = 1;
R_best = zeros(G,M); %各代的最佳路线
L_best = inf.*ones(G,1); %每一代的最佳路径的长度,初始假设为无穷大
L_Max = zeros(G,1);
% 开始迭代计算
while gen<=G
random_pos = [];
for i=1:(ceil(m/M)) %m只蚂蚁随机放到M座城市
random_pos = [random_pos,randperm(M)]; %random_pos=[1~M + 1~M],将每只蚂蚁放到随机的城市,在random_pos 中随机选择m个数,代表蚂蚁的初始城市
end
Tabu(:,1) = (random_pos(1,1:m))'; %每只蚂蚁的禁忌表
for i=2:M %从第二个城市开始
for j=1:m %每只蚂蚁
visited = Tabu(j,1:(i-1)); %在访问第i个城市的时候,第j个蚂蚁访问过的城市
unvisited = zeros(1,(M+1-i)); %待访问的城市
visit_P = unvisited; %蚂蚁j访问剩下的城市的概率
count = 1;
for k=1:M %这个循环是找出未访问的城市
if isempty(find(visited==k)) %还没有访问过的城市,如果成立。则证明第k个城市没有访问过
unvisited(count) = k;
count = count+1;
end
end
% 计算待选择城市的概率
for k=1:length(unvisited) %Tau(visited(end),unvisited(k))访问过的城市的最后一个与所有未访问的城市之间的信息素
visit_P(k) = ((Tau(visited(end),unvisited(k)))^alpha)*(Eta(visited(end),unvisited(k))^beta);
end
sum1 = sum(visit_P);
visit_P = visit_P/sum1; %访问每条路径的概率的大小
%按照概率选择下一个要访问的城市
%这里运用轮盘赌选择方法,这里也可以选择选择概率最大的路径去走, 这里采用轮盘赌选择法。
Pcum = cumsum(visit_P);
random1 = rand;
selected = find(Pcum>=random1);
to_visited = unvisited(selected(1));
Tabu(j,i) = to_visited; %添加到禁忌表
end
end
%到此为止所有蚂蚁已经将所有城市走了一遍
% if gen>=2
% Tabu(1,:) = R_best(gen-1,:);
% end
%记录m只蚂蚁迭代的最佳路线
L = zeros(1,m);
for i=1:m
R = Tabu(i,:);
L(i) = distance(R(M),R(1)); %因为要走一周回到原来的地点
for j=1:(M-1)
L(i) = L(i)+distance(R(j),R(j+1));%L(i)就是这一次迭代后 每一只蚂蚁走完一周的路程距离
end
end
% temp_R_best=0;
% if gen>=2
% for n=1:M-1
% temp_R_best = temp_R_best+distance(R_best(gen-1,n),R_best(gen-1,n+1));
% end
% temp_R_best = temp_R_best+distance(R_best(gen-1,M),R_best(gen-1,1));
% else
% temp_p_best = min(L)
% end
% if temp_p_best<min(L)
% R_best(gen,:) = R_best(gen-1,:);
% else
if gen>=2
if L_best(gen-1)<L(1)
L(1) = L_best(gen-1);
Tabu(1,:) = R_best(gen-1,:);
end
end
L_Max(gen) = max(L);
L_best(gen) = min(L); %记录每一代中路径的最短值
pos = find(L==L_best(gen));%找到哪那一只蚂蚁走了最短
R_best(gen,:) = Tabu(pos(1),:); %在禁忌表中找到这只蚂蚁的路径即最优的路径
% end
%更新信息素的值,这里算的信息素的增量
Delta_Tau = zeros(M,M);
for i=1:m % m只蚂蚁
for j=1:(M-1) % M座城市
Delta_Tau(Tabu(i,j),Tabu(i,j+1)) = Delta_Tau(Tabu(i,j),Tabu(i,j+1)) + Q/L(i); %m只蚂蚁的信息素累加,这里采用的是论文中ant-cycle模型
end
Delta_Tau(Tabu(i,M),Tabu(i,1)) = Delta_Tau(Tabu(i,M),Tabu(i,1)) + Q/L(i);%终点城市与起点城市之间的信息素
end
Tau = (1-rho).*Tau+Delta_Tau; %更新路径上的信息素含量
%禁忌表清零
Tabu = zeros(m,M);
%一边运行一边显示结果,速度会更慢
% figure(1);
% for i=1:(M-1)
% plot([C(R_best(gen,i),1),C(R_best(gen,i+1),1)],[C(R_best(gen,i),2),C(R_best(gen,i+1),2)],'bo-');
% hold on;
% end
% plot([C(R_best(gen,M),1),C(R_best(gen,1),1)],[C(R_best(gen,M),2),C(R_best(gen,1),2)],'ro-');
% xlabel('城市位置横坐标')
% ylabel('城市位置纵坐标')
% title(['迭代次数:',int2str(gen),'最短路径:',num2str(L_best(gen))]);
% hold off;
% pause(0.001);
% %收敛情况
% figure(2);
% plot(L_best);
% title('路径长度变化曲线');
% xlabel('迭代次数');
% ylabel('路径长度数值');
gen = gen+1;
end
%最后再显示结果,速度更快
figure(1);
for i=1:(M-1)
plot([C(R_best(G,i),1),C(R_best(G,i+1),1)],[C(R_best(G,i),2),C(R_best(G,i+1),2)],'bo-');
hold on;
end
plot([C(R_best(G,M),1),C(R_best(G,1),1)],[C(R_best(G,M),2),C(R_best(G,1),2)],'ro-');
xlabel('城市位置横坐标')
ylabel('城市位置纵坐标')
title(['迭代次数:',int2str(G),'最短路径:',num2str(L_best(G))]);
hold off;
%收敛情况
figure(2);
plot(L_best);
title('路径长度变化曲线');
xlabel('迭代次数');
ylabel('路径长度数值');
ACO算法处理TSP问题实验界面如图:
界面控件功能参考遗传算法(GA)分析总结里遗传算法仿真实验界面。
ACO算法结果显示上只设置了最基本的结果信息。开发环境使用Visual Studio 2019(vs2019)、开发语言C#以及.NET Framework Windows窗体应用开发类库。
VS项目文件链接,有需要的可以作学习参考:C#仿真程序资源
参考文献:[1]M D, V M, A C.Ant system:optimization by a colony of cooperating agents[J].IEEE transactions on systems, man,and cybernetics Part B, Cybernetics:a publication of the IEEE Systems, Man, and Cybernetics Society,1996,26(1).