我正在维基百科的伪代码中查看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
中设置父项的重点。
答案 0 :(得分:1)
上一个节点在第20行设置:
prev[v] ← u
只有在执行第14行时才会发生这种情况:
remove u from Q
因此,对于任何v
,prev[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的算法构建最短路径树,但它并没有遍历它。相反,它通过以特定顺序处理原始路径的节点,不断更新与处理的节点相邻的节点的候选距离来工作。这意味着在伪代码中,“循环遍历所有相邻节点”的逻辑是正确的,因为它意味着“在原始图形中循环所有相邻节点。”“它不起作用迭代生成的最短路径树中的所有子节点 ,因为该算法中的那个树尚未完全组装。