蚁群算法
一、思想
将蚁群算法应用于解决优化问题的基本思路为:用蚂蚁的行走路径表示待优化问题的可行解,整个蚂蚁群体的所有路径构成待优化问题的解空间。路径较短的蚂蚁释放的信息素量较多,随着时间的推进,较短的路径上累积的信息素浓度逐渐增高,选择该路径的蚂蚁个数也愈来愈多。最终,整个蚂蚁会在正反馈的作用下集中到最佳的路径上,此时对应的便是待优化问题的最优解。
二、基本原理
- 蚂蚁在路径上释放信息素。
- 碰到还没走过的路口,就随机挑选一条路走。同时,释放与路径长度有关的信息素。
- 信息素浓度与路径长度成反比。后来的蚂蚁再次碰到该路口时,就选择信息素浓度较高路径。
- 最优路径上的信息素浓度越来越大。
- 最终蚁群找到最优寻食路径。
三、代码实现(旅行商问题)
随机生成城市序列,数量为50,城市位置的横纵坐标范围为[1000,4000]:
%% 产生数据
a=randperm(3000,50)+1000;
b=randperm(3000,50)+1000;
citys=[a;b]';
ACO.m
%% 旅行商问题(TSP)优化
%% 计算城市间相互距离
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 = 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 = 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('各代最短距离与平均距离对比')
四、结果与分析
4.1算法迭代
在整个蚁群算法中,要进行多次迭代。每一次迭代都会产生当前的最优分配策略,也就是“局部最优解”。迭代的次数越多,那么局部最优解就越接近于全局最优解。但是,迭代次数过多会造成负载均衡器大量的时间和性能上的开销,从而无法满足海量任务的调度。但迭代次数太少了,可能得到的并不是全局最优解。那么这个问题如何解决呢?有两种办法:
- 限定迭代次数——为了避免过多的迭代,我们可以事先设置一个迭代次数,从而迭代了这么多次后,就把当前的局部最优解当作全局最优解。
- 设置误差允许范围——我们还可以事先设置一个允许的误差范围。当迭代N此后,当前最优的任务处理时间在这个允许范围之内了,那么就停止迭代。
这两种方式各有千秋,这里选择第一种——限定迭代次数。并且将迭代次数限定为150次。
4.2参数设置对蚁群算法性能的影响
设蚂蚁k当前所在城市为i,则其选择城市j作为下一个访问对象的概率为:
信息素更新:
这里主要讨论以下三个参数对算法性能的影响:
α——信息素重要程度因子
β——启发函数重要程度因子
ρ——信息素挥发因子
%为测试参数,将随机产生的城市序列存入data.txt中,后续调试使用语句"citys=load('data.txt');"以保证每次调试所用数据相同
a=randperm(3000,50)+1000;
b=randperm(3000,50)+1000;
citys=[a;b]';
fid=fopen('data.txt','wt');%写入文件路径
[m,n]=size(citys);
for i=1:1:m
for j=1:1:n
if j==n
fprintf(fid,'%g\n',citys(i,j));
else
fprintf(fid,'%g\t',citys(i,j));
end
end
end
fclose(fid);
4.2.1参数α对算法性能的影响
α反映蚂蚁在运动过程中所积累的信息量在指导蚁群搜索中的相对重要程度,其值越大,蚂蚁选择以前走过路径的可能性就越大,搜索的随机性减弱;其值过小,则等同于贪婪算法,易使蚁群的搜索过早陷入局部最优。
设定beta=5,rho=0.1,改变alpha的值,分别得到如下结果:
alpha=0.2:(可得结果:达到最短距离的迭代次数为114,最短距离为18908.4754)
alpha=0.5:(可得结果:达到最短距离的迭代次数为103,最短距离为19139.3294)
alpha=0.7:(可得结果:达到最短距离的迭代次数为86,最短距离为18848.7902)
alpha=1:(可得结果:达到最短距离的迭代次数为91,最短距离为18757.7856)
alpha=2:(可得结果:达到最短距离的迭代次数为70,最短距离为18916.844)
结论:alpha过小,收敛速度慢,且易陷入局部最优; alpha过大,即信息素的重要性得以充分体现,局部最优路径上正反馈作用强,过早收敛。
当alpha∈[0.7,1]时,综合求解性能较好。
4.2.2参数β对算法性能的影响
β指启发函数重要程度因子,反映了启发式信息在指导蚁群搜索过程中的相对重要程度,其大小反映了蚁群寻优过程中先验性、确定性因素的作用强度。其值越大,则蚂蚁在某个局部点上选择局优的可能性越大,虽然收敛速度加快,但搜索全优的随机性减弱,易于陷入局部最优。
设定alpha=1,rho=0.1,改变beta的值,分别得到如下结果:
beta=4:(可得结果:达到最短距离的迭代次数为119,最短距离为18843.0569)
beta=5:(可得结果:达到最短距离的迭代次数为109,最短距离为18691.879)
beta=6:(可得结果:达到最短距离的迭代次数为92,最短距离为18668.4975)
beta=7:(可得结果:达到最短距离的迭代次数为92,最短距离为18691.879)
beta=8:(可得结果:达到最短距离的迭代次数为89,最短距离为18691.879)
beta=10:(可得结果:达到最短距离的迭代次数为3,最短距离为18670.6286)
结论:beta过小,蚂蚁群体陷入纯粹的随机搜索,很难找到最优解; beta过大时,收敛速度增快,但收敛性能有变差的趋势。
当beta∈[5,8]时,综合求解性能较好。
4.2.2参数ρ对算法性能的影响
ρ表示信息素挥发因子,1- ρ即为信息素残留因子。ρ的大小直接关系蚁群算法的全局搜索能力及收敛速度,1-ρ则反映蚂蚁之间个体相互影响的强弱。由于p的存在,当问题规模较大时,会使从未被搜索的路径的信息素量减小到接近于0,降低全局搜索能力,且当p过大时,重复搜索的可能性大,影响随机性有和全局搜索能力;当ρ越小时,则会使收敛速度降低。
设定alpha=1,beta=5,改变rho的值,分别得到如下结果:
rho=0.1:(可得结果:达到最短距离的迭代次数为117,最短距离为18757.7856)
rho=0.3:(可得结果:达到最短距离的迭代次数为27,最短距离为18813.4791)
rho=0.5:(可得结果:达到最短距离的迭代次数为29,最短距离为18765.6448)
rho=0.7:(可得结果:达到最短距离的迭代次数为19,最短距离为18757.7856)
rho=0.9:(可得结果:达到最短距离的迭代次数为7,最短距离为18904.4838)
结论:ρ与迭代次数近似反比,当1-ρ很大时,即ρ很小时,残留信息占主导地位,正反馈作用减弱,随机性增强,速度较慢;1-ρ较小时,正反馈作用强,随机性强,收敛较快,但易陷入局部最优。
当ρ ≈0.5时,全局收敛性和收敛速度比较好,性能也稳定。