如何使用A star算法查找前100条最短路径?
答案 0 :(得分:8)
找到第k个最短路径的问题是NP-Hard,因此对A-Star进行的任何修改都将是输入大小的指数。
<强>证明:强>
(注意:我将在简单的路径上显示)
假设您有一个在多项式时间内运行的多项式算法,并返回k
的最短路径长度,让算法为A(G,k)
最大路径数为n!
,并且通过在[1,n!]
范围内应用二进制搜索来查找长度为n
的最短路径,您需要O(log(n!)) = O(nlogn)
次调用A
。
如果您发现有一条长度为n
的路径 - 它是hamiltonian path。
通过重复图表中每个源和目标的过程(O(n^2)
),您可以多项式求解Hamiltonian Path Problem,假设存在A
。
的 QED 强>
由此我们可以得出结论,除非P=NP(并且根据大多数CS研究人员不太可能),否则问题不能通过多项式解决。
另一种方法是使用Uniform Cost Search的变体而不保持visited
/ closed
设置。您也可以修改A *,通过禁用已关闭的节点,并且一旦遇到而产生/生成解决方案而不是返回它们并完成,但我想不出一种方法来证明它为A *此刻。
答案 1 :(得分:0)
除了NP
这个问题 - 很难,如果没有重大修改,就无法使用A*
或dijkstra
执行此操作。以下是一些主要原因:
首先,算法到目前为止每一步都只保留最佳路径。请考虑以下图表:
A
/ \
S C-E
\ /
B
假设距离为d(S,A)=1, d(S,B)=2, d(A,C)=d(B,C)=d(C,E)=10
。
访问C时,您将通过A
选择路径,但您无法通过B
存储路径。所以你必须保留这些信息。
但是,其次,你甚至不考虑每条路径,假设如下图:
S------A--E
\ /
B--C
假设距离d(S,A)=1, d(S,B)=2, d(B,C)=1, d(A,E)=3
。您的访问顺序为{S,A,B,C,E}
。因此,在访问A
时,您甚至无法通过B
和C
保存绕行路线,因为您不知道。你必须为每个未访问的邻居添加类似“通过C的潜在路径”的东西。
第三,你必须合并循环和cul-de-sacs's,因为是的,一个带有循环的路径最终可能是你的100条最短路径之一。你当然可能想要限制它,但这是一种通用的可能性。考虑例如这样的图:
S-A--D--E
| |
B--C
很明显,您可以轻松地在此处开始循环,除非您不允许“返回”(例如,如果D->A
已经在路径中,则禁止A->D
。实际上,如果没有明显的图形循环,这甚至是一个问题,因为在通用情况下,您总是可以在两个邻居(路径A-B-A-B-A-...
)之间进行乒乓。
现在我甚至可能忘记了一些问题。
请注意,大多数这些事情使得开发通用算法也很困难,当然最后一部分是因为使用循环很难限制可能的路径数量(“无限循环”)。
答案 2 :(得分:0)
这不是NP硬算法,下面的链接是用于在多项式时间内计算图中K最短路径的Yen算法。 Yen's algorithm link
答案 3 :(得分:-1)
当目的地第k次推入队列时,使用*搜索。这将是第k个最短的路径。