使用Dijkstra找到最小生成树?

时间:2009-12-15 18:08:48

标签: algorithm language-agnostic graph-theory dijkstra minimum-spanning-tree

Dijkstra's通常用于查找图中两个节点之间的最短距离。可以用来找到最小spanning tree吗?如果是这样,怎么样?

编辑:这不是家庭作业,但我想了解一个关于旧练习考试的问题。

5 个答案:

答案 0 :(得分:22)

答案是否定的。为了解原因,让我们首先阐明这样的问题:

问:对于只有非负边权重的连通,无向,加权图G = (V, E, w),Dijkstra算法生成的前任子图是否形成G的最小生成树<?h3>

(请注意,无向图是一类特殊的有向图,因此在无向图上使用Dijkstra算法是完全可以的。此外,MST仅针对连通的无向图定义,如果图不加权则很简单,所以我们必须限制我们对这些图表的查询。)

A: Dijkstra的算法在每一步都贪婪地选择最接近某个源顶点s 的下一条边。它执行此操作,直到s连接到图中的每个其他顶点。显然,生成的前任子图是G的生成树,但最小化边缘权重的总和?

已知产生最小生成树的

Prim算法与Dijkstra算法非常相似,但在每个阶段它贪婪地选择最接近任何顶点的下一个边缘在该阶段的工作MST中。让我们用这个观察来产生一个反例。

反例:考虑无向图G = (V, E, w)其中

V = { a, b, c, d }

E = { (a,b), (a,c), (a,d), (b,d), (c,d) }

w = { ( (a,b) , 5 ) ( (a,c) , 5 ) ( (a,d) , 5 ) ( (b,d) , 1 ) ( (c,d) , 1 ) }

a作为源顶点。

Picture of the Graph G

Dijkstra的算法需要边{ (a,b), (a,c), (a,d) } 因此,此生成树的总重量 5 + 5 + 5 = 15

Prim的算法需要边{ (a,d), (b,d), (c,d) } 因此,此生成树的总重量 5 + 1 + 1 = 7

答案 1 :(得分:17)

严格来说,答案是否定的。 Dijkstra算法在图上找到2个顶点之间的最短路径。然而,算法的一个非常小的变化产生了另一种有效产生MST的算法。

The Algorithm Design Manual是我发现的最好的书,可以回答像这样的问题。

答案 2 :(得分:3)

Prim's algorithm使用与Dijkstra算法相同的基本原理。

答案 3 :(得分:1)

我会继续使用像Prim或Kruskal这样的贪婪算法。我担心Djikstra不会做,只是因为它最小化了节点对之间的成本,而不是整个树。

答案 4 :(得分:0)

当然,可以使用Dijkstra作为最小生成树:

dijsktra(s):
dist[s] = 0;
while (some vertices are unmarked) {
    v = unmarked vertex with 
    smallest dist;
    Mark v; // v leaves “table”
    for (each w adj to v) {
        dist[w] = min[ dist[w], dist[v] + c(v,w) ];
    }
}

以下是使用Dijkstra进行生成树的示例:

Example of using Dijkstra for spanning tree

您可以在“算法基础”一书中找到更多解释,第4章第2节。

希望这个帮助