基于蚁群算法的路径规划

本文介绍了蚁群算法的基本原理,模拟蚂蚁觅食行为寻找最短路径,通过信息素浓度和启发函数决定蚂蚁行动。算法详细描述了蚂蚁的选择策略、信息素更新机制以及如何在实际问题中应用,如在MATLAB中求解100x100地图上的最短路径问题。
摘要由CSDN通过智能技术生成

蚁群算法(Ant Colony Algorithm, ACO)于1991年首次提出,该算法模拟了自然界中蚂蚁的觅食行为。蚂蚁在寻找食物源时,会在其经过的路径上释放一种信息素,并能够感知其它蚂蚁释放的信息素。信息素浓度的大小表征路径的远近,信息素浓度越高,表示对应的路径距离越短。通常,蚂蚁会以较大的概率优先选择信息素浓度较高的路径,并释放一定量的信息素,以增强该条路径上的信息素浓度,这样,会形成一个正反馈。最终,蚂蚁能够找到一条从巢穴到食物源的最佳路径,即距离最短。

用蚂蚁的行走路径表示待优化问题的可行解, 整个蚂蚁群体的所有路径构成待优化问题的解空间。

路径较短的蚂蚁释放的信息素量较多, 随着时间的推进, 较短的路径上累积的信息素浓度逐渐增高, 选择该路径的蚂蚁个数也愈来愈多。

最终, 整个蚂蚁会在正反馈的作用下集中到最佳的路径上, 此时对应的便是待优化问题的最优解。

具体步骤如下:

设整个蚂蚊群体中蚂蚊的数量为m, 路径节点的数量为n, 节点i与节点 j 之间的相互距离为dij ( i , j = 1 , 2 , … , n ) , t时刻节点i与节点j的连接路径上的信息素浓度为τij (t),初始时刻, 各个节点间连接路径上的信息素浓度相同。

蚂蚁k( k =1,2,…,m)根据各个节点间连接路径上的信息素浓度决定其下一个访问节点, 设Pijk (t)表示t时刻蚂蚊 k从节点 i转移到节点 j的概率, 其计算公式如下:

ηij(t)为启发函数, ηij(t)=1/dij,表示蚂蚊从节点i转移到节点j的期望程度。

allowk(k=1,2,…,m)为蚂蚁k待访问节点的集合。开始时,allowk中有n-1个元素,即包括除了蚂蚁k出发节点的其它所有节点。随着时间的推进, allowk中的元素不断减少, 直至为空, 即表示所有的节点均访问完毕。

α为信息素重要程度因子,其值越大, 蚂蚁选择之前走过的路径可能性就越大,搜索路径的随机性减弱,其值越小,蚁群搜索范围就会减少,容易陷入局部最优。一般取值范围为[0,5]。

β为启发函数重要程度因子,其值越大,表示启发函数在转移中的作用越大, 即蚂蚊会以较大的摡率转移到距离短的节点,蚁群就越容易选择局部较短路径,这时算法的收敛速度是加快了,但是随机性却不高,容易得到局部的相对最优。一般取值范围为[0,5]。

计算完节点间的转移概率后,采用轮盘赌方法选择下一个待访问的节点。依据轮盘赌法来选择下一个待访问的节点,而不是直接按概率大小选择,是因为这样可以扩大搜索范围,进而寻找全局最优,避免陷入局部最优。首先计算每个个体的累积概率qj ,之后随机生成一个(0,1)的小数r,比较所有qj与r的大小,选出大于r的最小的那个qj,该qj对应的索引j即为第k只蚂蚁在第i条路径时下一步要选择的目标点。

蚂蚁信息素更新的模型包括蚁周模型(Ant-Cycle模型)、蚁量模型(Ant-Quantity模型)、蚁密模型(Ant-Density模型)等。

区别:

蚁周模型利用的是全局信息,即蚂蚁完成一个循环后更新所有路径上的信息素。

蚁量和蚁密模型利用的是局部信息,即蚂蚁完成一步后更新路径上的信息素。

在蚂蚁释放信息素的同时,各个节点间连接路径上的信息素逐渐消失,设参数ρ(0<ρ<1,一般取值为0.1~0.99 )表示信息素的挥发程度。当所有的蚂蚁完成一次循环后,各个节点间链接路径上的信息素浓度需进行更新,计算公式为

τijt+1=1-ρτijt+Δτij

Δτij=k=1nΔτijk

其中,Δτijk表示第k只蚂蚁在节点i与节点j连接路径上释放的信息素浓度;Δτij表示所有蚂蚁在节点i与节点j连接路径上释放的信息素浓度之和。

算法流程图如下:

在实验中,设定的蚂蚁数量为50,迭代200次。在100*100的地图上随机生成地图(通过MATLAB的binornd函数实现)。从左上角顶点处(起点)走到右下角顶点处(终点),结果如下。

实验代码如下

clc

clear

G=binornd(1,0.05,100,100);

G(1,1)=0;

G(100,100)=0;

MM=size(G,1);                 %G地形图为01矩阵,如果为1表示障碍物

Tau=ones(MM*MM,MM*MM);        %Tau初始信息素矩阵 大小要与Alpha系数匹配

%Tau=8.*Tau;

K=200;                        %迭代次数(指蚂蚁出动多少波)

M=50;                         %蚂蚁个数

S=1;                          %最短路径的起始点

E=MM*MM;                      %最短路径的目的点

Alpha=1;                      %Alpha表征信息素重要程度的参数

Beta=7;                       %Beta表征启发式因子重要程度的参数

Rho=0.4;                      %Rho信息素蒸发系数

Q=1;                         %Q信息素增加强度系数

minkl=inf;                    %minkl表示当前最短路径长度

mink=0;                       %当前完成最短路径为第几次迭代

minl=0;                       %当前完成最短路径为第只蚂蚁

D=G2D(G);                     %每个栅格至各自邻域无障碍栅格的代价值

N=size(D,1);                  %N表示问题的规模(像素个数)

a=1;                          %小方格像素的边长

Ex=a*(mod(E,MM)-0.5);         %目的点横坐标

if Ex==-0.5

    Ex=MM-0.5;

end

Ey=a*(MM+0.5-ceil(E/MM));     %目的点纵坐标

Eta=zeros(1,N);               %启发式信息矩阵,记录启发式信息

%以下开始建立启发式信息矩阵

for i=1:N                     %每个栅格的索引号,一共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次迭代中的第M只蚂蚁的爬行路线

PL=zeros(K,M);        %用矩阵存储第K次迭代中的第M只蚂蚁爬行路线的长度

%开始K次迭代,每轮派出M只蚂蚁,开始寻找路径

for k=1:K               %第K次迭代

    for m=1:M           %第M只蚂蚁

        %状态初始化

        W=S;                  %将当前节点初始化为起始点

        Path=S;               %爬行路线初始化

        PLkm=0;               %爬行路线长度初始化

        TABUkm=ones(N);       %禁忌表初始化为1,禁忌表记录走过的位置,将走过的位置由1变0

        TABUkm(S)=0;          %将禁忌表起点位置置为0

        DD=D;                 %邻栅格点初始化

        %下一步可以前往的栅格点

        DW=DD(W,:);   %取G2D矩阵中以当前点为局部起始点的一行

        DW1=find(DW); %DW1矩阵存储该行中所有无障碍相邻栅格点(元素不为0)的索引位置

        for j=1:length(DW1)

            if TABUkm(DW1(j))==0  %判断TABUkm禁忌表中,该位置是否为之前走过的点

                DW(DW1(j))=0;     %删除DW中所有之前已经走过的相邻栅格点

            end

        end %现在DW中为当前栅格点可以选择的所有相邻栅格点了

        %计算各可选择邻节点的选择概率

        LJD=find(DW);       %LJD记录未走过的点的索引号,即下一步可选的点

        Len_LJD=length(LJD);%可选点的个数

        %蚂蚁未遇到食物或者陷入死胡同或者觅食停止

        while W~=E&&Len_LJD>=1 %起始点不等于终止点,且可选节点个数大于等于1

            %转轮赌法选择下一步怎么走

            PP=zeros(Len_LJD);

            for i=1:Len_LJD

                PP(i)=(Tau(W,LJD(i))^Alpha)*((Eta(LJD(i)))^Beta);

                %PP(i)=(Tau(W,LJD(i))^Alpha)*((D(W,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;                  %蚂蚁移到下一个点

            %对应禁忌表更新D中可选择的相邻栅格点

            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(DW1(j))=0;  

                end

            end

            LJD=find(DW);

            Len_LJD=length(LJD);%可选节点的个数

        end                 %本次迭代的当前蚂蚁寻路完毕

        %记下每一代每一只蚂蚁的觅食路线和路线长度

        ROUTES{k,m}=Path; %记录本次迭代中的当前蚂蚁的行走路线

        if Path(end)==E   %判断本只蚂蚁寻找路径的最后一个节点是否为终点

            PL(k,m)=PLkm; %若该蚂蚁到达终点,将本次路线长度放到PL的第k行m列

            if PLkm<minkl %若本次路径长度<当前已知的最短路径长度

                mink=k;   %记录完成本次最短路径的迭代次数

                minl=m;   %记录完成本次最短路程的哪只蚂蚁

                minkl=PLkm; %记录本次最短路线的长度

            end

        else

            PL(k,m)=0; %若该蚂蚁没有到达终点,则本次路径长度为0

        end

    end %返回进行下一只蚂蚁的寻路

    %更新信息素

    Delta_Tau=zeros(N,N);%初始化信息素增量

    for m=1:M

        if PL(k,m) 

            ROUT=ROUTES{k,m}; %ROUT取本次迭代的所有蚂蚁的行走路线

            TS=length(ROUT)-1;

            PL_km=PL(k,m); %PL_km取本次迭代当前蚂蚁的路径长度

            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

%绘图

plotif=1;%是否绘图的控制参数

if plotif==1 %绘收敛曲线

    minPL=zeros(K);

    for i=1:K %选出每次迭代的最短路径

        PLK=PL(i,:); %取第i次迭代的所有路径长度

        Nonzero=find(PLK); %提取本次迭代路径长度不为0的索引号存储至Nonzero

        if isempty(Nonzero)

            minPL(i)=0;

        else

            PLKPLK=PLK(Nonzero);

            minPL(i)=min(PLKPLK); %选出本次迭代最短路径存储至minPL的相应迭代位置

        end

    end

    %绘制“收敛曲线变化趋势”图,将每次迭代的最短路径放在图中表示

    FFF=[];

    WWJ=minPL(:,1);

    for i=1:length(WWJ)

        if WWJ(i)~=0

            FFF=[FFF;[i,WWJ(i)]];

        end

    end

    figure(1)

    plot(FFF(:,1),FFF(:,2));

    axis([0 200 0 1000]);

    hold on

    grid on

    title('收敛曲线变化趋势');

    xlabel('迭代次数');

    ylabel('最小路径长度');

    %绘爬行图

    figure(2)

    axis([0,MM,0,MM]) %设置图的横纵坐标,MM为地图矩阵的行数或列数

    for i=1:MM

        for j=1:MM

            if G(i,j)==1 %1是黑色代表障碍,0为白色无障碍

                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]); %将1234点所围成的图形进行黑色填充

                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]); %将1234点所围成的图形进行白色填充

                hold on

                set(gca,'YTickLabel',[100 90 80 70 60 50 40 30 20 10 0]); %使得地图的矩阵的行列与正常坐标轴的行列一致

                %set(gca,'YTickLabel');

            end

        end

    end

    hold on

    title('最优路径');

    xlabel('坐标x');

    ylabel('坐标y');

    ROUT=ROUTES{mink,minl};

    %ROUT取最短行走路线,mink为该路线的迭代号,minl为该路线的蚂蚁号

    LENROUT=length(ROUT);

    %Rx与Ry中分别存储具体的该路线

    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

  • 24
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个基于蚁群算法路径规划MATLAB代码示例: ```matlab % 初始化参数 num_ants = 10; % 蚂蚁数量 num_cities = 20; % 城市数量 alpha = 1; % 表示信息素重要程度的参数 beta = 5; % 表示距离重要程度的参数 rho = 0.1; % 信息素挥发率 Q = 100; % 信息素常量 num_iters = 100; % 迭代次数 % 生成随机的城市坐标 cities = 100 * rand(num_cities, 2); % 计算城市之间的距离 distances = pdist2(cities, cities); % 初始化信息素矩阵 pheromones = ones(num_cities, num_cities); % 开始迭代 for iter = 1:num_iters % 记录每只蚂蚁的走过的路径和距离 paths = zeros(num_ants, num_cities); distances_travelled = zeros(num_ants, 1); % 每只蚂蚁开始走 for ant = 1:num_ants % 随机选择一个起点城市 current_city = randi(num_cities); path = current_city; % 蚂蚁依照信息素和距离的权重选择下一个城市 for i = 1:num_cities-1 unvisited_cities = setdiff(1:num_cities, path); probabilities = pheromones(current_city, unvisited_cities).^alpha .* (1./distances(current_city, unvisited_cities)).^beta; probabilities = probabilities / sum(probabilities); next_city = randsample(unvisited_cities, 1, true, probabilities); path = [path, next_city]; current_city = next_city; end % 计算蚂蚁走过的路径和距离 paths(ant,:) = path; distances_travelled(ant) = sum(distances(sub2ind([num_cities,num_cities], path(1:end-1), path(2:end)))); end % 更新信息素矩阵 pheromones = (1-rho) * pheromones; for ant = 1:num_ants for i = 1:num_cities-1 pheromones(paths(ant,i), paths(ant,i+1)) = pheromones(paths(ant,i), paths(ant,i+1)) + Q/distances_travelled(ant); end end % 找到最短路径和长度 [shortest_path_length, shortest_path_index] = min(distances_travelled); shortest_path = paths(shortest_path_index,:); % 绘制图像 clf; hold on; plot(cities(:,1), cities(:,2), 'r.', 'MarkerSize', 20); plot(cities(shortest_path,1), cities(shortest_path,2), 'k', 'LineWidth', 2); title(sprintf('Iteration %d: shortest path length = %f', iter, shortest_path_length)); drawnow; end ``` 这段代码实现了一个简单的蚁群算法来进行城市路径规划。它随机生成一些城市坐标,计算城市之间的距离,初始化信息素矩阵,然后开始迭代。每个迭代中,它会让每只蚂蚁按照一定的规则走一遍路径,并记录它们的路径和长度。然后,它会使用这些信息更新信息素矩阵。最后,它会找到最短的一条路径,并画出城市和路径的图像。 需要注意的是,这只是一个简单示例,实际使用时可能需要根据具体问题进行一些修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wjdamowang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值