Prim算法正确性证明
3036
2022.09.19
2022.09.28
发布于 未知归属地

更多「图论」相关证明文章见如下帖子:
图论相关证明文章列表


【目录】

  1. 算法描述

  2. 算法过程

      1. 正确性证明

算法描述

Prim (普里姆算法): 一种基于贪心思想的求解无向图上 MST 的算法。我们直接将 Prim 算法和 Dijkstra 二者对比如下。

DijkstraPrim
贪心算法贪心算法
顶点分为 距离已确定距离未确定 顶点顶点分为 距离已确定 (已加入生成树)距离未确定 (未加入生成树) 顶点
所有顶点距离初始化为 所有顶点距离初始化为
源点 的距离初始化为 0生成树起始点 的距离初始化为 0
以一个循环寻找 当前距离未确定顶点中距离最小者
立即置 的距离为「已确定」。
以一个循环寻找 当前距离未确定顶点中距离最小者
立即置 的距离为「已确定」。
尝试以如下方式更新 (松弛) 的邻接顶点的距离
尝试以如下方式更新 的邻接顶点的距离
结束时所有顶点最短路径及其距离被求出 结束时 MST 及其所有边权被求出

我们看到这两个算法的每一步都几乎相同,不同点主要有三处,最主要的是第 3 点。

  1. Prim 用于在「无向图」中求 MST,因此建图时要「双向建边」。Dijkstra 应用于有向图时单向建边,应用于无向图时双向建边。
  2. Dijkstra 中的「距离」指的是顶点到源点的距离。Prim 中的「距离」指的是顶点到其已在生成树上的邻接顶点 (父顶点) 的距离。
  3. 顶点距离更新方式不同

算法过程

  1. 建图及初始化。

    1. 构建双向带权图。
    2. 设置一个大小为 的用于标记顶点距离是否「已确定」的 数组 ,下标表示顶点。
    3. 设置一个大小为 的距离数组 ,下标表示顶点。初始化所有顶点的距离为 ,表示所有顶点的距离尚未确定。
    4. 任意选取 一个顶点作为起始顶点,置距离为 0,通常我们将第一个顶点的距离置为 0 。
  2. 以一个循环寻找 当前距离未确定顶点中距离最小者 ,立即置 的距离为「已确定」。

  3. 距离更新。尝试更新 的所有 距离未确定的 邻接顶点 的距离 。即

  4. 循环结束时,所有顶点距离被求出,也就是 MST 所有边权被求出。


正确性证明

如下证明参考了 参考1 以及 参考2

虽然 Prim 算法过程与 Dijkstra 类似,但证明过程并不通用。如下是 Prim 算法的证明过程。

证明:在图 上执行 Prim 算法得到的生成树 是 MST。

  1. 上的 MST (之一) 是生成树 ,即证明 ,绝对值表示生成树的边权和。
  2. 生长过程中,首次 遇到的不属于 的边为 在此前得到的点集中, 在剩余的顶点中。从 中拿走 ,则 剩下的不连通的两部分分别为包含 的子树 以及包含 的子树
  3. 是 MST,其上必存在 的路径,且已知 中, 中,由于 ,则必然存在边 穿过 ,即 中, 中 (若 ,则 不是 ;若 ,则 不是 ) 。
  4. 即将被加入 时,顶点 已在 中 ( 当前生长到的部分)。
    1. 此时 是「距离未确定」的顶点。因为如果 是距离已确定的顶点,则在 中存在一条边 连接 和另一顶点,我们已经知道 生长过程中 首次 遇到的不属于 的边,也就是说 ,这与 矛盾,因为 一旦「距离确定」,后续就不会考察 的连边, 也就不可能加入
    2. 由于 是「距离未确定」的顶点,考察顶点 的连边时,顶点 的连边也一定会被考察。由于 在此轮考察中被 Prim 算法选入 中,而 未被选择,可知
  5. 对于 ,断开 ,则 被分成不连通的两棵子树 ,且 被断开,说明 分别在不连通的两棵子树 上。此时连上 得到的 显然是一棵生成树。因为 ,则必然有 , 否则 边权之和更小,与 是 MST 矛盾。因此 ,即 也是 MST。
  6. 重复上述过程,继续考察 中下一条不属于 的边,直到得到 。每一次考察,都可以得到上述 5 的结论,最终有 ,即 是 MST。

image.png


评论 (5)