蚁群算法Matlab

% ACO算法实现
function [Lnum_max, num] = p2p(Alpha, Beta)
    G=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
        0 1 1 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0;
        0 1 1 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0;
        0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0;
        0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0;
        0 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 1 1 0 0;
        0 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0;
        0 1 1 1 0 0 1 1 1 0 1 1 1 1 0 0 0 1 1 0;
        0 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0;
        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0;
        0 0 0 0 0 0 0 1 1 1 0 1 1 1 0 0 0 0 0 0;
        0 0 0 0 0 0 0 1 1 1 0 1 1 1 0 0 0 0 0 0;
        0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 0;
        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0;
        1 1 1 1 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 0;
        1 1 1 1 0 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0;
        0 0 0 0 0 0 1 1 0 1 1 1 0 0 0 0 0 1 1 0;
        0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0;
        0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0;
        0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0;];
    MM=size(G,1);                         % 获取边长,G 地形图为01矩阵,如果为1表示障碍物
 
    Tau=ones(MM*MM,MM*MM);        % Tau 初始信息素矩阵
    Tau=8.*Tau;
    K=100;                              %迭代次数(指蚂蚁出动多少波)
    M=50;                               %蚂蚁个数
%     Alpha=1;                             % Alpha 表征信息素重要程度的参数
%     Beta=7;                              % Beta 表征启发式因子重要程度的参数
    Rho=0.3 ;                             % Rho 信息素蒸发系数
    Q=1;                               % Q 信息素增加强度系数
 
    minkl=inf;   % 最小正数
    mink=0;
    minl=0;
    D=G2D(G);
    N=size(D,1);               %N表示问题的规模(像素个数)
    a=1;                     %小方格像素的边长
 
    S=1 ;                                %最短路径的起始点
    E=MM*MM;                        %最短路径的目的点
    Ex=a*(mod(E,MM)-0.5);    %终止点横坐标
    if Ex==-0.5
        Ex=MM-0.5;
    end
    Ey=a*(MM+0.5-ceil(E/MM)); %终止点纵坐标 ceil向上取整
 
    Eta=zeros(N);             %启发式信息,取为至目标点的直线距离的倒数  N=L^2
    %以下启发式信息矩阵,每个点到终点距离的倒数
    for i=1:N
        ix=a*(mod(i,MM)-0.5);
        if ix==-0.5
            ix=MM-0.5;
        end
        iy=a*(MM+0.5-ceil(i/MM));
        if i~=E
            Eta(i)=1/((ix-Ex)^2+(iy-Ey)^2)^0.5;
        else
            Eta(i)=100;
        end
    end
    ROUTES=cell(K,M);     %用元胞结构存储每一代的每一只蚂蚁的爬行路线,K=100 迭代次数 M=50蚂蚁数量 cellplot:利用图形方式显示内容(奈斯!)
    PL=zeros(K,M);         %用矩阵存储每一代的每一只蚂蚁的爬行路线长度
    %启动K轮蚂蚁觅食活动,每轮派出M只蚂蚁
    for k=1:K
        for m=1:M
            %状态初始化
            W=S;                  %当前节点初始化为起始点 S为起始点
            Path=S;                %爬行路线初始化
            PLkm=0;               %爬行路线长度初始化
            TABUkm=ones(N);       %禁忌表初始化
            TABUkm(S)=0;          %已经在初始点了,因此要排除
            DD=D;                 %邻接矩阵初始化
            %下一步可以前往的节点
            DW=DD(W,:);
            DW1=find(DW);  % 当前点8邻域的索引,find:寻找非零元素的索引和值,返回线性索引
            for j=1:length(DW1)
                if TABUkm(DW1(j))==0
                    DW(DW1(j))=0;
                end
            end
            LJD=find(DW);  % 下一步的可选节点
            Len_LJD=length(LJD);%可选节点的个数
            %蚂蚁未遇到食物或者陷入死胡同或者觅食停止
            while W~=E&&Len_LJD>=1
                %轮盘赌法选择下一步怎么走
                PP=zeros(Len_LJD);
                for i=1:Len_LJD
                    PP(i)=(Tau(W,LJD(i))^Alpha)*((Eta(LJD(i)))^Beta);
                end
                sumpp=sum(PP);
                PP=PP/sumpp;%建立概率分布
                Pcum(1)=PP(1);
                for i=2:Len_LJD
                    Pcum(i)=Pcum(i-1)+PP(i);
                end
                Select=find(Pcum>=rand);
                to_visit=LJD(Select(1));
                %状态更新和记录
                Path=[Path,to_visit];                %路径增加
                PLkm=PLkm+DD(W,to_visit);    %路径长度增加
                W=to_visit;                   %蚂蚁移到下一个节点
                for kk=1:N   % 更新禁忌表
                    if TABUkm(kk)==0  % 禁忌表
                        DD(W,kk)=0;  % 双向关系
                        DD(kk,W)=0;
                    end
                end
                TABUkm(W)=0;                %已访问过的节点从禁忌表中删除
                DW=DD(W,:);
                DW1=find(DW);
                for j=1:length(DW1)
                    if TABUkm(DW1(j))==0
                        DW(j)=0;
                    end
                end
                LJD=find(DW);
                Len_LJD=length(LJD);%可选节点的个数
            end
            %记下每一代每一只蚂蚁的觅食路线和路线长度
            ROUTES{k,m}=Path;
            if Path(end)==E
                PL(k,m)=PLkm;
                if PLkm                     mink=k;
                    minl=m;
                    minkl=PLkm;
                end
            else
                PL(k,m)=0;
            end
        end
        %更新信息素
        Delta_Tau=zeros(N,N);%更新量初始化
        for m=1:M
            if PL(k,m)
                ROUT=ROUTES{k,m};
                TS=length(ROUT)-1;%跳数
                PL_km=PL(k,m);
                for s=1:TS
                    x=ROUT(s);
                    y=ROUT(s+1);
                    Delta_Tau(x,y)=Delta_Tau(x,y)+Q/PL_km;
                    Delta_Tau(y,x)=Delta_Tau(y,x)+Q/PL_km;
                end
            end
        end
        Tau=(1-Rho).*Tau+Delta_Tau;%信息素挥发一部分,新增加一部分
    end
    
    for i=1:K
        PLK=PL(i,:);  % 第i次迭代每只蚂蚁的路程
        Nonzero=find(PLK);
        PLKPLK=PLK(Nonzero);
        if length(PLKPLK) == 0  % 该世代的蚂蚁全部没找到终点
            minPL(i) = 10000;  % 此时赋一个很大的值,代表没最优路径
            continue;
        end
        minPL(i)=min(PLKPLK);  % 本次迭代的最短路程
    end
    
    %绘图
    plotif=1;%是否绘图的控制参数
    if plotif==1 %绘收敛曲线
        minPL=zeros(K);
        for i=1:K
            PLK=PL(i,:);
            Nonzero=find(PLK);
            PLKPLK=PLK(Nonzero);
            minPL(i)=min(PLKPLK);
        end
        figure(1)
        plot(minPL);
        hold on
        grid on
        title('收敛曲线变化趋势');
        xlabel('迭代次数');
        ylabel('最小路径长度'); %绘爬行图
        figure(2)
        axis([0,MM,0,MM])
        for i=1:MM
            for j=1:MM
                if G(i,j)==1
                    x1=j-1;y1=MM-i;
                    x2=j;y2=MM-i;
                    x3=j;y3=MM-i+1;
                    x4=j-1;y4=MM-i+1;
                    fill([x1,x2,x3,x4],[y1,y2,y3,y4],[0.2,0.2,0.2]);
                    hold on
                else
                    x1=j-1;y1=MM-i;
                    x2=j;y2=MM-i;
                    x3=j;y3=MM-i+1;
                    x4=j-1;y4=MM-i+1;
                    fill([x1,x2,x3,x4],[y1,y2,y3,y4],[1,1,1]);
                    hold on
                end
            end
        end
        hold on
        title('本次迭代的最优路径');
        xlabel('x');
        ylabel('y');
        ROUT=ROUTES{mink,minl};
        LENROUT=length(ROUT);
        Rx=ROUT;
        Ry=ROUT;
        for ii=1:LENROUT
            Rx(ii)=a*(mod(ROUT(ii),MM)-0.5);
            if Rx(ii)==-0.5
                Rx(ii)=MM-0.5;
            end
            Ry(ii)=a*(MM+0.5-ceil(ROUT(ii)/MM));
        end
        plot(Rx,Ry)
    end
end
 
% G2D函数实现
function D=G2D(G)
    L=size(G,1);
    D=zeros(L*L,L*L);
    for i=1:L
        for j=1:L
            if G(i,j)==0
                for m=1:L
                    for n=1:L
                        if G(m,n)==0
                            im=abs(i-m);
                            jn=abs(j-n);
                            if im+jn==1||(im==1&&jn==1)  % 8邻域内
                                D((i-1)*L+j,(m-1)*L+n)=(im+jn)^0.5;  % D矩阵内每一行存储是一个点的8邻域内的距离
                            end
                        end
                    end
                end
            end
        end
    end
end

 

你可能感兴趣的:(算法)