首页 > 编程语言 >多A*算法路径规划(附MATLAB代码)

多A*算法路径规划(附MATLAB代码)

时间:2024-05-29 20:59:07浏览次数:13  
标签:Estart end frontier 路径 算法 MATLAB 代价 节点

 A*算法介绍

A*算法是一种常用的寻路算法,被广泛应用于人工智能和游戏开发中。该算法通过评估每个节点的代价和启发式函数来找到最佳路径。在这篇博文中,我们将深入探讨A*算法的原理。

A*算法的核心思想是在搜索过程中综合考虑两个因素:已经花费的代价和还需要花费的代价。具体而言,A*算法通过计算每个节点的综合评估函数f(n)来确定下一个最优的节点进行探索。其中,f(n)的计算方式为:

f(n) = g(n) + h(n)

其中,g(n)表示从起始节点到当前节点的实际代价,h(n)表示从当前节点到目标节点的估计代价。通过计算f(n),A*算法可以选择具有最小f(n)值的节点作为下一个探索的节点。

A*算法的启发式函数h(n)在很大程度上决定了算法的搜索效率。一般来说,h(n)应该是一种乐观估计,即不会高估实际代价。如果h(n)准确地估计了到目标节点的代价,那么A*算法将以最短路径找到目标节点。

总的来说,A*算法是一种高效且可靠的寻路算法,适用于许多领域的问题解决。通过深入理解A*算法的原理,我们可以更好地应用该算法,提高问题解决的效率和准确性。希望这篇博文能帮助您更好地理解A*算法的工作原理和应用场景。感谢阅读!

代码原理

这段代码实现了A*搜索算法,用于在二维网格中找到从起点到终点的最短路径。以下是对代码每个部分的详细解释:

function [dis, road] = Axing_fun(startx, starty, endx, endy, Estart_x, Estart_y, Weight, High, C, show_flag)
  • 输入参数:

    • startx, starty:起点坐标。
    • endx, endy:终点坐标。
    • Estart_x, Estart_y:网格的起始坐标。
    • Weight, High:网格的宽度和高度。
    • C:成本矩阵,表示每个格子的代价。
    • show_flag:显示标志,用于控制是否绘制路径。
  • 输出参数:

    • dis:从起点到终点的总距离。
    • road:从起点到终点的路径。

 初始化

f = 0 + abs(startx - endx) + abs(starty - endy);  % 初始估计总代价(曼哈顿距离)
already_frontier = {f, startx, starty, 0, [startx, starty]};  % 已探索节点列表
  • f:起始节点的估计总代价,使用曼哈顿距离。
  • already_frontier:已探索节点列表,包含起始节点信息。

 寻找邻居点

frontier = cell(0, 5);
N = find_frontier(startx, starty, Estart_x, Estart_x + Weight, Estart_y, Estart_y + High, C, already_frontier);
  • frontier:待探索节点列表。
  • N:起始节点的邻居点,通过find_frontier函数找到。

处理邻居点

for i = 1:size(N, 2)
    g = norm([startx, starty] - [N(1, i), N(2, i)]);  % 计算当前代价
    f = g + abs(N(1, i) - endx) + abs(N(2, i) - endy);
    frontier{i, 1} = f;
    frontier{i, 2} = N(1, i);
    frontier{i, 3} = N(2, i);
    frontier{i, 4} = g;
    frontier{i, 5} = [[startx, starty]; [N(1, i), N(2, i)]];  % 记录路径
end
frontier = sortrows(frontier, 1);  % 按总代价排序

计算邻居点的代价g和估计总代价f,并将它们添加到frontier中。

主循环:探索节点

while isempty(frontier) == 0
    current = frontier(1, :);  % 取出当前节点
    already_frontier(end + 1, :) = frontier(1, :);  % 将当前节点移入已探索列表
    frontier(1, :) = [];  % 从待探索列表中移除当前节点

    mx = current{1, 2};  % 当前节点的坐标
    my = current{1, 3};
    if show_flag == 2
        plot(current{1, 2}, current{1, 3}, 'g*');  % 用绿色*号标记当前节点
    end

    % 查找当前节点的邻居
    N = find_frontier(mx, my, Estart_x, Estart_x + Weight, Estart_y, Estart_y + High, C, already_frontier);
    for i = 1:size(N, 2)
        b = find([frontier{:, 2}] == N(1, i));
        a = b([frontier{b, 3}] == N(2, i));
        g = current{1, 4} + norm([mx, my] - [N(1, i), N(2, i)]);
        f = g + abs(N(1, i) - endx) + abs(N(2, i) - endy);
        if a > 0  % 如果节点已经在frontier中,检查是否有更小的代价
            if frontier{a, 4} > g
                frontier{a, 5} = [current{1, 5}; [N(1, i), N(2, i)]];
                frontier{a, 4} = g;
                frontier{a, 1} = f;
            end
        else  % 如果节点不在frontier中,加入frontier
            temp{1, 1} = f;
            temp{1, 2} = N(1, i);
            temp{1, 3} = N(2, i);
            temp{1, 4} = g;
            temp{1, 5} = [current{1, 5}; [N(1, i), N(2, i)]];
            temp_frontier = [temp; temp_frontier];
            if show_flag == 2
                plot(N(1, i), N(2, i), 'bs');  % 用蓝色正方形标记待检测节点
            end
        end
    end

    % 如果终点在already_frontier中,跳出循环
    if already_frontier{end, 2} == endx && already_frontier{end, 3} == endy
        plot(already_frontier{end, 5}(:, 1), already_frontier{end, 5}(:, 2), 'b', 'LineWidth', 2);
        drawnow;
        break;
    end

    % 插入排序,将新节点按代价插入frontier中
    for i = 1:size(temp_frontier, 1)
        j = 0;
        while j <= size(frontier, 1) + 1
            j = j + 1;
            if j == size(frontier, 1) + 1
                frontier = [frontier; temp_frontier(i, :)];
                break;
            end
            if temp_frontier{i, 1} < frontier{j, 1}
                if j == 1
                    frontier = [temp_frontier(i, :); frontier];
                else
                    frontier = [frontier(1:j-1, :); temp_frontier(i, :); frontier(j:end, :)];
                end
                break;
            end
        end
    end
    temp_frontier = cell(0, 5);  % 清空临时列表

    if show_flag == 1 || show_flag == 2
        p = plot(already_frontier{end, 5}(:, 1), already_frontier{end, 5}(:, 2), 'b', 'LineWidth', 2);
        drawnow;
        delete(p);
    end
end
dis = already_frontier{end, 1};  % 返回总路程
road = already_frontier{end, 5};  % 返回最短路径
  • 步骤1:取出当前代价最小的节点,将其移到already_frontier
  • 步骤2:找到当前节点的邻居点,计算邻居点的代价。
  • 步骤3:如果邻居点已在frontier中,检查并更新代价;如果不在,加入frontier
  • 步骤4:检查是否找到终点,如果找到则绘制路径并跳出循环。
  • 步骤5:按代价将新节点插入frontier中。
  • 步骤6:更新显示路径。

 最后返回最短路径的总路程和路径坐标。

 代码运行效果图

 

 代码获取链接

哔哩哔哩工房 (bilibili.com)icon-default.png?t=N7T8https://gf.bilibili.com/item/detail/1106192108

标签:Estart,end,frontier,路径,算法,MATLAB,代价,节点
From: https://blog.csdn.net/LJGHZ/article/details/139287987

相关文章

  • PSO算法路径规划(附MATLAB代码)
    粒子群优化(PSO)算法一种启发式优化算法,灵感来源于鸟群或鱼群等群体智能行为的模拟。PSO算法最早由Kennedy和Eberhart于1995年提出,通常用于解决搜索空间连续、高维的优化问题。PSO算法模拟了鸟群中鸟类搜索食物的行为。在PSO算法中,候选解称为粒子,每个粒子通过搜索空间中移动来......
  • Java数据结构与算法(红黑树)
    前言红黑树是一种自平衡二叉搜索树,确保在插入和删除操作后,树的高度保持平衡,从而保证基本操作(插入、删除、查找)的时间复杂度为O(logn)。实现原理红黑树具有以下性质:每个节点要么是红色,要么是黑色。根节点是黑色的。每个叶子节点(NIL节点,通常是空节点)是黑色的。如果一个节点......
  • Java数据结构与算法(散列表)
    前言散列表是根据关键码值(Keyvalue)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。而key的冲突主要通过链表的方式来处理,后期链表过长情况下可以通过红黑树来优化查询效率。实现原理散列函数(HashFunction):散列函数......
  • Java数据结构与算法(B+树)
    前言B+树(B+Tree)是一种平衡树数据结构,广泛用于数据库和文件系统中。它是一种自平衡的树结构,每个节点包含多个键,并且所有键都是排序的。B+树的叶子节点包含指向相邻叶子节点的指针,这使得范围查询非常高效。B+树的优点1.由于B+树在非叶子结点上不包含真正的数据,只当做索引使用......
  • ClickHouse 留存、路径、漏斗、session 位图 roaringbitmap 位图优化
    Clickhouse在大数据分析平台-留存分析上的应用_大数据_腾讯云大数据_InfoQ写作社区https://xie.infoq.cn/article/c7af40e5ba5f5f5beaccde990ClickHouse实战留存、路径、漏斗、session-腾讯云开发者社区-腾讯云https://cloud.tencent.com/developer/article/1953792导语 | ......
  • P9 【力扣+知识点】【算法】【二分查找】C++版
    【704】二分查找(模板题)看到复杂度logN,得想到二分给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。示例1:输入:nums=[-1,0,3,5,9,12],target=9输出:4解释:9出现在......
  • “量化之王”的人生算法
    ”量化之王“吉姆·西蒙斯总结自己的五大“人生算法”:1)以美为导向;2)与最聪明、最优秀的人为伍;3)不随波逐流;4)不轻言放弃;5)坚守乐观主义。5月11日,对冲基金文艺复兴科技(RenaissanceTechnologies)的创始人、传奇量化投资大师吉姆·西蒙斯(JimSimons)去世,享年86岁。《金钱心......
  • 数组算法-差分数组
    //差分数组使用背景:区间元素同步增减//差分数组:用来表示原始数组中相邻元素的差值,表示原数组的变化。classex_diff{private:vector<int>diff;public:ex_diff(vector<int>nums){/**求diff[]*diff[i]=nums[i],i......
  • 【KELM回归预测】基于麻雀算法优化核极限学习SSA-KELM-Adaboost实现风电回归预测附mat
    以下是使用麻雀算法优化核极限学习机(SSA-KELM)和Adaboost算法实现风电回归预测的MATLAB代码示例:matlab复制%导入风电数据load(‘wind_data.mat’);%假设数据存储在wind_data.mat文件中X=wind_data(:,1:end-1);%输入特征Y=wind_data(:,end);%输出标签%数......
  • 动态规划在图搜索中的应用:Floyd算法详解
    多源汇最短路问题-具有多个源点Floyd算法O(n^3)-动态规划给定一个n个点m条边的有向图,图中可能存在重边和自环,边权可能为负数。再给定k个询问,每个询问包含两个整数x和y,表示查询从点x到点y的最短距离,如果路径不存在,则输出“impossible”。数据保证图中不存在负权回路。......