最短路径算法之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》一文中的两个问题 的相关文章

  • Tips for Qt

    Based on Qt 5 14 0 Qt Creator 4 11 0 1 在UI设计界面添加控件后 xff0c 要编译一下 xff0c 再到编辑界面写代码 xff0c 否则系统不识别新添加的控件 2 多看帮助文档 xff0c 好多开发时
  • iptables - administration tools for packet filtering and NAT

    2 iptables administration tools for packet filtering and NAT Linux Iptables Manual Incoming Traffic V 43 43 PREROUTING 4
  • java 优化双重for循环

    首先我们要有两个对象分别是 学生信息 和 学生住宿信息 span class token keyword class span span class token class name Student span span class toke
  • A*寻路算法浅析

    最近刚接触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 控制结构练习题

    练习1 某人有100 000元 每经过一次路口 需要交费 规则如下 1 当现金 gt 50000时 每次交5 2 当现金 lt 50000时 每次交1000 编程计算该人可以经过多少次路口 要求 使用while break方式完成 publ
  • java 最大公约数和最小公倍数

    题目 题目 输入两个正整数m和n 求其最大公约数和最小公倍数 比如 12和20的最大公约数是4 最小公倍数是60 说明 break关键字的使用 代码一 package l2 for 题目 输入两个正整数m和n 求其最大公约数和最小公倍数 比
  • PHP 中的 A* 搜索算法 [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 有没有人有实施A 算法在 PHP 中 我知道维基百科有一个伪代码和一个 C 伪代码的链接 但我似乎找不到已经用 PHP 编写的伪代码 我也在寻找一种高效的书面 A 算法 None
  • 如何在网格中找到所有可能的唯一路径?

    我有一个 3 x 3 网格 其中有随机放置的障碍物 其中有一个随机起点但没有终点 当没有更多的单元格可供占用时 将创建端点 移动可以向上 向下 向左或向右 如何查看网格内所有可能的唯一路径 Example 一旦在寻找路径时使用了某个单元 就
  • 在网格上编写随机路径从哪里开始比较合适?

    我不知道从哪里开始 我不是要求别人为我做这件事 但我不知道如何做 所以如果有人能指出我正确的方向 那就太好了 我无法使用谷歌找到任何东西 这就是我需要的 我需要创建一条从网格一侧到另一侧的路径 但不是以随机方式最短 我需要确保如果路径与路径
  • Astar 可以多次访问节点吗?

    我一直在阅读维基百科的 Astararticle 在他们的实现中 他们检查每个节点是否在closed设置 如果是这样 他们会跳过它 是不是有可能 如果启发式是可以接受的 但是NOT一致 我们可能需要重新访问一个节点两次 或更多次 才能改进它
  • A*,开放列表的最佳数据结构是什么?

    免责声明 我真的相信这不是类似问题的重复 我读过这些内容 他们 大多数 建议使用堆或优先级队列 我的问题更多的是 我不明白这些在这种情况下如何运作 简而言之 我指的是典型的 A A star 寻路算法 如维基百科上所述 例如 https e
  • 寻找有界子图之间的最小割集

    如果游戏地图被划分为子图 如何最小化子图之间的边 我有一个问题 我试图通过基于网格的游戏 如 pacman 或 sokoban 进行 A 搜索 但我需要找到 外壳 外壳是什么意思 子图尽可能少切边 http en wikipedia org
  • 最快的跨平台 A* 实施?

    有这么多可用的实现 使用小网格的 C 执行速度最快 CPU 占用最少 二进制文件最小 跨平台 Linux Mac Windows iPhone A 实现是什么 实施 谷歌返回 http www heyes jones com astar h
  • 当网格地图中有多个目标时,如何设计A*的启发式?

    我面临一个问题 我必须使用 A 来搜索地图 并且该地图中有多个目标需要达到 我的目标是扩展地图中的最少节点 关于如何设计这个 A 算法的启发式有什么想法吗 谢谢 假设 多个目标 是指您想要实现的目标any one 只需取所有启发式中的最小值
  • 如何获取neo4j路径中的最后一个节点?

    在这个密码查询中 将返回与 STATUS on 属性有关系的节点之间的最长路径 但我还想获取路径的最后一个节点 query START n node MATCH p n rels INCLUDE gt m WHERE ALL rel IN
  • 路径未到达我的 A* 算法中的结束节点

    继从如何在大空间范围内加速最小成本路径模型 https stackoverflow com questions 23202199 how to speed up least cost path model at large spatial
  • A* 寻路不采用最短路径

    我的 A 寻路功能总是能到达预期目的地 但它几乎总是有点偏离路线 这是一个例子 我制作了一张漂亮的图片来展示我的问题 但显然直到我的声誉达到 10 后它才会发布 抱歉 我是新人 P 本质上 它会尽可能向左或向上拉动 而不实际向路径添加更多图
  • 冰滑拼图寻路

    我对这个有点模糊的标题表示歉意 我不确定你会如何称呼这个谜题 我正在制作一种路径查找方法来查找移动次数最少的路线 而不是行驶的距离 游戏规则很简单 你必须从橙色方块移动到绿色方块 但你只能沿直线移动 并且不能停止沿该方向移动 直到碰到边界
  • 使用 A 星查找路径的启发式函数

    I am trying to find a optimal solution for the following problem 每个节点内表示的数字表示为 x y 一个节点的相邻节点总是有一个y值为 当前节点 y 值 1 更改的成本为 1

随机推荐

  • 蓝牙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 这篇入门文章的算法不能找出最短