Astar算法的Java实现 (其他很多都是错的,没有计入曼哈顿值的代价)

·  阅读 368

这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战


看懂本文的前提是了解清楚A星算法的原理

推荐这篇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#1issue#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:点我传送 注释全,已经在项目中使用,无任何问题

分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改