【发布时间】:2018-12-03 22:37:19
【问题描述】:
我似乎有点难以理解贪婪策略的工作原理以及 Dijkstra 算法如何跟踪最短路径。作为参考,这里是 Dijkstra 算法的伪代码
DijkstrasAlgorithm(G, w, s)
InitalizeSingleSource(G, s)
S = 0
Q = G.V
while Q != 0
u = ExtractMin(Q)
S = S∪{u}
for each vertex v ∈ G.Adj[u]
Relax(u, v, w)
请考虑以下重量方向图。
有5个顶点:s、t、x、y、z 有 10 条边:
s->t = 3
s->y = 5
t->y = 2
t->x = 6
y->t = 1
y->x = 4
y->z = 6
x->z = 2
z->x = 7
z->s = 3
我们的目标是找到从 s 到 x 的最短路径。我的答案是长度为 9 的 s->t->y->x,我假设伪代码中的“S”是最短路径,并且将 minQ 中的每个 ExtractMin 添加到路径中。
然而,我的老师告诉我这是错误的。正确答案是 s->t->x,长度为 9。我们答案的不同在于是否包含 y。我的老师说既然s->t->x是“先找到”的,就不更新为s->t->y->x,就是等长了。
这让我很困惑。 Dijkstra 算法使用贪心策略,我认为贪心策略总是选择当时可用的最短路径。而当在 t->y 和 t->x 之间选择时,t->y 更短,因此应该选择。
我的问题是:
1) 贪心策略在什么情况下不会为最终结果选择最直接的最短路径?
2) 如果在 minQ 上使用 ExtractMin 不是我们跟踪从 s 到 x 的整体路径的方式,那么我们如何跟踪完整路径?
【问题讨论】:
-
我不同意 Dijkstra 算法是一种贪心算法。该算法最重要的特征是
Relax函数,它甚至没有显示出来。从s开始,算法发现在3中可以到达t,在5中到达y。从t开始,算法发现在5中可以到达y(但是忽略了,因为我们可以已经在 5) 中到达y,在 9 中到达x。从y开始,您也可以在 9 中到达x,但这被忽略了。所以你老师是对的,路径是stx。 -
那么你如何跟踪路径呢?
-
我将有一个与每个顶点关联的
from成员变量。t.from = s、y.from = s、x.from = t。算法完成后,从目的地向后工作。Relax函数需要在缩短距离的任何时候更新from。 -
那么“如果(变量 = 目标)则返回源”?另外,伪代码中的 S 应该是什么?我认为这就是跟踪路径的原因。
-
看来
S是访问过的顶点集合。不确定它有什么用途,因为算法从不使用它,并且当算法完成时,它包含所有可到达的顶点。