Algorithm 为什么Dijkstra算法会松弛最短路径树中已存在顶点的相邻边?
在第24章第658页CLRS第三版的DIJKSTRA伪代码中,在内部循环中,当从新添加的顶点放松相邻边时,为什么允许放松已从队列中去除并添加到树的最短路径的边Algorithm 为什么Dijkstra算法会松弛最短路径树中已存在顶点的相邻边?,algorithm,clrs,Algorithm,Clrs,在第24章第658页CLRS第三版的DIJKSTRA伪代码中,在内部循环中,当从新添加的顶点放松相邻边时,为什么允许放松已从队列中去除并添加到树的最短路径的边 while(Q not empty){ u = extractMin from Q; Add S to the shortest path tree; for each vertex v adjacent to u relax(u,v,w) } 为什么内部循环不检查顶点是否已经是最短路径树的一部分 while(Q not e
while(Q not empty){
u = extractMin from Q;
Add S to the shortest path tree;
for each vertex v adjacent to u
relax(u,v,w)
}
为什么内部循环不检查顶点是否已经是最短路径树的一部分
while(Q not empty){
u = extractMin from Q;
Add S to the shortest path tree;
for each vertex v adjacent to u
if v is in Q
then relax(u,v,w)
}
哪种方法是正确的?放松的第一件事是检查
if v.d > u.d + w(u,v)
如果v
已在最短路径树上,则检查将始终失败,relax
将不会继续。如果v在Q中,检查将是多余的
然而,在算法的具体实现中,ifif v in Q
比if v.d>u.d+w(u,v)
的运算速度要快得多,包括它可能是一个有用的优化。relax做的第一件事就是检查
if v.d > u.d + w(u,v)
如果v
已在最短路径树上,则检查将始终失败,relax
将不会继续。如果v在Q中,检查将是多余的
然而,在算法的具体实现中,ifif v in Q
比if v.d>u.d+w(u,v)
的运算速度要快得多,包括它可能是一种有用的优化。这两种方法在功能上都是正确的。但是,您的版本不如CLRS版本优化。
如果v在Q中,您不想执行,因为这是一个O(logn)操作,而如果v.d>u.d+w(u,v)
是O(1)。在算法开始时,Q包含图中的所有顶点。因此,对于一个非常大的稀疏连接图,您的版本最终将比CLR糟糕得多
然而,你的问题并非完全没有道理。在CLRS中对Dijkstra算法的解释有点让人困惑,这正是我来到这个讨论主题的原因。查看第658页上的伪代码:
DIJKSTRA(G, w, s)
1 INITIALIZE-SINGLE-SOURCE(G, s)
2 S = 0
3 Q = G.V
4 while Q not empty
5 u = EXTRACT-MIN(Q)
6 add u to S
7 for each vertex v in G.Adj[u]
8 RELAX(u, v, w)
有人想知道维持S到底有什么意义?如果我们完全通过删除第2行和第6行来删除它,那么算法仍然有效,完成后,您可以按照前面的指针(已存储在每个顶点中)向后通过图形打印最短路径(使用第601页的print-path(G,s,v)
,如第647页所述)。在这里,S似乎更多地被用作一种解释工具,以说明Dijkstra是一种贪婪算法,但在实际的图形实现中,在我看来,似乎不需要它。这两种方法在功能上都是正确的。但是,您的版本不如CLRS版本优化。
如果v在Q中,您不想执行,因为这是一个O(logn)操作,而如果v.d>u.d+w(u,v)
是O(1)。在算法开始时,Q包含图中的所有顶点。因此,对于一个非常大的稀疏连接图,您的版本最终将比CLR糟糕得多
然而,你的问题并非完全没有道理。在CLRS中对Dijkstra算法的解释有点让人困惑,这正是我来到这个讨论主题的原因。查看第658页上的伪代码:
DIJKSTRA(G, w, s)
1 INITIALIZE-SINGLE-SOURCE(G, s)
2 S = 0
3 Q = G.V
4 while Q not empty
5 u = EXTRACT-MIN(Q)
6 add u to S
7 for each vertex v in G.Adj[u]
8 RELAX(u, v, w)
有人想知道维持S到底有什么意义?如果我们完全通过删除第2行和第6行来删除它,那么算法仍然有效,完成后,您可以按照前面的指针(已存储在每个顶点中)向后通过图形打印最短路径(使用第601页的print-path(G,s,v)
,如第647页所述)。在这里,S似乎更多地被用作一种解释工具,以说明Dijkstra是一种贪婪算法,但在实际的图形实现中,在我看来,似乎不需要它