使用 Dijkstra 找到最小生成树?

发布于 2024-08-15 07:55:19 字数 261 浏览 3 评论 0原文

Dijkstra 通常用于查找图中两个节点之间的最短距离。它可以用来查找最小生成树吗?如果是这样,怎么办?

编辑:这不是作业,但我试图理解旧练习考试中的一个问题。

Dijkstra's is typically used to find the shortest distance between two nodes in a graph. Can it be used to find a minimum spanning tree? If so, how?

Edit: This isn't homework, but I am trying to understand a question on an old practice exam.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

深海少女心 2024-08-22 07:55:19

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

问:对于仅具有非负边权重的连通、无向、带权图 G = (V, E, w),前驱子图是否由Dijkstra算法形成G的最小生成树?

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

答:Dijkstra 算法在每一步都会贪婪地选择最接近某个源顶点的下一条边。它会执行此操作,直到 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为源顶点。

图 G 的图片

Dijkstra 算法取边 { (a,b), (a,c), ( a,d) }.
因此,这棵生成树的总权重为5 + 5 + 5 = 15

Prim 算法采用边{ (a,d), (b,d), (c,d) }
因此,这棵生成树的总权重为5 + 1 + 1 = 7

The answer is no. To see why, let's first articulate the question like so:

Q: For a connected, undirected, weighted graph G = (V, E, w) with only nonnegative edge weights, does the predecessor subgraph produced by Dijkstra's Algorithm form a minimum spanning tree of G?

(Note that undirected graphs are a special class of directed graphs, so it is perfectly ok to use Dijkstra's Algorithm on undirected graphs. Furthermore, MST's are defined only for connected, undirected graphs, and are trivial if the graph is not weighted, so we must restrict our inquiry to these graphs.)

A: Dijkstra's Algorithm at every step greedily selects the next edge that is closest to some source vertex s. It does this until s is connected to every other vertex in the graph. Clearly, the predecessor subgraph that is produced is a spanning tree of G, but is the sum of edge weights minimized?

Prim's Algorithm, which is known to produce a minimum spanning tree, is highly similar to Dijkstra's Algorithm, but at each stage it greedily selects the next edge that is closest to any vertex currently in the working MST at that stage. Let's use this observation to produce a counterexample.

Counterexample: Consider the undirected graph G = (V, E, w) where

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 )
}

Take a as the source vertex.

Picture of the Graph G

Dijkstra's Algorithm takes edges { (a,b), (a,c), (a,d) }.
Thus, the total weight of this spanning tree is 5 + 5 + 5 = 15.

Prim's Algorithm takes edges { (a,d), (b,d), (c,d) }.
Thus, the total weight of this spanning tree is 5 + 1 + 1 = 7.

不交电费瞎发啥光 2024-08-22 07:55:19

严格来说,答案是否定的。 Dijkstra 算法找到图上 2 个顶点之间的最短路径。然而,对算法进行很小的改变就会产生另一种能够有效生成 MST 的算法。

算法设计手册是我发现回答此类问题的最好的书一。

Strictly, the answer is no. Dijkstra's algorithm finds the shortest path between 2 vertices on a graph. However, a very small change to the algorithm produces another algorithm which does efficiently produce an MST.

The Algorithm Design Manual is the best book I've found to answer questions like this one.

尘世孤行 2024-08-22 07:55:19

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

Prim's algorithm uses the same underlying principle as Dijkstra's algorithm.

雪若未夕 2024-08-22 07:55:19

我会坚持使用 Prim 或 Kruskal 等贪婪算法。我担心 Djikstra 不会这样做,只是因为它最大限度地减少了节点对之间的成本,而不是整个树的成本。

I'd keep to a greedy algorithm such as Prim's or Kruskal's. I fear Djikstra's won't do, simply because it minimizes the cost between pairs of nodes, not for the whole tree.

回忆那么伤 2024-08-22 07:55:19

当然,可以使用 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对于生成树

您可以在《算法基础》一书第 4 章第 2 节中找到进一步的解释。

希望这会有所帮助

Of course, It's possible to use Dijkstra for minimum spanning tree:

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) ];
    }
}

Here is an example of using Dijkstra for spanning tree:

Example of using Dijkstra for spanning tree

You can find further explanation in Foundations of Algorithms book, chapter 4, section 2.

Hope this help

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文