这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战
看懂本文的前提是了解清楚A星算法的原理
先吐槽
项目里的寻路算法是项目老大从网上直接copy下来用的
发现从(0,0)
到(length-1,length-1)
的路径寻不到。不止这样,以80*80
的地图为例,从(0,0)到((30,30)
之间随便找个起点,到终点(length-1,length-1)
的路径全都寻不到
排查到问题之后挺无语,百度搜到的Java实现的Astar算法都一模一样,==计算出的曼哈顿值都没乘代价10就直接当做H使用==,不止有一半的路寻不到,且效率消耗至少指数倍增长 (断点分析:寻不到路径时会将所有结点加入到closeList之后才结束,导致地图越大消耗越大)
2021.07.28 补充 通过查询到的错误资料的时间推断,大概率认为是各路大神从github复制的代码:仓库链接 经过和作者沟通,确定了是有错误的。相关issues:issue#1、issue#3 且作者也已经修改 ==同样在这里贴出 在其基础上做了小优化的实现,已经在项目中使用,没有任何问题== 仓库链接
贴几个无脑复制的错误示例
![]()
![]()
错误分析
简单举个例子,当曼哈顿值不乘代价直接作为H值来用时,会造成最直接的问题就是 会取到错误的最优点
假设从12*12地图中,(4,4)寻路到(11,11)
在(4,4)周围的八个格子中,理所当然的最优点应该是(5,5)
而实际上最优点会变成(4,5)
因为曼哈顿值不乘10(DIRECT_VALUE横竖移动代价)而直接作为H使用,是这样的:
(4,5)的G=10,F=13;而(5,5)的G=14,F=12,明显10+13 < 14+12
乘上DIRECT_VALUE再看:
(4,5)的G=10,F=130;而(5,5)的G=14,F=120,明显10+130 > 14+120
复制代码
这会使很多最优点都取错,最终产生大量不必要的节点判断,效率消耗将成至少指数倍增加,且也寻不到终点
效率
看下面检验效率的代码 消耗大的是网上错误的代码(曼哈顿值直接作为H使用),不仅死慢,而且会有很多路寻不到 消耗小的是正确的代码(曼哈顿值乘代价(10)作为H) 具体的代码实现都是一样的,但是不是直接copy网上的,我做了优化。
差距非常悬殊 (再次吐槽无脑复制)
找到的正确代码
百度筛选截止到16年的博文,基本都是正确的实现 如 A*算法的java实现
正确的Java实现代码 - 已简单优化
已上传到github:点我传送 注释全,已经在项目中使用,无任何问题