最短路径算法之AStar算法(三) 《A* Pathfinding for Beginners》一文中的两个问题

2023-05-16

现在,看看网上流传的很广的一篇文章《A* Pathfinding for Beginners》,经典的A STar算法的入门文章,也是我前面推荐的阅读文章。

 

个人认为,这篇入门文章的算法不能找出最短路径,只能找出较短路径。因为算法有两个问题:

 

1,这篇入门文章的算法的H函数采用曼哈顿距离,该距离不是节点到终点的最短距离。根据前篇文章的注意点5,算法找出来的不一定是最短路径。看下图

绿色的点代表起点,红色的点代表终点。灰色的点代表不可通过的路径。
根据文章的算法,从起点开始依次扩展最左边的列的点,左下角的点的F值是180。而左上角的点的F值200.那么,根据文章中的算法,图下半面的点的F值统一是180,直至终点都是180,而左上角的点直至算法结束都不会被扩展。
因此,根据文章中的算法选择的路径就是下半面的唯一的一条通向终点的路径。如下图所示,紫色的格代表了选择的路径。

可是实际上的最短路径是下图所示的路径:

 

 

2,将AStar算法入门文章中的算法和本文前面列出的算法进行比较,可以发现一个区别,就是当某个节点已经在close链表中时。AStar算法入门文章中的算法是当某个节点已经在close链表中时就不会被重新放到open链表再次进行扩展,但是本文前面列出的的算法是当某个节点在close链表中时可以被重新放到open链表中并且重新被扩展。根据注意点2,AStar算法入门文章中的算法是不对的。看下图

起点左方的节点(里面标有1)的F值是180,而右面的节点(里面标有2)的F值是160。因此从起点右面的节点开始扩展。根据文章中的算法,会按照下图所示的路径进行扩展,一直扩展到标有3的紫色节点,该节点的F值是180,因此它的下一个后继节点就是它上面的标有4节点,F值是200,该F值已经大于起点左边的标有1的F值是180的节点

于是开始从标有1的节点开始继续扩展。扩展到标有6的节点,如下图:

从标有6的节点开始扩展时,遇到后继节点5,但是节点5已经在close链表中了,不会进行处理。因此,按照文章中的算法找到的最短路径如下图

 

实际上,最短路径应该是如下图所示的:

 

现在来解决这两个问题。首先解决的就是H函数的问题。H函数不应该选取曼哈顿距离,应该是最短路径。我们根据坐标来看距离问题,假设起点的坐标是(Xstart,Ystart),终点的坐标是(Xend,Yend)。每个格子的长度是1。图形中任意一点N的坐标是(XN,YN)。令x= XN-Xend,y=YN-Yend
如果x>y,则H(N)= y*14+(x-y)*10。如果x>y,则H(N)= x*14+(y-x)*10。


解决了第一个问题,现在看看第二个问题。其实,解决了第一个问题以后,第二个问题就捎带着解决了。


道理很简单,点N的F值是G(N)+H(N)。按照修改过的H函数计算方法,扩展点N时,它的后继节点M的F值只可能大于或者等于F(N),而不可能小于F(N)。假设F(M)<F(N)。F(M)=G(M)+H(M)=G(N)+w(N,M)+H(M)。w(N,M)代表了从N到M的路径值或者是10或者是14。F(N)=G(N)+H(N)。也就是所,G(N)+H(N)> G(N)+w(N,M)+H(M)。两边去掉G(N),可以得到,H(N)> w(N,M)+H(M)。那么就是说从N到M再到终点的最短距离比从N到终点的最短距离要短,这本身就是一个矛盾的结论,因为N到M再到终点的路径本身就属于从N到终点的路径!


有了这个结论,来看第二个问题。
随着第一个问题的解决,AStar算法入门文章中的算法和本文中的算法的唯一区别就在于当一个节点已经在close链表中时是否会被再次扩展。AStar算法入门文章中的算法不会再次扩展,而按照本文中的算法,如果新计算的节点的F值小于被放入close链表时的F值,那么该节点会被放进open链表中重新等待扩展。
现在我们假设某个节点C已经被放到了close链表中,并且此时的F值为M,并且在以后的某个时候重新计算节点C的F值时得到了一个更小的F值N,N<M,此时对应的路径是l。那么根据上面的结论,属于路径l的在节点C的前面的节点的F值都小于N,因此都小于M。
我们现在看看路径l。设在路径l上起点到C的节点依次为start-l1-l2-…-lk-C,此时它们的F值(除了start和C)依次为为F1、F2、…Fk
如果沿着这条路径进行扩展,那么从start到C的所有节点的F值都小于M。当从start开始扩展时,l1被放到了open链表中。此时l1的F值只可能是F1(证明很简单,和起点直接相连的节点的F值一开始就是最小值并且不会改变。因为从起点到这些节点的最短距离就是和他们到起点的直接距离,根据F=G+H。H函数不变,当G达到最小值时F就达到了最小值)。因为l1的节点的F值小于M,因此在l1没有被扩展时C节点是不可能以M做为F值而被扩展的。
当l1被扩展时,l2作为它的后继节点计算其F值为F2。根据AStar算法,如果l2节点在open链表中,则它的F值肯定小于或者等于F2,此时如果l2没有被扩展,则C节点是不可能以M做为F值而被扩展的。如果l2节点在close链表中,则它肯定是已经被以小于或者等于F2的值被扩展了。因此,当l2节点没有被以小于或者等于F2的F值被扩展时,C节点是不可能以M做为F值而被扩展的。
我们现在假设,lk-1(k>=3)被以小于或者等于Fk-1的F值F’k-1。F’k-1=G’(lk-1)+H(lk-1),Fk-1=G(lk-1)+H(lk-1),因此,G’(lk-1)<= G(lk-1)。
现在来看lk。F’k=G’(lk)+H(lk)=G’(lk-1)+w(lk-1,lk)+H(lk)。而Fk=G(lk)+H(lk)= G(lk-1)+w(lk-1,lk)+H(lk)。因为G’(lk-1)<= G(lk-1),因此,F’k<=Fk。根据AStar算法,如果lk节点在open链表中,则它的F值肯定小于或者等于Fk,此时如果lk没有被扩展,则C节点是不可能以M做为F值而被扩展的。如果lk节点在close链表中,则它肯定是已经被以小于或者等于Fk的值被扩展了。因此,如果lk-1(k>=3)以小于或者等于Fk-1的F值被扩展,那么当lk节点没有被以小于或者等于Fk的F值被扩展时,C节点是不可能以M做为F值而被扩展的。
当lk节点被以小于或者等于Fk的F值被扩展时,根据和上面相同的过程可以推出C节点必须以小于或者等于N的F值被扩展后才可能以M值被扩展。但是这本身是矛盾的,因为N<M,根据AStar算法,对于某个节点而言,不可能以较大的F值去替换较小的F值。
因此,我们可以推出,对于修改过的算法,每个节点都只可能以最小的F值被扩展一次,并且以后不会被再次扩展。因此,在这个情况下,AStar入门文章的算法和本文的算法是相同的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

最短路径算法之AStar算法(三) 《A* Pathfinding for Beginners》一文中的两个问题 的相关文章

  • unity3d:Astar寻路,A星,A*,二叉堆优化Open表

    原理视频 油管 xff1a https youtu be i0x5fj4PqP4 别人的B站翻译 xff1a https www bilibili com video BV1v44y1h7Dt spm id from 61 333 999
  • Trajectory generation for quadrotor while tracking a moving target in cluttered environment

    四旋翼在杂波环境下跟踪运动目标的轨迹生成 摘要1 文章主要贡献2 前言2 1 轨迹公式2 2 实现结构 3 跟踪轨迹生成3 1 标称路径点生成3 2 可行路径点生成3 3 安全飞行走廊生成3 4 代价函数3 5 强制约束3 6 求解跟踪轨迹
  • Online Trajectory Generation of a MAV for Chasing a Moving Target in 3D Dense Environments

    微型无人机的在线轨迹生成 xff0c 用于在3D密集环境中追踪运动目标 摘要一 介绍二 相关工作A 在障碍物环境中追逐B 通过预先规划安全地生成轨迹 三 问题陈述A 问题设置B 能力C 命名 IV 视点生成A 可见度指标B 具有安全性和可见
  • 学习ROS-Academy-for-Beginners-noetic,修改记录

    一 编译安装ROS Academy for Beginners noetic 可以参考我之前的博客ROS Academy for Beginers noetic安装教程 之后可以看到里面提供了很多例程 xff0c 包括 软件包 内容 rob
  • A*寻路算法浅析

    最近刚接触A 寻路算法 听说是一种比较高效的自动寻路的算法 当然 事实也正是如此 这么好的东西 自然是要收入囊中的 说不定什么时候也能派上用场呢 为了学习这个 也是上网找了好多资料 看了好多博客 但是貌似有些关键点没有具体说明 所以自己也是
  • Python语法:... for ... in ... if ...

    Python中 for in if 语句是一种简洁的构建List的方法 从for给定的List中选择出满足if条件的元素组成新的List 其中if是可以省略的 下面举几个简单的例子进行说明 for in for in 语句 实例如下 1 a
  • Python 的 map、列表推导、循环效率比较

    话不多说 直接上代码 1 准备数据 三个列表 import time x x1 x2 for i in range 1000000 x append i x1 append i x2 append i 2 开始表演 2 1 for循环 st
  • 教妹学Java(十五):for循环详解

    你好呀 我是沉默王二 一枚颜值与才华俱在的程序员 本篇教程通过我和三妹对话的形式来谈一谈 for while do while 循环之间的差别 以及重点介绍一下 for 循环 while do while 会在接下来的教程中单独介绍 教妹学
  • 第二节 分支和循环语句

    第二节 分支和循环语句 目录 一 什么是语句 二 分支语句 选择结构 三 循环语句 本章重点 分支语句 if switch 循环语句 while for do while goto语句 一 什么是语句 C语句可分为以下五类 表达式语句 函数
  • matlab for循环坑

    matlab 用 for 嵌套循环遍历数组时 可能有 bug matlab octave 环境 linux Matlab R2018a 1 windows GNU Octave version 5 2 0 以 for x vector 的形
  • 批处理学习教程(4)------for的用法

    循环 for 1 如果批处理不具备批量处理的功能 那么它就徒有虚名了 而命令 for 在某种意义上彻底体现出了批处理的强大快捷省事批量的作用 在看过 for 后 可以归纳出 for 大致可以分三种常用的类型 或者叫使用方法 从针对的循环目标
  • 寻找 A* 算法的启发式有哪些好方法?

    您有一张方形图块地图 您可以在其中向 8 个方向中的任意方向移动 鉴于您有名为的函数cost tile1 tile2 它告诉您从一个相邻图块移动到另一个图块的成本 您如何找到既可接受又一致的启发式函数 h y goal 给定此设置 寻找启发
  • 如何在迷宫中找到最短路线?

    我想编写一个代码 当给定迷宫作为矩阵时给出最短路线 在这种情况下 该迷宫的矩阵表示如下 1 2 3 4 1 2 0 0 0 2 1 1 0 1 3 0 1 0 0 4 1 1 1 3 where 0 denotes inaccessible
  • 如何在网格中找到所有可能的唯一路径?

    我有一个 3 x 3 网格 其中有随机放置的障碍物 其中有一个随机起点但没有终点 当没有更多的单元格可供占用时 将创建端点 移动可以向上 向下 向左或向右 如何查看网格内所有可能的唯一路径 Example 一旦在寻找路径时使用了某个单元 就
  • 通过需要考虑多种成本的矩阵的最佳路径

    例如给出以下矩阵 0 8 0 3 0 8 8 0 3 0 0 5 0 1 0 6 0 0 对于每个元组 第一个数字是食物 第二个数字是水 我需要从右下角到左上角 并且只能向上或向左移动 我需要收集尽可能多的食物和水 这样我才能活得尽可能长
  • 如何使用A*算法找到最佳的3条路线

    在 A 中 通常您得到的结果只是一条路径 对于给定的出发地和目的地 是否有可能根据 A 有 3 条推荐路径 所以第二个返回的是第二最佳路径 第三个返回的是第三最佳路径 我正在考虑也许以某种方式修改启发式以反映第二和第三最佳路径 你们觉得怎么
  • 路径查找算法:A* 与跳跃点搜索

    我知道 A 比 Dijkstra 算法更好 因为它考虑了启发式值 但是从 A 和跳跃点搜索来看 哪种算法是在有障碍物的环境中找到最短路径的最有效算法 有何不同 跳跃点搜索是基于图表上的某些条件的改进的 A 因此 如果满足这些条件 主要是统一
  • 寻找有界子图之间的最小割集

    如果游戏地图被划分为子图 如何最小化子图之间的边 我有一个问题 我试图通过基于网格的游戏 如 pacman 或 sokoban 进行 A 搜索 但我需要找到 外壳 外壳是什么意思 子图尽可能少切边 http en wikipedia org
  • 明星算法:距离启发式

    我正在使用 A 星算法 如此处所示 取自http code activestate com recipes 578919 python a pathfinding with binary heap http code activestate
  • 如何在 QuickGraph Dijkstra 或 A* 中设置目标顶点

    我使用的是 QuickGraph 3 6 版 我找到了函数 SetRootVertex 但没有 SetTagretVertex 我需要这个 因为我正在巨大的图中搜索短路径 这会大大加快程序速度 有问题的类是 DijkstraShortest

随机推荐

  • 蓝牙Mesh基础(9)设备配网

    设备配网 xff08 启动配置 xff09 设备配网过程配网PDU配网PDU如何传输呢 设备配网过程 首先 xff0c 需要配网的设备先进行未配网广播 xff0c 这个广播不同于普通的ble广播 xff0c 广播数据结构类型 xff08 A
  • 弱网络环境模拟--树莓派搭建ATC

    弱网络环境模拟 树莓派搭建ATC 1 硬件和系统2 搭建过程3 遇到的问题1 Failed to start hostapd service Unit hostapd service is masked2 django python版本问题
  • OpenCV双目相机测距程序

    本文主要分享一个双目测距的实现程序 xff0c 用的bumblebee2相机 使用的OpenCV自带的BM算法 在OpenCV3中 xff0c StereoBM算法发生了比较大的变化 xff0c StereoBM被定义为纯虚类 xff0c
  • stm32 printf 串口输出

    在使用STM32调试时 xff0c 经常使用串口发送信息 xff0c 为了方便调试与串口发送信息 xff0c 用printf xff08 xff09 函数实现通过串口打印信息 1 添加包含printf xff08 xff09 函数的头文件
  • 【slighttpd】基于lighttpd架构的Server项目实战(7)—http-parser

    对于http服务器 xff0c http request的解析是比较麻烦的 xff0c 由于我们的重点并不在这上面 xff0c 所以这一部分不打算自己编写 xff0c 而是使用开源的http parser库 xff0c 下面我们将使用该库来
  • C#实现以图搜图

    朋友们 xff0c 如需转载请标明出处 xff1a http blog csdn net jiangjunshow 前言 最近在逛淘宝时发现了淘宝的图片搜索功能 xff0c 可能是我太Low了这个技术点已经实现很长时间了 想想自己能不能实现
  • 床长人工智能教程 - 前言

    朋友们 如需转载请标明出处 xff1a http blog csdn net jiangjunshow 人工智能被认为是一种拯救世界 终结世界的技术 毋庸置疑 xff0c 人工智能时代就要来临了 xff0c 科幻电影中的场景将成为现实 xf
  • 如何做接口测试呢?接口测试有哪些工具【小白都会系列】

    回想入职测试已经10年时间了 xff0c 初入职场的我对于接口测试茫然不知 后来因为业务需要 xff0c 开始慢慢接触接口测试 从最开始使用工具进行接口测试到编写代码实现接口自动化 xff0c 到最后的测试平台开发 回想这一路走来感触颇深
  • C++有限状态自动机解析HTTP协议

    一 HTTP请求报文格式 HTTP请求报文主要由四部分组成 xff0c 分别为请求头 请求行 空行 请求体 xff1b 请求方法 请求方法包括GET HEAD PUT POST TRACE OPTIONS DELETE等 xff1b xff
  • 解析URL

    简介 在github有轮子http parser解析器 小的就不再造轮子了 xff0c 哈哈 xff08 造这个轮子真不是一时半会的事 xff09 目前该解析器用于nodejs的http解析 xff0c 另还有大家熟知的tcpflow 以及
  • ubuntu 串口调试助手

    ubuntu 下的串口调试助手推荐有两个 PuTTY 和 CuteCom PuTTY 除了串口通讯功能外还有 SSH 和 Telnet 等功能 CuteCom 只能用于串口通讯 但串口界面更友好 安装串口工具 ubuntu 标准安装源中包含
  • 数据的存储(1):字节序与比特序

    前言 在计算机的发展过程中 xff0c 由于不同硬件体系在数据高低有效位及存储方式理解上的差异 xff0c 出现了大端和小端这两种截然相反的对数据的位进行解释的模式 大小端模式本身没有优劣之分 xff0c 但我们在开发过程中 xff0c 需
  • [C/C++后端开发学习] 11 实现一个简单的HTTP服务器

    文章目录 实现GET方法约定GET时URI的格式状态机与websocket协议兼容实现几个辅助函数GET请求一个html页面 一张图片或一个PDF文件 实现POST方法实现一个简单的服务框架POST请求报文处理的代码块POST响应报文处理的
  • C++ Primer Plus习题及答案-第六章

    习题选自 xff1a C 43 43 Primer Plus 第六版 内容仅供参考 xff0c 如有错误 xff0c 欢迎指正 1 简单文件输入 输出 xff08 写入到文本文件中 xff09 对于文件输入 xff0c C 43 43 使用
  • 航模电池-LiPo锂聚合物电池(未完待续)

    一 外形 1 一般有几个电芯 xff0c 就是几 S xff0c 比如三个电芯就是3S 2 从电池上 xff0c 会引出两组导线 xff0c 一组细的 xff0c 一组粗的 细的一组 xff0c 由一根红线和若干根黑线组成 xff0c 最前
  • visual studio 编译C++程序,加快编译速度

    网上很多有关于选择预编译选项出现 xff0c fatal error C1083 无法打开预编译头文件 pch No such file or directory xff0c 这样的错误 xff0c 好多人会选择直接不使用预编译选项 如果工
  • C++中标准名称空间出错(cout,cin,endl是一个未知标识符)

    相信有很多小伙伴刚刚学习C 43 43 都有出现cout cin endl为未知标识符 原因是 xff1a lt iostream gt 头文件没有namespace std库 解决方法有3种 xff0c 如下 方法1 xff1a 加 us
  • C++源文件编译过程

    对于C 43 43 源文件 xff0c 从文本到可执行文件一般需要四个过程 xff1a 预处理阶段 编译阶段 汇编阶段 链接阶段 预处理阶段 xff1a 对源代码文件中文件包含关系 xff08 头文件 xff09 预编译语句 xff08 宏
  • 最短路径算法之AStar算法(一) AStar算法的证明

    本文并不试图对A Star算法进行一个入门式的讲解 xff0c 因为光是那个讲解就有可能会占据很长的篇幅 xff0c 而且网上已经有讲解的文章 xff0c 讲的肯定比我好 所以 xff0c 本文是面向已经对A Star算法有了一定了解的人
  • 最短路径算法之AStar算法(三) 《A* Pathfinding for Beginners》一文中的两个问题

    现在 xff0c 看看网上流传的很广的一篇文章 A Pathfinding for Beginners xff0c 经典的A STar算法的入门文章 xff0c 也是我前面推荐的阅读文章 个人认为 xff0c 这篇入门文章的算法不能找出最短