最小生成树

最小生成树的形成

假设已知一无向连通图G=(V,E),其加权函数为w:E→R,我们希望找到图G的最小生成树。后文所讨论的两种算法都运用了贪心方法,但在如何运用贪心法上却有所不同。

下列的算法GENERNIC-MIT正是采用了贪心策略,每步形成最小生成树的一条边。算法设置了集合A,该集合一直是某最小生成树的子集。在每步决定是否把边(u,v)添加到集合A中,其添加条件是A{(u,v)}仍然是最小生成树的子集。我们称这样的边为A的安全边,因为可以安全地把它添加到A中而不会破坏上述条件。

 GENERNIC-MIT(G,W)

1. A←?

2. while A没有形成一棵生成树

3    do  找出A的一条安全边(u,v);

4.       A←A{(u,v)};

5. return A

注意从第1行以后,A显然满足最小生成树子集的条件。第2-4行的循环中保持着这一条件,当第5行中返回集合A时,A就必然是一最小生成树。算法最棘手的部分自然是第3行的寻找安全边。必定存在一生成树,因为在执行第3行代码时,根据条件要求存在一生成树T,使AíT,且若存在边(u,v)?T(u,v)?A,则(uv)A的安全边。

在本节余下部分中,我们将提出一条确认安全边的规则(定理1),下一节我们将具体讨论运用这一规则寻找安全边的两个有效的算法。

首先我们来定义几个概念。有向图G=(V,E)的割(S,V-S)V的一个分划。当一条边(u,v)?E的一个端点属于S而另一端点属于V-S,则我们说边(u,v)通过割(S,V-S)。若集合A中没有边通过割,则我们说割不妨害边的集合A。如果某边是通过割的具有最小权值的边,则称该边为通过割的一条轻边。要注意在链路的情况下可能有多条轻边。从更一般意义来讲,如果一条边是满足某一性质的所有边中具有最小权值的边,我们就称该边为满足该性质的一条轻边。图2说明了这些概念。(a)集合S中的结点为黑色结点,V-S中的那些结点为白色结点。连接白色和黑色结点的那些边为通过该割的边。边(d,c)为通过该割的唯一一条轻边。子集A包含阴影覆盖的那些边,注意,由于A中没有边通过割,所以割(S,V-S)不妨害A(b)对于同一张图,我们把集合S中的结点放在图的左边,集合V-S中的结点放在图的有边。如果某条边使左边的顶点与右边的顶点相连则我们说该边通过割。

(a)

(b)

2 从两种途径来观察图1所示图的割(S,V-S)

确认安全边的规则由下列定理给出。

定理1

设图G(V,E)是一无向连通图,且在E上定义了相应的实数值加权函数w,设AE的一个子集且包含于G的某个最小生成树中,割(S,V-S)G的不妨害A的任意割且边(u,v)是穿过割(S,V-S)的一条轻边,则边(u,v)对集合A是安全的。

证明:

T是包含A的一棵最小生成树,并假定T不包含轻边(u,v),因为若包含就完成证明了。我们将运用剪贴技术”(cut-and-paste technique)建立另一棵包含A{(uv)}的最小生成树T,并进而证明(uv)A是一条安全边;

3 定理1的证明


3演示出了定理1的证明。S中的结点为黑色,V-S中的结点为白色,边(u,v)T中从uv的通路P中的边构成一回路。由于uv处于割(S,V-S)的相对的边上,因此在T中的通路P上至少存在一条边也通过割。设(x,y)为满足此条件的边。因为割不妨害A,所以边(x,y)不属于A。又因为(x,y)处于T中从uv的唯一通路上,所以去掉边(x,y)就会把T分成两个子图。这时加入边(u,v)以形成一新的生成树T=T-{(x,y)}{(u,v)}

下一步我们证明T是一棵最小生成树。因边(u,v)是通过割(S,V-S)的一条轻边且边(x,y)也通过割,所以有w(u,v)w(x,y),因此 w(T)=w(T)-w(x,y)+w(u,v)(T),但T是最小生成树,所以w(T)=w(T),因此T必定也是最小生成树。

现在还要证明(u,v)实际上是A的安全边。由于AíT(x,y)?A,所以有AíT,则A{(u,v)}íT。而T是最小生成树,因而(u,v)A是安全的。

定理1使我们可以更好地了解算法GENERNIC-MIT在连通图G=(V,E)上的执行流程。在算法执行过程中,集合A始终是无回路的,否则包含A的最小生成树包含一个环,这是不可能的。在算法执行中的任何一时刻,图GA=(V,A)是一森林且GA的每一连通支均为树。其中某些树可能只包含一个结点,例如在算法开始时,A为空集,森林中包含|V|棵树,每个顶点对应一棵。此外,对A安全的任何边(u,v)都连接GA中不同的连通支,这是由于A{(u,v)}必定不包含回路。

随着最小生成树的|V|-1条边相继被确定,GENERNIC-MIT中第2-4行的循环也随之要执行|V|-1次。初始状态下,A=?GA中有|V|棵树,每个迭代过程均将减少一棵树,当森林中只包含一棵树时,算法执行终止。

2节中论述的两种算法均使用了下列定理1的推论。

推论2

G=(V,E)是一无向连通图,且在E上定义了相应的实数值加权函数 w,设AE的子集且包含于G的某最小生成树中,C为森林GA=(V,A)中的连通支() 若边(u,v)是连接CGA中其他某连通支的一轻边,则边(u,v)对集合A是安全的。

证明:

因为割(C,V-C)不妨害A,因此(u,v)是该割的一条轻边。

 

.1 图的基本概念

5.2 图的存储结构

5.3 图的遍历

5.4 生成树和最小生成树

5.5 最短路径问题

5.6 拓扑排序

  

以图的观点来看,树也是图,只不过它是一个无向连通图。我们也可以把树称为树图

对无向连通图进行遍历,只需调用遍历算法一次便可得到图的各个顶点的访问序列,这个访问序列(路径)就是连通图的一棵生成树。很显然,一个无向连通图的生成树可能不是惟一的,我们一般称用深度优先搜索得到的为深度优先生成树,由广度优先搜索得到的为广度优先搜索得到的为广度优先生成树,对图5.9可以得到按深度优先遍历和按宽度优先遍历得到两棵如5.10所示的生成树。



 

 5.4.2 最小生成树

(理解最小生成树的概念,大致了解算法)

给定一个无向网络,在图的所有生成树中,使得各边权数和最小的那棵生成树称为图的最小生成树,也叫最小代价生成树

我们先来看一个例子

拿修筑公路网来说,什么样的图既能把所有的城镇连接起来,又使得长度最小呢?不难看出,答案只能从它的生成树之中去找,因为要做到任何两个城镇之间有公路可达,公路网必须是连通的,但对长度最小的要求可以知道公路网中显然不能有圈,如果有圈,去掉图上的一条边后,并不破坏连通性,但总长度显然减少了,这与总长度最小的假设是矛盾的

这个例子的实际意义显而易见,在连同所有城镇的条件,使建设公里数降到最小,从而降低了费用.

[提高] 最小生成树的算法 (增)

构造最小生成树的算法很多,其中多数算法是利用了最小生成树的下列性质: 设G=(V,E)是一个带权连通图,U是顶点集合V的一个非空子集.若u属于U,v属于V-U,且(u,v)是U中顶点到V-U中顶点之间权值最小得边,则必定存在一个包含边(u,v)的最小生成树.



 5.4.3求解图的最小生成树

(对一个无向网络求解它的最小生成树,通常有两种方法:一是kruskal法,二是prim法)

1.Kruskal算法

kruskal算法的基本思想是:

1)若网络G的边数e=n-1,则G即为所求的最小生成树,否则,一定有e>n-1。

2)将网络的e条边按权值自小到大顺序排列。

3)将网络G中的边都去掉,只留下n个孤立顶点作为初始的最小生成树T,再按边的排放顺序逐个考察,若与当前E(T)中的边不构成圈,便将它加入到边集E(T)中 ,直至E(T)中边数满(n-1)为止。

[要点]

Kruskal算法给出一种按权值的递增次序选择合适边来构造最小(代价)生成树的方法

 

例如图5.11所示的网络按Kruskal法得到的最小生成树如图5.12所示

 

同生成树一样,最小生成树也可能不是惟一的。

 



2.prim算法

prim算法是另一种求最小生成树的方法,它的基本思想是按权值局部最小逐次将顶点和边加入到T中,直至V(T)满n个顶点为止。

 

prim算法的步骤为:

1)设最小生成树T的V(T)和E(T)均为空。 (2)从顶点集V(G)中任取一顶点加到顶点集V(T)中。  (3)在与V(T)中各顶点相关联的所有边中,取一条权值最小的边(Vi,Vj)其中,Vi包含于V(T),Vj含于 V(T)。 (4)将边Vi,Vj)加入到E(T)中,将顶点Vj到入到V(T)中。  (5)若V(T)已满n个顶点,则算法终止,否则转步骤(3)。

在实现Prim算法的程序中,我们采用邻接矩阵表示给定的带权连通无向图(如下),&:表示无穷大

 

0

1

2

3

4

5

0

0

3

9

&

15

&

1

3

0

1

9

&

7

2

9

1

0

5

2

&

3

&

9

5

0

11

4

4

15

&

2

11

0

13

5

&

7

&

4

13

0

[要点]

为了实现这个算法,可以引进一个数组close来反映当前已选顶点的状况,该数组元素的初始均为1。另设一个数组closedge来反映已选边的状况,若close[i]=0,则表示顶点i已被选到顶点集中,相应的边为(i,closedge)。

 

>>继续<< >>后退<<

 

 

<script src="../../../../lib/footer.js"> </script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值