使用A *算法识别最便宜的路径

时间:2015-04-19 02:55:52

标签: java algorithm search

所以我正在编写一个使用A *搜索算法的Java程序。该程序在二维数组上运行。它有一个起始位置,一个目标和四处移动的障碍。网格上的每个对象都是一个节点。

SRRRRRRR
RXXRRXXX
RRRXXXRX
RXRRXRRR
XXXRRXRR
RRRRRRRR
XXRXRRXR
XXXXRRRG

S =开始,G =目标,R =有效移动图块,X =非法移动图块

我有两个arraylists: - openList - closedList

openList是从最便宜到最昂贵的可能动作列表。 closedList是已访问过的节点列表,不会再次访问。该算法将始终移动到openList中的第一个节点。然后,该节点将从openList中删除并添加到closedList的末尾。

我的算法可以从头到尾成功导航。我遇到的问题是我不知道如何从我的封闭节点列表中过滤出真正的路径。 A *将始终寻找最便宜的选项,这意味着它可能不会直接进入目标。 openList根据移动成本对节点进行排名,因此即使算法让一个节点远离目标,如果有一个节点更便宜地移动到路径上的某个地方,那么它将采用更便宜的节点。这意味着我保证能找到最便宜的路径,但最后我的封闭列表中将包含不在目标最佳路径上的节点。

最后,我的closedList为我提供了算法所采用的确切路径,而不是最便宜的路径。

我的问题是:在我的算法将探索的所有节点中,如何区分最便宜路径上的节点和不是最节点的节点?

2 个答案:

答案 0 :(得分:1)

我非常高兴,强烈推荐Amit Patel's A* pages,这将详细介绍您可能想要了解的有关寻路的所有信息。

要解决您的具体问题,您需要以某种方式存储您在访问节点时来自的节点,因此当您到达目标时,您只需沿着路径向后走。这可以使用Map<Node, Node>来完成,或者,您可以通过存储除节点之外的其他内容来使用对父节点的引用:包含节点的内容以及对您来访的节点的引用添加到列表时的那个节点。

答案 1 :(得分:0)

听起来您的成本函数可能会被破坏。

在A *中,成本函数始终是到目前为止所经过的路径的实际成本加上剩余距离的下限之和。 admissability of the heuristic有一些规则 - 与metric space IIRC相同。

在这种情况下,用于下限剩余距离的明显启发式算法是......

  1. 欧几里德距离 - sqrt (xdist^2 + ydist^2)
  2. 剩余曼哈顿距离 - xdist + ydist
  3. 如果沿着间接路径迈出一步之后的总成本估算并不比直接踩到目标之后更大,那么唯一可行的方法是总成本估算是否相同。除非您在成本比较测试中添加打破平局,否则A *不会采取额外步骤。但是当直接路由可用时,它不会选择成本较高的路由 - 除非你的成本函数欺骗它(或者你的代码有错误)。

    在任何情况下,如果可能的移动直接达到目标,那么同样的成本要么不应该在正方形网格中发生。

    你有可能实施Dijkstra而不是A *。 Dijstra的成本函数只是到目前为止的总行程距离。没有尝试估计剩余距离,因此没有任何东西可以指导搜索目标 - 它会在所有方向上进行平等的探索。

    意外地结束Dijkstra的一种方法是使用明显的&#34;不知情的&#34; (但允许)剩余距离的下限 - 零。

    当然,最后它仍然可能是你会搜索离开最佳路径的节点 - 通常比你获得良好的A *启发式的节点少,但即使这样也可以尴尬的地图错了。请参阅moveaway00s answer - &#34;当您访问节点时,您需要以某种方式存储您来自的节点&#34;。对于您探索的每个节点,只有一个可能的最短可能距离 - 如果节点位于最短路径上,则向后步骤是沿最短路径的反向步骤。

    对于Dijkstra来说,第一次探索位置始终是最短的方式。对于A *,它不一定是真正的IIRC(对于目标节点来说是真的,不一定是针对其他探索过的节点),因此您可能需要将最短距离与向后步骤一起存储到节点。