Djikstra的算法:我是否遍历邻居或孩子?

时间:2016-10-06 15:03:56

标签: algorithm data-structures tree

我正在维基百科的伪代码中查看Djikstra的算法

 1  function Dijkstra(Graph, source):
 2
 3      create vertex set Q
 4
 5      for each vertex v in Graph:             // Initialization
 6          dist[v] ← INFINITY                  // Unknown distance from source to v
 7          prev[v] ← UNDEFINED                 // Previous node in optimal path from source
 8          add v to Q                          // All nodes initially in Q (unvisited nodes)
 9
10      dist[source] ← 0                        // Distance from source to source
11      
12      while Q is not empty:
13          u ← vertex in Q with min dist[u]    // Source node will be selected first
14          remove u from Q 
15          
16          for each neighbor v of u:           // where v is still in Q.
17              alt ← dist[u] + length(u, v)
18              if alt < dist[v]:               // A shorter path to v has been found
19                  dist[v] ← alt 
20                  prev[v] ← u 
21
22      return dist[], prev[]

https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm

让我感到困惑的是16行。它说for each neighbor但不应该是for each child(即for each neighbor where neighbor != parent)。否则,我没有看到在行20中设置父项的重点。

2 个答案:

答案 0 :(得分:1)

上一个节点在第20行设置:

prev[v] ← u

只有在执行第14行时才会发生这种情况:

remove u from Q 

因此,对于任何vprev[v]都不能在Q中 - 它之前被删除了,它永远不会返回Q(从12开始的循环内) ,项目不再添加到Q)。这与任何u的说法相同,prev[u]不能在Q中 - 除了更改变量的名称之外,它说同样的事情。

关于第16行的问题:

  

它说for each neighbor

但是,如果你看一下伪代码,它实际上是说

 for each neighbor v of u:           // where v is still in Q.

因此,prev[u]不会被迭代 - 它不在Q

对于它的价值,我认为伪代码有点草率和混乱// where v is still in Q不应该是评论。它没有澄清或解释代码的其余部分 - 它改变了意义,应该代码的一部分。也许那让你感到困惑。

答案 1 :(得分:1)

最终,Dijkstra的算法计算称为shortest-path tree的东西,这是一种植根于某个起始节点的树结构,其中树中的路径给出了图中每个节点的最短路径。您所看到的设置每个节点的父节点的逻辑是Dijkstra算法的一部分,该算法一次构建一个节点。

虽然Dijkstra的算法构建最短路径树,但它并没有遍历它。相反,它通过以特定顺序处理原始路径的节点,不断更新与处理的节点相邻的节点的候选距离来工作。这意味着在伪代码中,“循环遍历所有相邻节点”的逻辑是正确的,因为它意味着“在原始图形中循环所有相邻节点。”“它不起作用迭代生成的最短路径树中的所有子节点 ,因为该算法中的那个树尚未完全组装。