因为我看到Dijkstra和Prim的算法是相同的。这是来自维基百科的伪代码,我将解释我的困惑。
1 function Dijkstra(Graph, source):
2 dist[source] ← 0 // Initialization
3
4 create vertex set Q
5
6 for each vertex v in Graph:
7 if v ≠ source
8 dist[v] ← INFINITY // Unknown distance from source to v
9 prev[v] ← UNDEFINED // Predecessor of v
10
11 Q.add_with_priority(v, dist[v])
12
13
14 while Q is not empty: // The main loop
15 u ← Q.extract_min() // Remove and return best vertex
16 for each neighbor v of u: // only v that is still in Q
17 alt ← dist[u] + length(u, v)
18 if alt < dist[v]
19 dist[v] ← alt
20 prev[v] ← u
21 Q.decrease_priority(v, alt)
22
23 return dist[], prev[]
Prim的算法几乎相同,为方便起见,我只是改变从第14行开始的循环
14 while Q is not empty:
15 u ← Q.extract_min()
16 for each neighbor v of u:
17 if v ∈ Q and length(u, v) < cost[v]
18 cost[v] ← length(u, v)
19 prev[v] ← u
20 Q.decrease_priority(v, length(u, v))
有两个更改,第一个是用dist[]
替换cost[]
,据我所知,这与算法解决不同问题的事实有关。
第二个对我来说是模糊的,即在Dijkstra算法中没有if v ∈ Q
这个条件。我真的不知道为什么我们可以返回到Prim算法中的访问顶点集,这不能在Dijkstra算法中发生。
答案 0 :(得分:2)
在Dijkstra,如果alt ← dist[u] + length(u, v)
小于dist[v]
的当前值,我们会计算alt
并将alt
设置为dist[v]
。如果我们通过alt
,v
表示从起始节点到u
的距离。但是,u
是刚刚从Q
中取出的节点,因此,它与起始节点的距离大于或等于先前从{{1 }}。因为Dijkstra要求所有边权重都是非负的,所以如果Q
不在alt
中,则dist[v]
保证大于或等于v
,因为它是Q
的总和{1}}和dist[u]
,因此它不会传递length(u, v)
中的条件。换句话说,如果if
不在v
,Q
将相对于我们已经拥有u
的路径而绕道而行。
答案 1 :(得分:1)
不确定我的想法是否正确。对于Dijkstra和prims算法,我们只应该处理Q中的顶点。 对于Dijkstra算法,伪代码可能无法明确检查当前顶点是否仍在Q中,但它被评为“只有v仍然在Q中”
for each neighbor v of u: // only v that is still in Q
我认为它们与x∈Q
的含义相同17 if x ∈ Q and length(u, v) < cost[v]
如果这里的x代表第16行中的“v”。
答案 2 :(得分:0)
Dijkstra和Prim算法非常相似。
区别在于:
Prim的算法:通过无向边缘到最小生成树的最近顶点
Dijsktra算法:通过有向路径到源的最近顶点
来源:Sedgewick的算法&amp;韦恩