Introduce to algorithm--------pseudo code to C/C++ code (chapter 23)

最小生成树

图算法(连通无向图)中有一类经典问题,叫做最小生成树(Minimal Spanning Tree)。简单
的来说,最小生成树问题是这样一种问题 : 在连接所有图顶点的情况下,求使得所选边的权重和最
小的方案。

算法导论中主要介绍了两种经典的算法:

  1. Kruskal算法
  2. Prim算法

两种算法都采用贪心算法来解决问题。书中描述最小生成树的通用贪心解决方案

遵循一个循环不变式的边集合A:

在每遍循环之前,A是某棵最小生成树的一个子集。

这种策略一般并不能保证找到一个全局最优的解决方案。但对于最小生成树问题来说,
我们可以证明,某些贪心策略确实能够找到一棵权重最小的生成树。

Kruskal算法中,集合A是一个森林 ,其节点就是给定图的节点。每次加入到集合A中的安全边永
远是权重最小的连接两个不同分量的边。在Prim中,集合A则是一棵。每次加入到A中的安全
边永远是连接A和A之外某个节点的边中权重最小的。

Kruskal算法

核心

将图节点看成森林,不断选择连接任意两森林的权重最小的边、合并森林,通过不断重复选择、合并
,最后将所有森林合并成一棵树。

初始

每个图节点即为一个森林:

init

选择

选择连接任意两个森林的权重最小的边,这里是h->g:

select

合并

合并选中的边的两个节点所在的两个森林:

merge

重复

不断重复选择、合并操作,直到所有节点合并成一颗树。

结果

被深灰色涂中的边即为选中边:

result

Code

https://code.csdn.net/snippets/1346944
(注:编译、运行通过。运行环境:windows8.1 VS2013)

读者可自行下载代码,编译运行并与上图对照。

Prim 算法

核心

将图节点看成一棵树和剩余节点,选择一个根节点,选择与树相邻的最小边、将节点合并到树中,通
过不断重复选择、合并,最终将所有节点合并到树中。

根节点

随机选择一个根节点(图中涂黑的即为选择的根节点:a):

root

初始

一棵只包含根节点a的树、剩余节点(除根节点a外所有节点,即蓝色实线框出的节点):

init

选择

选择一条与树相连的权重最小的边:

select

合并

将所选边所连接的两端合并(即将节点合并到树中):

merge

重复

重复选择、合并过程,直到所有节点都被包含在树中。

结果

被深灰色涂中的边即为选中边:

result

Code

https://code.csdn.net/snippets/1347811
(注:编译、运行通过。运行环境:windows8.1 VS2013)

More

值得一提的是,上图所示的最小生成树不是唯一的。边 b->c 与 a->h 权重相同,也就是说,将
前一条边替换为后一条边所构造出来的MST同为最优解。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值