智能优化算法之蚁群算法
1. 概念
蚁群算法的本质是一种启发式优化算法,模拟了蚂蚁在搜索食物时的行为。它基于蚂蚁通过信息交流和相互合作的方式,通过自组织和正反馈的机制,找到最优解或近似最优解。
何谓启发式呢?启发式可以理解为一种启发性的指导或启示,它能够帮助算法在解空间中有针对性地搜索,并提供一些信息来指导解决方案的选择。启发式算法通常不保证找到全局最优解,但它们通常能够在合理的时间内找到接近最优解的解决方案。启发式算法的效果和性能很大程度上依赖于启发式信息的设计和利用,以及算法中其他参数的选择。
1.1 关键参数说明
- 蚂蚁数量:蚂蚁数量决定了搜索空间的探索程度。较多的蚂蚁数量能够增加搜索的广度和多样性,但缺削弱了正反馈作用。
- 信息素浓度:信息素是蚂蚁在路径上释放的化学物质,用于指引其他蚂蚁的选择。信息素浓度的大小影响了路径选择的偏好程度,高浓度的信息素会吸引更多的蚂蚁选择该路径。
- 信息素挥发率:信息素挥发率决定了信息素在路径上的消失速度。较高的挥发率会使信息素快速消失,促使蚂蚁重新探索新的路径,降低全局搜索能力。
- 启发因子:启发因子是用于评估路径上的启发式信息,例如距离、费用等。蚂蚁在路径选择时会综合考虑信息素浓度和启发因子,以决定下一步的移动。
2.代码
%%%%%%%%%%%%%%%%%%%%蚁群算法求函数极值%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%初始化%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear all; %清除所有变量
close all; %清图
clc; %清屏
m=20; %蚂蚁个数
G_max=200; %最大迭代次数
Rho=0.9; %信息素蒸发系数
P0=0.2; %转移概率常数
XMAX= 5; %搜索变量x最大值
XMIN= -5; %搜索变量x最小值
YMAX= 5; %搜索变量y最大值
YMIN= -5; %搜索变量y最小值
%%%%%%%%%%%%%%%%%随机设置蚂蚁初始位置%%%%%%%%%%%%%%%%%%%%%%
for i=1:m
X(i,1)=(XMIN+(XMAX-XMIN)*rand);
X(i,2)=(YMIN+(YMAX-YMIN)*rand);
Tau(i)=func(X(i,1),X(i,2));
end
step=0.1; %局部搜索步长
for NC=1:G_max
lamda=1/NC;
[Tau_best,BestIndex]=min(Tau);
%%%%%%%%%%%%%%%%%%计算状态转移概率%%%%%%%%%%%%%%%%%%%%
for i=1:m
P(NC,i)=(Tau(BestIndex)-Tau(i))/Tau(BestIndex)
end
%%%%%%%%%%%%%%%%%%%%%%位置更新%%%%%%%%%%%%%%%%%%%%%%%%
for i=1:m
%%%%%%%%%%%%%%%%%局部搜索%%%%%%%%%%%%%%%%%%%%%%
if P(NC,i)<P0
temp1=X(i,1)+(2*rand-1)*step*lamda;
temp2=X(i,2)+(2*rand-1)*step*lamda;
else
%%%%%%%%%%%%%%%%全局搜索%%%%%%%%%%%%%%%%%%%%%%%
temp1=X(i,1)+(XMAX-XMIN)*(rand-0.5);
temp2=X(i,2)+(YMAX-YMIN)*(rand-0.5);
end
%%%%%%%%%%%%%%%%%%%%%边界处理%%%%%%%%%%%%%%%%%%%%%%%
if temp1<XMIN
temp1=XMIN;
end
if temp1>XMAX
temp1=XMAX;
end
if temp2<YMIN
temp2=YMIN;
end
if temp2>YMAX
temp2=YMAX;
end
%%%%%%%%%%%%%%%%%%蚂蚁判断是否移动%%%%%%%%%%%%%%%%%%
if func(temp1,temp2)<func(X(i,1),X(i,2))
X(i,1)=temp1;
X(i,2)=temp2;
end
end
%%%%%%%%%%%%%%%%%%%%%%%更新信息素%%%%%%%%%%%%%%%%%%%%%%%
for i=1:m
Tau(i)=(1-Rho)*Tau(i)+func(X(i,1),X(i,2));
end
[value,index]=min(Tau);
trace(NC)=func(X(index,1),X(index,2));
end
[min_value,min_index]=min(Tau);
minX=X(min_index,1); %最优变量
minY=X(min_index,2); %最优变量
minValue=func(X(min_index,1),X(min_index,2)); %最优值
figure
plot(trace)
xlabel('搜索次数');
ylabel('适应度值');
title('适应度进化曲线')
%%%%%%%%%%%%%%%%%%%%%%%适应度函数%%%%%%%%%%%%%%%%%%%%%%%
function value=func(x,y)
value =20*(x^2-y^2)^2-(1-y)^2-3*(1+y)^2+0.3;
end
%%%%%%%%%%%%%%%%%%%%蚁群算法解决TSP问题%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%初始化%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear all; %清除所有变量
close all; %清图
clc; %清屏
m=50; %蚂蚁个数
Alpha=1; %信息素重要程度参数
Beta=5; %启发式因子重要程度参数
Rho=0.1; %信息素蒸发系数
G_max=200; %最大迭代次数
Q=100; %信息素增加强度系数
C=[1304 2312;3639 1315;4177 2244;3712 1399;3488 1535;3326 1556;...
3238 1229;4196 1044;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 2376;...
3394 2643;3439 3201;2935 3240;3140 3550;2545 2357;2778 2826;...
2370 2975]; %31个省会城市坐标
%%%%%%%%%%%%%%%%%%%%%%%%第一步:变量初始化%%%%%%%%%%%%%%%%%%%%%%%%
n=size(C,1); %n表示问题的规模(城市个数)
D=zeros(n,n); %D表示两个城市距离间隔矩阵
for i=1:n
for j=1:n
if i~=j
D(i,j)=((C(i,1)-C(j,1))^2+(C(i,2)-C(j,2))^2)^0.5;
else
D(i,j)=eps;
end
D(j,i)=D(i,j);
end
end
Eta=1./D; %Eta为启发因子,这里设为距离的倒数
Tau=ones(n,n); %Tau为信息素矩阵
Tabu=zeros(m,n); %存储并记录路径的生成
NC=1; %迭代计数器
R_best=zeros(G_max,n); %各代最佳路线
L_best=inf.*ones(G_max,1); %各代最佳路线的长度
figure(1);%优化解
while NC<=G_max
%%%%%%%%%%%%%%%%%%第二步:将m只蚂蚁放到n个城市上%%%%%%%%%%%%%%%%
Randpos=[];
for i=1:(ceil(m/n))
Randpos=[Randpos,randperm(n)];
end
Tabu(:,1)=(Randpos(1,1:m))';
%%%%%第三步:m只蚂蚁按概率函数选择下一座城市,完成各自的周游%%%%%%
for j=2:n
for i=1:m
visited=Tabu(i,1:(j-1)); %已访问的城市
J=zeros(1,(n-j+1)); %待访问的城市
P=J; %待访问城市的选择概率分布
Jc=1;
for k=1:n
if length(find(visited==k))==0
J(Jc)=k;
Jc=Jc+1;
end
end
%%%%%%%%%%%%%%%%%%计算待选城市的概率分布%%%%%%%%%%%%%%%%
for k=1:length(J)
P(k)=(Tau(visited(end),J(k))^Alpha)...
*(Eta(visited(end),J(k))^Beta);
end
P=P/(sum(P));
%%%%%%%%%%%%%%%%按概率原则选取下一个城市%%%%%%%%%%%%%%%%
Pcum=cumsum(P);
Select=find(Pcum>=rand);
to_visit=J(Select(1));
Tabu(i,j)=to_visit;
end
end
if NC>=2
Tabu(1,:)=R_best(NC-1,:);
end
%%%%%%%%%%%%%%%%%%%第四步:记录本次迭代最佳路线%%%%%%%%%%%%%%%%%%
L=zeros(m,1);
for i=1:m
R=Tabu(i,:);
for j=1:(n-1)
L(i)=L(i)+D(R(j),R(j+1));
end
L(i)=L(i)+D(R(1),R(n));
end
L_best(NC)=min(L);
pos=find(L==L_best(NC));
R_best(NC,:)=Tabu(pos(1),:);
%%%%%%%%%%%%%%%%%%%%%%%%%第五步:更新信息素%%%%%%%%%%%%%%%%%%%%%%
Delta_Tau=zeros(n,n);
for i=1:m
for j=1:(n-1)
Delta_Tau(Tabu(i,j),Tabu(i,j+1))=...
Delta_Tau(Tabu(i,j),Tabu(i,j+1))+Q/L(i);
end
Delta_Tau(Tabu(i,n),Tabu(i,1))=...
Delta_Tau(Tabu(i,n),Tabu(i,1))+Q/L(i);
end
Tau=(1-Rho).*Tau+Delta_Tau;
%%%%%%%%%%%%%%%%%%%%%%%第六步:禁忌表清零%%%%%%%%%%%%%%%%%%%%%%
Tabu=zeros(m,n);
%%%%%%%%%%%%%%%%%%%%%%%%%历代最优路线%%%%%%%%%%%%%%%%%%%%%%%%%%
for i=1:n-1
plot([ C(R_best(NC,i),1), C(R_best(NC,i+1),1)],...
[C(R_best(NC,i),2), C(R_best(NC,i+1),2)],'bo-');
hold on;
end
plot([C(R_best(NC,n),1), C(R_best(NC,1),1)],...
[C(R_best(NC,n),2), C(R_best(NC,1),2)],'ro-');
title(['优化最短距离:',num2str(L_best(NC))]);
hold off;
pause(0.005);
NC=NC+1;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%第七步:输出结果%%%%%%%%%%%%%%%%%%%%%%%%%%
Pos=find(L_best==min(L_best));
Shortest_Route=R_best(Pos(1),:); %最佳路线
Shortest_Length=L_best(Pos(1)); %最佳路线长度
figure(2),
plot(L_best)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')