jeremy的路径规划学习:蚁群算法

蚁群算法

声明:图片及内容基于:https://www.bilibili.com/video/BV1dA411s7Eb

python推荐:https://blog.csdn.net/fanxin_i/article/details/80380733?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162684729216780265491611%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=162684729216780265491611&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-80380733.first_rank_v2_pc_rank_v29&utm_term=%E8%9A%81%E7%BE%A4%E7%AE%97%E6%B3%95&spm=1018.2226.3001.4187

 蚁群算法(Ant Colony Algorithm, ACA) 于1992年在首次提出,
该算法模拟了自然界中蚂蚁的觅食行为。
 •蚂蚁在寻找食物源时, 会在其经过的路径上释放一种信息素, 并能够感知其它蚂蚁释放的信息素。 信息素浓度的大小表征路径
的远近, 信息素浓度越高, 表示对应的路径距离越短。
 通常, 蚂蚁会以较大的概率优先选择信息素浓度较高的路径, 并
释放一定量的信息素, 以增强该条路径上的信息素浓度, 这样,
会形成一个正反馈。 最终, 蚂蚁能够找到一条从巢穴到食物源的
最佳路径, 即距离最短。
 用蚂蚁的行走路径表示待优化问题的可行解, 整个蚂蚁群体的所
有路径构成待优化问题的解空间。
 路径较短的蚂蚁释放的信息素量较多, 随着时间的推进, 较短的
路径上累积的信息素浓度逐渐增高, 选择该路径的蚂蚁个数也愈
来愈多。
 最终, 整个蚂蚁会在正反馈的作用下集中到最佳的路径上, 此 时对应的便是待优化问题的最优解。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

%% 初始化参数
% 根据节点的邻近节点表及字母节点-数字节点对应表,构造节点元胞数组
nodes_data = cell(0);
nodes_data(1,:) = {1, [2, 6, 7], [12, 16, 14]};
nodes_data(2,:) = {2, [1, 3, 6], [12, 10, 7]};
nodes_data(3,:) = {3, [2, 4, 5, 6], [10, 3, 5, 6]};
nodes_data(4,:) = {4, [3, 5], [3, 4]};
nodes_data(5,:) = {5, [3, 4, 6, 7], [5, 4, 2, 8]};
nodes_data(6,:) = {6, [1, 2, 3, 5, 7], [16, 7, 6, 2, 9]};
nodes_data(7,:) = {7, [1, 5, 6], [14, 8, 9]};

% 始末节点
node_start = 4;                       % 初始源节点
node_end = 1;                         % 终节点

% 蚁群相关定义
m = 50;                              % 蚂蚁数量
n = size(nodes_data,1);              % 节点数量
alpha = 1;                           % 信息素重要程度因子
beta = 5;                            % 启发函数重要程度因子
rho = 0.1;                           % 信息素挥发因子
Q = 1;                               % 常数

% 迭代过程中,相关参数初始化定义
iter = 1;                            % 迭代次数初值
iter_max = 100;                      % 最大迭代次数 
Route_best = cell(iter_max,1);       % 各代最佳路径       
Length_best = zeros(iter_max,1);     % 各代最佳路径的长度  
Length_ave = zeros(iter_max,1);      % 各代路径的平均长度

% 将信息素、挥发因子一并放入nodes_data中
Delta_Tau_initial = nodes_data(:,1:2);
for i = 1:size(nodes_data,1)
    nodes_data{i,4} = ones(1, length(nodes_data{i,3}));   % 信息素
    nodes_data{i,5} = 1./nodes_data{i,3};                 % 挥发因子
    Delta_Tau_initial{i,3} = zeros(1, length(nodes_data{i,3}));
end


%% 迭代寻找最佳路径
while iter <= iter_max  
  
    route = cell(0);
    
    %%  逐个蚂蚁路径选择
    for i = 1:m
        % 逐个节点路径选择
        neighbor = cell(0);
        node_step = node_start;
        path = node_step;
        dist = 0;
        while ~ismember(node_end, path) %当路径表里面包含了终节点时,该蚂蚁完成路径寻优,跳出循环
           
            % 寻找邻近节点           
            neighbor = nodes_data{node_step,2};
            
            % 删除已经访问过的临近节点
            idx = [];
            for k = 1:length(neighbor)
                if ismember(neighbor(k), path)
                    idx(end+1) =  k;
                end
            end
            neighbor(idx) = [];
            
            % 判断是否进入死胡同, 若是,直接返回到起点,重新寻路
            if isempty(neighbor)
                neighbor = cell(0);
                node_step = node_start;
                path = node_step;
                dist = 0;
                continue
            end
                
            
            %计算下一个节点的访问概率
            P = neighbor;
            for k=1:length(P)
                P(2,k) = nodes_data{node_step, 4}(k)^alpha * ...
                    nodes_data{node_step, 5}(k)^beta;
            end
            P(2,:) = P(2,:)/sum(P(2,:));
            
            % 轮盘赌法选择下一个访问节点
            Pc = cumsum(P(2,:));
            Pc = [0, Pc];
            randnum = rand;
            for k = 1:length(Pc)-1
                if randnum > Pc(k) && randnum < Pc(k+1)
                    target_node = neighbor(k);
                end
            end
            
            
            % 计算单步距离
            idx_temp = find(nodes_data{node_step, 2} == target_node);
            dist = dist + nodes_data{node_step, 3}(idx_temp);
            
            % 更新下一步的目标节点及路径集合            
            node_step = target_node;
            path(end+1) = node_step;         
                       
        end
        
        % 存放第i只蚂蚁的累计距离及对应路径
        Length(i,1) = dist;
        route{i,1} = path;
    end
    
    %% 计算这一代的m只蚂蚁中最短距离及对应路径
    if iter == 1
        [min_Length,min_index] = min(Length);
        Length_best(iter) = min_Length;
        Length_ave(iter) = mean(Length);
        Route_best{iter,1} = route{min_index,1};
        
    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,1} = route{min_index,1};
        else
            Route_best{iter,1} = Route_best{iter-1,1};
        end
    end
    
    %% 更新信息素
    
    % 计算每一条路径上的经过的蚂蚁留下的信息素
    Delta_Tau = Delta_Tau_initial;    
    
    % 逐个蚂蚁计算
    for i = 1:m
       
        % 逐个节点间计算
        for j = 1:length(route{i,1})-1
            node_start_temp = route{i,1}(j);
            node_end_temp = route{i,1}(j+1);
            idx =  find(Delta_Tau{node_start_temp, 2} == node_end_temp);
            Delta_Tau{node_start_temp,3}(idx) = Delta_Tau{node_start_temp,3}(idx) + Q/Length(i);
        end
        
    end
    
    % 考虑挥发因子,更新信息素
    for i = 1:size(nodes_data, 1)
        nodes_data{i, 4} = (1-rho) * nodes_data{i, 4} + Delta_Tau{i, 3};
    end
    
    % 更新迭代次数
    iter = iter + 1;
end


%% 绘图、结果    

figure
plot(1:iter_max,Length_best,'b',1:iter_max,Length_ave,'r')
legend('最短距离','平均距离')
xlabel('迭代次数')
ylabel('距离')
title('各代最短距离与平均距离对比')

% 最优路径
[dist_min, idx] = min(Length_best);
path_opt = Route_best{idx,1};

另一个例子:

%% I. 清空环境
clc
clear all
%% II. 符号说明
% C                         -- n个城市的坐标
% NC_max                    -- 最大迭代次数
% m                         -- 蚁群中蚂蚁的数量,一般设置为城市的1.5% D(i, j)                   -- 两城市i和之间的距离
% Eta(i, j) = 1 ./ D(i, j)  -- 启发函数
% alpha                     -- 表征信息素重要程度的参数
% beta                      -- 表征启发函数重要程度的参数
% rho                       -- 信息素挥发因子
% Q                         --
% rBest                     -- 各代最佳的路线
% lBest                     -- 各代最佳路线的长度
% lAverage                  --各代的平均长度
 
%% III. 导入城市位置数据
citys = [18.4700   95.1000
     16.4700   94.6400
     20.0900   94.5400
     14.3900   93.3700
     25.2300   97.2400
     22.0000   93.0500
     23.4700   92.0200
     16.2000   96.2900
     17.3000   97.3800
     13.0500   98.1200
     15.5300   97.3800
     24.5200   95.5900
     16.4100   97.1300
     15.0900   92.5500];
 
%% IV. 计算距离矩阵
D = Distance(citys);                                        % 计算距离矩阵
n = size(D, 1);                                             % 城市的个数
  
%% V. 初始化参数
NC_max = 200;                                               % 最大迭代次数,取100~500之间
m = 22;                                                     % 蚂蚁的个数,一般设为城市数量的1.5倍
alpha = 1;                                                  % α 选择[1, 4]比较合适
beta = 4;                                                   % β 选择[3 4 5]比较合适
rho = 0.2;                                                  % ρ 选择[0.1, 0.2, 0.5]比较合适
Q = 20;
NC = 1;                                                     % 迭代次数,一开始为1
 
Eta = 1 ./ D;                                               % η = 1 / D(i, j) ,这里是矩阵
Tau = ones(n, n);                                           % Tau(i, j)表示边(i, j)的信息素量,一开始都为1
Table = zeros(m, n);                                        % 路径记录表
 
rBest = zeros(NC_max, n);                                   % 记录各代的最佳路线
lBest = inf .* ones(NC_max, 1);                             % 记录各代的最佳路线的总长度
lAverage = zeros(NC_max, 1);                                % 记录各代路线的平均长度
 
%% VI. 迭代寻找最佳路径
while NC <= NC_max
    %1步:随机产生各个蚂蚁的起点城市
    start = zeros(m, 1);
    for i = 1: m
        temp = randperm(n);
        start(i) = temp(1);
    end
    Table(:, 1) = start;                                    % Tabu表的第一列即是所有蚂蚁的起点城市
    citys_index = 1: n;                                     % 所有城市索引的一个集合
    %2步:逐个蚂蚁路径选择
    for i = 1: m
        % 逐个城市路径选择
        for j = 2: n
            tabu = Table(i, 1: (j - 1));                    % 蚂蚁i已经访问的城市集合(称禁忌表)
            allow_index = ~ismember(citys_index, tabu);
            Allow = citys_index(allow_index);               % Allow表:存放待访问的城市
            P = Allow;
             
            % 计算从城市j到剩下未访问的城市的转移概率
            for k = 1: size(Allow, 2)                       % 待访问的城市数量
                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
     
    %3步:计算各个蚂蚁的路径距离
    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
     
    %4步:计算最短路径距离及平均距离
    if NC == 1
        [min_Length, min_index] = min(length);
        lBest(NC) = min_Length;
        lAverage(NC) = mean(length);
        rBest(NC, :) = Table(min_index, :);
    else
        [min_Length, min_index] = min(length);
        lBest(NC) = min(lBest(NC - 1), min_Length);
        lAverage(NC) = mean(length);
        if lBest(NC) == min_Length
            rBest(NC, :) = Table(min_index, :);
        else
            rBest(NC, :) = rBest((NC - 1), :);
        end
    end
    %5步:更新信息素
    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;
 
    %6步:迭代次数加1,并且清空路径记录表
    NC = NC + 1;
    Table = zeros(m, n);
end
%% VII. 结果显示
[shortest_Length, shortest_index] = min(lBest);
shortest_Route = rBest(shortest_index, :);
disp(['最短距离:' num2str(shortest_Length)]);
disp(['最短路径:' num2str([shortest_Route shortest_Route(1)])]);
 
%% VIII. 绘图
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: NC_max, lBest, 'b', 1: NC_max, lAverage, 'r:')
legend('最短距离', '平均距离')
xlabel('迭代次数')
ylabel('距离')
title('各代最短距离与平均距离对比')

function D = Distance(citys)
%% 计算两两城市之间的距离
% 输入:各城市的位置坐标(citys)
% 输出:两两城市之间的距离(D)
 
n = size(citys, 1);
D = zeros(n, n);
for i = 1: n
    for j = i + 1: n
            D(i, j) = sqrt((citys(i, 1) - citys(j, 1))^2 + (citys(i, 2) - citys(j, 2))^2);
            D(j, i) = D(i, j);
    end
    D(i, i) = 1e-4;              %对角线的值为0,但由于后面的启发因子要取倒数,因此用一个很小数代替0
end
end

附加:蚁群算法求多元函数极值

思想:

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值