如何判断 A* 算法何时是一个好的选择,以及如何选择一个好的启发式算法?

How to tell when the A* algorithm is a good option, and how to choose a good heuristic?

最近我使用 A* 算法为著名的“15 拼图”编写了一个求解器,方法是使用启发式函数,该函数基于每个图块到其目的地点的距离的曼哈顿距离之和。

这让我想知道两件事:

  1. 你怎么知道什么时候可以使用 A* 算法?除非是看到网上的教程,否则我绝对想不到15的谜题可以这样解。

  2. 你怎么知道要使用哪个启发式函数?起初,对于 15 的谜题,我考虑了一个简单的 "sum of tiles not in position" 启发式。因此,如果所有部分都没有在正确的位置,则 15 拼图的启发式可能 return 15,而 0 表示已解决棋盘。但不知何故,距离的总和更好。一个人怎么知道,进入它?

如果您正在探索图表以找到某种方式 "shortest" 的路径(成本不一定是 "distance",但它必须是单调的),你已经可以使用 Dijkstra 的了。乍一看,您的问题通常看起来不像寻路,因为您不打算 "travel over a route"。它比那更抽象。

然后如果你可以使用 Dijkstra 你有一些可接受的启发式(这是困难的部分),你可以使用 A*。

寻找启发式方法的一种常用技术是放弃问题的某些约束。例如,如果您可以将每个图块传送到其目的地,而不管那里是否已经有一个图块,它将需要 #displacements 传送。所以有第一个启发式。如果您必须滑动瓷砖但它们可以相互滑动,则每个瓷砖的成本是到其目的地的曼哈顿距离。然后你可以看看改进启发式,例如曼哈顿距离启发式显然忽略了瓷砖移动时相互干扰的情况,但有一个简单的情况,我们知道瓷砖必须在哪里冲突并使用更多移动:考虑两个瓷砖(假装同一行中没有其他图块),它们的目的地也在该行中,但为了到达那里,它们必须相互穿过。他们必须绕着对方走,增加两个垂直移动。这给出了线性冲突启发式。可以考虑更多的干扰,例如模式数据库。