蚁群算法求解最优路径问题

以2017年华为杯研究生数学建模比赛A题(无人机在抢险救灾中的优化运用)为例,讲解蚁群算法在求解最优路径问题中的应用,我们将问题进行了简化,描述如下:

无人机从某一个基地出发,途径所有救援点,然后回到基地(每个点只经过一次),求解最佳行驶路径。

基地和所有救援点的散点图如图1所示。
图1:基地和救援点散点图
蚁群算法是寻求优化路径的一种算法,这种算法的思想起源于蚂蚁在寻求事物过程中的路径,这种算法在本质上属于一种启发式全局优化算法,具有信息正反馈、分布计算和启发式搜索的特点。蚁群算法采用的规则主要为环境信息、避障规则、移动规则、散发信息素规则等。蚁群算法主要应用在组合优化问题上,同时其在网络路由中应用也越来越广泛。

最终使用蚁群算法得到的救援路线如图2所示:
图2:蚁群算法求解得到的最佳路线
我们提供了可运行的代码,并添加了注释,大家可自行去了解该算法的精髓。代码包含三个部分,主函数mainfun.m调用Antcolonyalgorithm.m和flightRoute.m. Antcolonyalgorithm.m用于实现蚁群算法,flightRoute.m用于画飞行路线。

function mainfun()

% 位点坐标
position=[   91.2000   94.3000
   83.4000   90.4000
   76.7000   88.8000
   57.8000   91.4000
   75.6000   91.4000
   57.8000   88.0000
   51.1000   88.9000
   30.0000   90.6000
   30.0000   99.4000
   42.2000   78.1000
   58.9000   92.7000
   62.3000   93.2000
   50.0000   78.9000
   44.5000   86.7000
   55.6000   71.2000
   52.3000   67.3000
   72.3000   64.7000
   82.3000   66.0000
   85.6000   71.2000
   82.3000   67.3000
   85.6000   58.2000
   85.6000   60.8000
   83.4000   59.5000
   50.0000   71.7000
   52.3000   78.4000
   44.5000   75.8000
   66.0000   93.6000
   62.2000   82.9000
   78.9000   93.2000
   67.8000  116.5000
   52.2000  120.4000
   55.6000   80.2000
   91.2000  124.3000
   53.3000   65.9000
  110.0000   55.0000];

% 所有点的散点图
figure
scatter(position(:,1),position(:,2),'ro');
hold on
axis([10,120,20,140])
plot(110,55,'ro','MarkerFaceColor','r')
text(100,60,'基地J','Color','r')
set(gca,'FontSize',16)

% 蚁群算法
[~,L_best,L_ave,Shortest_Route,Shortest_Length]=Antcolonyalgorithm(position,2000,30,0.9,0.9,0.1,0.1);
figure
flightRoute(position,Shortest_Route)
hold on
axis([10,120,20,140])
plot(110,55,'ro','MarkerFaceColor','r')
text(100,60,'基地J','Color','r')
set(gca,'FontSize',16)

figure
plot(L_best,'b','LineWidth',2)
hold on
plot(L_ave,'b','LineWidth',2)
xlabel('迭代次数')
ylabel('平均距离和最短距离')
set(gca,'FontSize',16)

end

蚁群算法函数——

function [R_best,L_best,L_ave,Shortest_Route,Shortest_Length]=Antcolonyalgorithm(C,NC_max,m,Alpha,Beta,Rho,Q)

% 输入输出说明
% C城市的坐标
% NC_max 最大迭代次数
% m 蚂蚁个数
% Rho 信息素蒸发系数
% Q 信息素增加强度系数
% R_best 最佳路线
% L_best 最佳路线的长度
% Alpha 信息素重要程度
% Beta 启发式因子重要程度

%变量初始化
n=size(C,1);
D=zeros(n,n);
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;
Tau=ones(n,n); 
Tabu=zeros(m,n);
NC=1;
R_best=zeros(NC_max,n);
L_best=inf.*ones(NC_max,1);
L_ave=zeros(NC_max,1);

while NC<=NC_max 
    Randpos=[];
    for i=1:(ceil(m/n))
        Randpos=[Randpos,randperm(n)];
    end
    Tabu(:,1)=(Randpos(1,1: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 isempty(find(visited==k, 1))
                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),:); 
    L_ave(NC)=mean(L);
    NC=NC+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);
end
%输出结果
Pos=find(L_best==min(L_best)); 
Shortest_Route=R_best(Pos(1),:); 
Shortest_Length=L_best(Pos(1));

end

画路线图的函数,输入为位点坐标和路径——


function flightRoute(C,Rou)

Num=length(Rou);
scatter(C(:,1),C(:,2));
hold on
plot([C(Rou(1),1),C(Rou(Num),1)],[C(Rou(1),2),C(Rou(Num),2)],'r','LineWidth',3)
hold on
for ii=2:Num
    plot([C(Rou(ii-1),1),C(Rou(ii),1)],[C(Rou(ii-1),2),C(Rou(ii),2)],'r','LineWidth',3)
    hold on
end

end

原文链接见:https://mp.weixin.qq.com/s?__biz=Mzg2OTIzOTg0Mw==&mid=2247484010&idx=1&sn=a959ec5bc9c4482567b1178fd5e08dbd&chksm=cea15f26f9d6d630cc904339618825110f861fef9071cf21d4dbd203d547b7b372f30b7572b2&token=1990617603&lang=zh_CN#rd
欢迎关注公众号”数学建模公会“,获取源代码文件。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值