写在前面
借着对生成树技术的好奇,不知是多少次再次翻开算法导论这本书,探寻下最小生成树理论和生成树技术之间的蛛丝马迹,可惜的是没有什么联系。但是再看过英文版的算法导论之后发现生成树理论并不像中文版中的那么晦涩难懂。还是那句话:算法导论是一本功力十足的书,但是中文版翻译出几成功力真的不好说。算法导论中对于最小生成树的讨论有着相当的深度,对于最小生成树算法的理解很有帮助。这篇文章本着翻译原作章节的目的,讨论最小生成树的原理,下面一篇文章将讨论最小生成树的实现。
问题的本质
在一个有
n
个顶点的连通图中,找到
通用算法
计算一个无向连通图的最小生成树的常用算法是Prim算法和Kruskal算法,其本质都是贪心算法。在当前情况下选择局部最优解,重复迭代相同的操作,可以最终达到最优解。这种贪心算法的本质是一种通用算法:每次增加一条边。算法维护了一个边集的子集
A
,
最初情况下,A是一个空集,属于一颗最小生成树的性质是满足的 。通用算法不断迭代向子集A增加安全边的过程。由于最小生成树一定包含n-1条边,迭代的次数是确定值:
定理24.1 (安全边判别定理)
G=(V,E)
是无向连通图,在边集
E
上定义了实函数
定理24.1给出了判断子集A的安全边,或者说安全元素的方法,因此叫做安全边判定定理更加直观。定理中为了判断安全边,引入了很多新的概念:割、不妨害、轻边。
先解释定理中引入的新概念,然后证明定理24.1。
割
割的本质是对顶点的划分,割将全部顶点划分为两个部分。割的表达为
跨越割的边
如果边集E中的一条边(u,v),u属于S,v属于V-S,则边(u,v)跨越了割 (S,V−S) 。
不妨害边子集A的割
边集E的子集A中没有边跨越割 (S,V−S) 则成为这个割不妨害边子集 A 。
割的轻边
给出一个割
定理24.1的证明
假设
T
是包含边子集
由于边(u,v)不在最小生成树T上,候选边(u,v)加上最小生成树T构成了一个环路,因为T中已存在一条路径连通顶点u和v。由于u,v分别在割(S,V-S)的两侧,那么T中存在一条边跨过割(S,V-S),这条边为(x,y)。(x,y)并不在边子集A中,因为割(S,V-S)不妨害A。由于生成树T中任意两个点之间的路径唯一,T去掉边(x,y)会把T分成两部分,每个部分都为连通体。增加边(u,v)又形成一棵新的树
T′
。
证明
T′
仍是一棵最小生成树:因为(u,v)是割的轻边,是局部最小值。并且边(x,y)也通过割,那么有
w(u,v)≥w(x,y)
,则:
由于T是最小生成树,有 w(T)≤w(T′) ,所以T‘仍是最小生成树。
随着算法的迭代,子集A是无环的。子集A出现环路意味着最小生成树出现环路,是不可能的。在算法执行的中间过程中,图GA是一个森林,其中每一个连通体都是一棵树。
定理的本质
割不妨害边子集A的情况下,割轻边是子集A的安全边。
逆定理
逆定理为:边子集A的安全边是不妨害A的割的轻边。逆定理并不成立。逆定理的反例:边子集A的安全边在一棵最小生成树上,但是不一定是不妨害A的的割的轻边。这样的反例为割通过了最小生成树的两条边,将最小生成树分成了3个部分。此时对于A的安全边有2条,可能存在权值不同的情况,这时其中一条安全边就不是割的轻边。因此,边子集A的安全边不一定是不妨害A的割的轻边。
推论24.2
连接两个连通体的轻边对于子集A是安全边。
有意义的结论
图G中权最小的边属于某一棵最小生成树。
最小生成树中的边是某个割的轻边。