带有传送器的网格上的 A* 可接受的启发式方法?
Posted
技术标签:
【中文标题】带有传送器的网格上的 A* 可接受的启发式方法?【英文标题】:A* admissible heuristics on a grid with teleporters? 【发布时间】:2013-01-03 21:34:56 【问题描述】:假设您有一个 2D 单元格网格,其中一些被墙填充。角色可以从一个方格跨步到任何水平或垂直的方格,但不能跨墙。
给定一个起始位置和一个结束位置,我们可以使用 A* 算法和一个可接受的启发式算法找到从起始位置到结束位置的最短路径。在当前的设置中,曼哈顿距离是可以接受的,因为它永远不会高估到目的地的距离。
现在假设除了墙之外,这个世界还有成对的传送器。踏上传送器会立即将角色传送到链接的传送器。传送器的存在打破了上面给出的可接受的启发式方法,因为通过使用传送器缩短距离,可能比采取最佳曼哈顿距离步行更快地到达目的地。例如,考虑这个线性世界,传送器标记为 T,起始位置标记为 S,结束位置标记为 E:
T . S . . . . . . . . . . . . . E . T
这里,最好的路线是走到左边的传送点,然后向左走两步。
我的问题是:在带有传送器的网格世界中,什么是 A* 的良好可接受启发式?
谢谢!
【问题讨论】:
到最近的传送器的距离似乎是一个显而易见的选择。 @VaughnCato 结尾可能会更近,但这很容易通过额外的分钟来解决 @templatetypedef 那是一些在线编程竞赛/自动解决方案评审系统的一部分吗?如果是这样,您能给我们一个链接,以便我们加入:) 吗? @us2012- 不,这只是我在玩 Lode Runner 后的一个月里一直在思考的问题。 :-) 【参考方案1】:如果您的世界中没有太多的传送器,我会尝试以下启发式方法,其中MHD(a,b)
是单元格a
和b
之间的曼哈顿距离,T(i)
是距离单元格@987654325 最近的传送器@:
h(x,y) = min( MHD(x,y), MHD(x,T(x)) + MHD(T(y),y) )
【讨论】:
+1,这也是我的想法。我冒昧地将d*(x,y)
更改为h(x,y)
,至少 AFAIK 它是表示启发式值的约定字符。
@nhahtdh:这仍然是可以接受的,他的方法可能是高估了——据我所知,它需要最接近源头和最接近目的地的传送方式——它不能低估距离。
@amit:nhahtdh 是对的。可接受性要求永远不要高估,不要永远不要低估。
@amit:是的,h(x,y)=0
是可以接受的,因为它总是低估。我担心你在这里混淆了一些东西。
@congusbongus 我想我不明白你的意思。启发式不必考虑所有事情,它只需要确保它是可接受的。当然,您可能会找到更好的启发式方法(例如,您可以对网格进行完整的 BFS 并使用那些确切的结果,但随后您就打败了 A* 的观点),但我认为我的答案不正确/不需要更新。【参考方案2】:
形成传送器的图表:
每个传送器都有一个节点,终点位置有一个节点。 您有一条边将每个节点与其他节点连接起来,形成一个全连接图。 对于边权重,请使用每个节点的目标单元格(您进入传送器时到达的单元格)与所有其他节点之间的曼哈顿距离。使用 Dijkstra 算法计算每个节点到终点的最短距离。
您现在可以使用特定位置与所有节点之间的距离的最小值加上从节点到末端的预先计算的距离作为启发式函数。 Dijkstra 的算法只需运行一次作为预处理步骤。但是,如果传送器的数量占单元格数量的很大比例,那么与使用更简单的启发式函数相比,您可能不会获得任何好处。
【讨论】:
这没有意义,使用 Dijkatra 的算法基本上是运行 A* 和h(x,y) =0
作为“预处理”如果有的话 - 使用 floyd-warshall 算法,你需要每对 (x,y) 的距离
@amit:你只需要找到到终点的距离,而不是每对之间的距离。
我自己的两分钱的价值:我计划在一个静态世界中测试这个,预先计算是完全合理的。我其实很喜欢这种两层的方法!
@WolframH:因为它是一个启发式函数,你只需要确保你永远不会高估实际距离。没有墙的距离永远不会大于有墙的距离。
@VaughnCato:谢谢,我现在明白了。 Dijkstra 本身不使用启发式算法,它被输入了非高估的启发式值,因此产生的输出(与 Dijkstra 的输入完全相同)是原始问题的非高估启发式。不错,+1。以上是关于带有传送器的网格上的 A* 可接受的启发式方法?的主要内容,如果未能解决你的问题,请参考以下文章