如何找到覆盖有向循环图中所有节点的最短路径?

时间:2009-04-25 15:36:40

标签: c++ algorithm graph-theory cycle shortest-path

我需要一个节点的有向循环图的最短路径示例 (它应该从将作为输入的节点到达图形的所有节点。)

如果有例子,我需要用C ++或算法。

4 个答案:

答案 0 :(得分:6)

编辑:哎呀,误读了这个问题。谢谢@jfclavette选择了这个。最后的答案就是答案。

您尝试解决的问题称为Travelling salesman problem。有许多potential solutions,但它是NP完全的,所以你将无法解决大型图形。

旧答案:

您要查找的内容称为图表的girth。可以通过设置从节点到自身的距离到无穷大并使用Floyd-Warshall算法来解决。从节点i开始的最短周期的长度就是位置ii中的条目。

答案 1 :(得分:2)

在未加权的情况下:Breadth first search。 在加权的情况下:Dijkstra's

答案 2 :(得分:2)

在伪代码中:

//INPUT: graph G = (V,E)
//OUTPUT: shortest cycle length
min_cycle(G)
  min = ∞
  for u in V
    len = dij_cyc(G,u)
    if min > len
      min = len
  return min    

//INPUT: graph G and vertex s
//OUTPUT: minimum distance back to s
dij_cyc(G,s)
  for u in V
    dist(u) = ∞
                   //makequeue returns a priority queue of all V
  H = makequeue(V) //using dist-values as keys with s First In
  while !H.empty?
    u = deletemin(H)
    for all edges (u,v) in E
      if dist(v) > dist(u) + l(u,v) then
        dist(v) = dist(u) + l(u,v)
        decreasekey(H,v)

  return dist(s)

这在每个顶点上运行稍微不同的Dijkstra。突变的Dijkstras 有一些关键的区别。首先,所有初始距离都设置为∞,即使是 开始顶点。其次,必须先将起始顶点放在队列中才能生成 确保它首先出现,因为它们都具有相同的优先级。最后, mutated Dijkstras返回返回起始节点的距离。如果没有 路径返回起始顶点距离保持∞。所有这些中的最小值 从变异的Dijkstras返回是最短的路径。自Dijkstras运行 最糟糕的是在O(| V | ^ 2)和min_cycle运行这种形式的Dijkstras | V |时代, 找到最短周期的最终运行时间是O(| V | ^ 3)。如果min_cyc返回 ∞那么图是非循环的。

要返回最短周期的实际路径,只需稍作修改即可。

答案 3 :(得分:1)

对于非加权图,BFS将完成这项工作。由于图表中存在潜在的循环,因此您需要跟踪被访问节点(无论如何,您需要为BFS执行此操作)。

对于加权图,可以使用bellman-Ford算法。它还能够检测周期。