并行化 A* 以进行昂贵的成本计算

Parallelizing A* for expensive cost computation

我正在尝试使用计算耗时的成本函数执行 A*。成本函数是单线程的,可能需要几秒钟,无法优化。

我想并行计算尽可能多的成本。

以防万一,我有一个可接受的启发式算法,计算成本低。

答案中有两点要讨论。首先是算法效率。其次是并行。

有一个 research paper 研究了这个案例并创建了一个 A* 变体,DEA*。它在边成本上使用便宜的可接受的启发式方法来获得 lower-bound 后继成本,然后仅在显示后继可能位于最佳路径上时才计算边的实际成本。

通常,A* 通过以下方式扩展节点:(1) 使用新的 f-cost 生成后继节点,以及 (2) 将它们置于开放状态。 DEA* 算法 (1) 生成具有估计(下限)f-costs 的后继,(2) 将它们置于开放状态。如果仅使用 f-cost 估计从打开状态中删除状态,则会计算出准确的 edge/f-cost 并将状态放回打开状态。

这是 Partial Expansion, and other work 的一般思想的变体,也探索了昂贵的边缘问题。

在此模型中,您可以避免计算许多昂贵的边,这很有帮助。但是,并行计算剩余边仍然有用。根据确切的成本,有很多方法可以做到这一点。如果你的 open 列表是 multi-threaded,它可以在每次添加一个状态到 open 时计算边缘成本。但是,本质上有两个优先级队列会更有效率。

一个优先级队列将包含已计算边缘成本的状态,另一个将包含需要完成计算的状态。可以编写并行代码以从第二个优先级队列中获取状态并计算它们的边缘成本,并在完成后将它们添加到第一个队列中。然后,常规程序可以按照常规优先顺序从第一个队列开始处理状态。

关键是并行部分可以专注于计算接下来要展开的状态的边缘成本,而不是在将所有状态添加到队列时都进行计算。

请注意,这样的过程可能会导致在发现较短路径之前先探索较长路径。因此,您需要跟踪何时找到通往状态的较短路径(打开或关闭),并确保在发现较短路径时将状态从关闭状态移回打开状态。

与此相关,一旦找到解决方案就不能终止 - 它不一定是最优的。您需要完成所有比您找到的解决方案低 f-cost 的状态的展开。 (您可以丢弃解决方案成本大于或等于您找到的解决方案的任何状态。) [请注意,我在这里给出了关于好的方法的总体方向;如果您对具体细节有疑问,可以要求澄清。]