最小生成树的2种算法介绍

下面这篇文章是我在16年的时候写就的,首发于博客园。今天来复习一下。

《大话数据结构》中在“图”的那一章节有这样一个实例:假设你是电信实施工程师,需要为一个镇的九个村庄架设通信网络做设计。村庄位置大致如下图,之间连线的数字表示村与村间的可通达直线距离(个别如v0与v6,v6与v8,v5与v7未测算距离是因为有高山或湖泊,不予考虑)。你们领导要求你必须用最小的成本完成这次任务。你说怎么办?


图1

我多年前在某家设计院也是做网络规划设计的,而且觉得很有实际意义,所以拿出来给大家分享一下。其实这个案例就是查找连通网的最小生成树。这术语不懂也没关系,我们不管它叫什么。

有人说,这还不简单嘛,我凭着直觉就能做出来。不排除你有这种能力,有时候人类的“直觉”真的是强大,也不知道人类是如何进化到这么聪慧的。

有人说,把所有可能的方案罗列出来,再一一比对,找到最短路径的那个方案,就行了。这确实是个好办法,实际上我们也是这样做的。那么怎么去罗列所有的方案呢?。

为了便于描述上面的图,我们构造图的邻接矩阵。如下图所示:


图2

在单纯的计算或者有规律的运算方面,我们很容易想到借助计算机来帮忙解决。 刚刚我提到人类的直觉是很强大的,比如有的人答题的时候直接省略了步骤得出了结果,而要他写详细的步骤可能他也说不太清。计算机是没有直觉的,某些我们认为很简单的东西她可能要运算很多次,而且你还得教她怎样按照她自己“有限的能力”去执行,可是往往我们不知道怎么去教计算机,也就是具体的怎样写代码。

这里介绍两种思路,也就是两个算法:

一、一种思路是这样的:

从v0(可以任意选定一点,这里选v0)开始,找到与其相连的最短的路径,定义两个一维数组a,b。a存储相关顶点的权值(边长度),b存储对应的顶点。路径(b[i],i)的权值为a[i].i为0至8的整数,v0为起点至各点的权值如下所示(实际中我们用65535来代表无穷大)。


图3

求a数组中的最小值,为10,对应的i为1,标记边(v0,v1)并让ai置为0,代表vi已经纳入生成路径了(此时i为1)。

然后从v1开始,排除a[i]=0对应的顶点vi,当(v1,vi)的权值小于此时a[i]的值,将前者替换掉后者,更新a数组的值。


图4

求a数组中的最小值,为11,对应的i为5,标记边(v0,v5)并让a5置为0,代表v5已经纳入生成路径了。

然后从v5开始,排除a[i]=0对应的顶点vi,当(v5,vi)的权值小于此时a[i]的值,将前者替换掉后者,更新a数组的值。


图5

下面的步骤依此类推,以表格表述。


图6
图7

图8

图9

图10

上面这个一步步找到最优路径的方法其实就是普里姆算法。是不是很巧妙呢?我猜是一个叫普里姆的人发明的方法。具体的代码实现如下(从《大话数据结构》拷贝的):


图11
二、第二种思路是这样的:

将各边所对应的起始点及权值(边长)按权值排序,整理成下表所示:


图12

这种方法就是以边为核心,每次搜索相关的最短边,排除掉形成闭环的边。

第一次找到的边为(v4,v7)

第二次找到的边为(v2,v8)

第三次找到的边为(v0,v1)

第四次找到的边为(v0,v5)

第五次找到的边为(v1,v8)

第六次找到的边为(v3,v7)

第七次找到的边为(v1,v6)

第八次找到的边为:这次按边长排序轮到(v5,v6),但是此时与上面所找到这些边形成了环路。过滤掉!

第九次找到的边为:这次按边长排序轮到(v1,v2),但是此时与上面所找到这些边形成了环路。过滤掉!

第十次找到的边为(v6,v7)

此后的边均构成环路,过滤掉。

过程是很明晰的,但是算法的具体实现却很精妙。也是用数组的模型,占位更新的思想去实现。每次确定了一条边就在数组中相应位置用相关值做上标记。判断是否形成环路的方法也是很巧妙的,桥接起了边与起始点的关系:形成一个环路就是起始点首尾依次连接,最后回到起点。

图13
图14

最终最小生成树就是如下图标黑所示:

图15

对比两个算法,克鲁斯算法边数少时,效率会非常高;而普里姆算法对于边数非常多的情况会更好一些。

关于这两个算法相信大家都大概了解了。或许有人会对上面算法的正确性存疑,可以在网上搜索一下相关证明或者验证,我这边提供一个链接作为参考 点这里

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容