今天学习了Prim算法和Kruskal算法,因为书中只给出了算法的实现,而没有给出关于算法正确性的证明,所以尝试着给出了自己的证明。刚才看了一下《算法》一书中的相关章节,使用了切分定理来证明这两个算法的正确性,更加简洁、优雅并且根本。相比之下,我的证明带着许多草莽气息,于此写成博客,只当是记录自己的思考
 
-------------------------------------------
 
说明:
本文仅提供关于两个算法的正确性的证明,不涉及对算法的过程描述和实现细节
本人算法菜鸟一枚,提供的证明仅是自己的思路,不保证正确,仅供参考,若有错误,欢迎拍砖指正
关于使用切分定理来证明两个算法的正确性,请参考《算法》一书中的相关章节
 
-------------------------------------------
Prim算法和Kruskal算法用来求解无向连通图中的最小生成树,相关概念这里不作介绍
 
Prim算法的思路是,从任意一个顶点开始,把这个顶点作为最初的最小生成树的子树,通过逐步地为当前的子树添加新边来生成最终的最小生成树,添加的策略是,每次只添加从外部连接到该子树的所有边中的最短边
 
这种算法之所以可行,是基于这样一个判断:对于任意一个顶点vi,连接到该顶点的所有边中的一条最短边(vi, vj)必然属于最小生成树(该判断也可以扩展成:任意一个属于最小生成树的连通子图(子树),从外部连接到该连通子图的所有边中的一条最短边必然属于最小生成树
 
下面证明如上的判断:
假设最小生成树已经建成;(vi, vj)是连接到顶点vi的最短边,在最小生成树中取出vi,断开连接到vi的边,则生成树被拆分成
1、顶点vi
2、顶点vj所在的连通分量(单独一个顶点也看作一个独立的连通分量)
3、其余若干个连通分量(个数大于等于0)
三个部分
 
现在要重建生成树,就要重新连接之前被断开的各边
虽然不知道之前被断开的都是哪几条边,但是可以通过这样一个简单的策略来重建连接:将vi分别以最小的成本逐个连接到这若干个互相分离的连通分量;具体来说,就是要分别遍历顶点vi到某个连通分量中的所有顶点的连接,然后选择其中最短的边来连接vi和该连通分量;而要将vi连接到vj所在的连通分量,显然通过边(vi, vj)连接的成本最低,所以边(vi, vj)必然属于最小生成树(如果连接到vi的最短边不止一条,只要任意挑选其中的一条(vi, vj)即可,以上的证明对于这种情况同样适用)
 
这样我们就为原来只有一个顶点vi的子树添加了一个新的顶点vj及新边(vi, vj);接下来只要将这棵新子树作为一个连通子图,并且用这个连通子图替换顶点vi重复以上的分析,迭代地为子树逐个地添加新顶点和新边即可
 
--------------------------------------------- 
 
Kruskal算法通过从小到大遍历边集,每次尝试为最小生成树加入当前最短的边,加入成功的条件是该边不会在当前已构建的图中造成回路,当加入的边的数目达到n-1,遍历结束
 
Kruskal算法每次为当前的图添加一条不会造成回路的新边,其本质是逐步地连接当前彼此分散的各个连通分量(单个顶点也算作一个连通分量),而连接的策略是每次只用最小的成本连接任意两个连通分量。这个策略之所以能够实现,是因为每加入一条边之后只会出现两种结果:
1、在已有的连通分量中形成回路
2、连接两个彼此独立的连通分量
所以,通过从小到大遍历边集,判断是否会造成回路,然后逐条添加新边就可以实现上诉的连接策略
 
接下来需要证明的是,为什么每次用最小成本连接两个连通分量,最后就可以生成一棵最小生成树(毕竟每一个当前的最优解之和未必是全局的最优解)
 
借用在Prim算法中提到的那个判断就可以很方便地证明:“如果某个连通图属于最小生成树,那么所有从外部连接到该连通图的边中的一条最短的边必然属于最小生成树”
通过这个判断,可以很容易地证明:当最小生成树被拆分成彼此独立的若干个连通分量的时候,所有能够连接任意两个连通分量的边中的一条最短边必然属于最小生成树(因为该边必然是这两个连通分量的可以连接到外部的最短边)
 
由此也就证明了,Kruskal算法通过每次以最小的成本来连接两个连通分量的策略确实可以正确地生成最小生成树
 

Prim算法和Kruskal算法的正确性证明的更多相关文章

  1. 转载:最小生成树-Prim算法和Kruskal算法

    本文摘自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html 最小生成树-Prim算法和Kruskal算法 Prim算 ...

  2. 最小生成树之Prim算法和Kruskal算法

    最小生成树算法 一个连通图可能有多棵生成树,而最小生成树是一副连通加权无向图中一颗权值最小的生成树,它可以根据Prim算法和Kruskal算法得出,这两个算法分别从点和边的角度来解决. Prim算法 ...

  3. java实现最小生成树的prim算法和kruskal算法

    在边赋权图中,权值总和最小的生成树称为最小生成树.构造最小生成树有两种算法,分别是prim算法和kruskal算法.在边赋权图中,如下图所示: 在上述赋权图中,可以看到图的顶点编号和顶点之间邻接边的权 ...

  4. 最小生成树——Prim算法和Kruskal算法

    洛谷P3366 最小生成树板子题 这篇博客介绍两个算法:Prim算法和Kruskal算法,两个算法各有优劣 一般来说当图比较稀疏的时候,Kruskal算法比较快 而当图很密集,Prim算法就大显身手了 ...

  5. 最小生成树Prim算法和Kruskal算法

    Prim算法(使用visited数组实现) Prim算法求最小生成树的时候和边数无关,和顶点树有关,所以适合求解稠密网的最小生成树. Prim算法的步骤包括: 1. 将一个图分为两部分,一部分归为点集 ...

  6. Prim算法和Kruskal算法

       Prim算法和Kruskal算法都能从连通图找出最小生成树.区别在于Prim算法是以某个顶点出发挨个找,而Kruskal是先排序边,每次选出最短距离的边再找. 一.Prim(普里姆算法)算法: ...

  7. 【数据结构】最小生成树之prim算法和kruskal算法

    在日常生活中解决问题经常需要考虑最优的问题,而最小生成树就是其中的一种.看了很多博客,先总结如下,只需要您20分钟的时间,就能完全理解. 比如:有四个村庄要修四条路,让村子能两两联系起来,这时就有最优 ...

  8. 最小生成树---Prim算法和Kruskal算法

    Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (gra ...

  9. prim 算法和 kruskal算法

    Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (gra ...

随机推荐

  1. CDH的ntp时间同步

    云服务器: ntpq -p ntpdate -u 10.52.255.1  #手动同步 自建NTP服务器: https://www.cnblogs.com/yinzhengjie/p/9480665. ...

  2. SSM笔记

    Spring Spring就像是整个项目中装配bean的大工厂,在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象.也可以称之为项目中的粘合剂. Spring的核心思想是IoC(控制 ...

  3. 初步学习jquery学习笔记(一)

    什么是jquery? Jquery是javascript的一个函数库包含以下功能: html元素选取 html元素的操作 css操作 html事件的函数 javacript的特效 html的遍历和修改 ...

  4. [CF750G] New Year and Binary Tree Paths

    目录 简单的 组合的 题目链接 简单的 设从节点\(x\)开始不断往左儿子走h-1步,则编号和为\(x\sum_{i=0}^{h-1}2^i=x(2^h-1)\). 若倒数第\(i\)步走向的是右儿子 ...

  5. selenium与页面交互之一:webdriver浏览器的属性

    selenium提供了许多API方法与页面进行交互,如点击.键盘输入.打开关闭网页.输入文字等. webdriver对浏览器提供了很多属性来对浏览器进行操作,常用的如图: get(url).quit( ...

  6. ELK的搭建以及使用

    一.架构如图: 二.工作机制: 在需要收集日志的应用上安装filebeat(需要修改配置文件,配置文件稍后介绍),启动filebeat后,会收集该应用的日志推送给redis,然后logstash从re ...

  7. luoguP4578_ [FJOI2018]所罗门王的宝藏

    题意 一个n*m的矩阵,初始值全为0,每一行每一列操作一次可以加1或者减1,问能否操作得到给定矩阵. 分析 行和列的分别的加减是可以相互抵消的,因此我们只需要考虑行的加和列的减. 对于给定矩阵每一个数 ...

  8. homebrew学习(三)之homebrew命令

    安装homebrew: /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/m ...

  9. eclipse控制台输出太多被顶掉问题

    控制台空白处右键 属性

  10. ORA-01846: 周中的日无效

    参考这篇博客:https://blog.csdn.net/yabingshi_tech/article/details/8678218