📌  相关文章
📜  为什么 Prim 和 Kruskal 的 MST 算法对有向图失败?(1)

📅  最后修改于: 2023-12-03 15:06:16.448000             🧑  作者: Mango

为什么 Prim 和 Kruskal 的 MST 算法对有向图失败?

在无向图中,Prim 和 Kruskal 算法都是有效的最小生成树(MST)算法。然而,对于有向图而言,这两种算法会失败,也就是无法正确地计算出最小生成树。

MST 算法概述

在深入探讨为什么 Prim 和 Kruskal 算法在有向图中失败之前,我们需要回顾一下这两种算法是如何在无向图中工作的。一般而言,MST 算法的目标是找到一个包含图中所有顶点的最小连通子图。显然,对于无向图而言,这个最小子图就是一棵树,且树中的每条边都有一个唯一的起点和终点。Prim 和 Kruskal 算法都是贪心算法,它们通过不断选择图中权重最小的边来构建最小生成树。

Prim 算法的基本步骤:

  1. 选择一个起始节点并将其放入最小堆中;
  2. 从堆中取出权重最小的节点;
  3. 将该节点加入 MST 中;
  4. 遍历该节点的邻居节点,将它们加入最小堆中;
  5. 重复步骤 2 到 4,直到 MST 中包含所有节点。

Kruskal 算法的基本步骤:

  1. 将每个节点都作为一棵独立的树;
  2. 将所有边按照权重从小到大排序;
  3. 依次遍历每条边,如果两个节点不在同一棵树中,那么将它们合并并将该边加入 MST;
  4. 重复步骤 3,直到 MST 中包含所有节点。
为什么它们不能用于有向图?

对于有向图而言,Prim 和 Kruskal 算法都不是有效的 MST 算法。原因在于,无向图中的每条边都是双向的,可以在两个方向上遍历。但是,在有向图中,两个顶点之间可能存在多条不同的有向边,且这些有向边的方向不同。

看下面这个例子,其中有向边用箭头表示:

A -> B
A <- C
B -> C
B -> D
C -> D

如果我们使用 Prim 算法计算这个图的 MST,那么可能会出现一些不受欢迎的副作用。具体而言,Prim 算法遍历节点的顺序可能与我们期望的不同,导致算法计算出的 MST 不是我们想要的。同样的,Kruskal 算法也可能会选择包含有向环的边,从而无法构建一棵树。

因此,当我们需要在有向图中计算 MST 时,我们需要使用其他算法,例如 Edmonds 算法、Chu-Liu/Edmonds 算法等。

总结

Prim 和 Kruskal 算法是有效的 MST 算法,但是只能用于无向图。对于有向图而言,这两种算法可能会选择包含有向环的边,从而无法构建一棵树。因此,我们需要使用其他算法来计算有向图的 MST。