说说最小生成树(Minimum Spanning Tree)
minimum spanning tree(MST)
最小生成树是连通无向带权图的一个子图,要求
能够连接图中的所有顶点、无环、路径的权重和为所有路径中最小的.
graph-cut
对图的一个切割或者叫切断,会使图分离成为两个不相连的顶点集.
它基于树的两个基本属性:
为树的任意两个节点间添加一条边,会在树中形成一个环.
删去树中的一条边,会将原树分离成两棵不相连的树.
crossing edge
有了切断的概念,很容易就会问到,被切开的那些边是什么?
切断造成了两个不相连的顶点集,而切断的操作施加在这些边上,那么这些边本身就横跨了两个顶点集.
prim’s algorithm
最常用的一种求MST的算法是普利姆算法
它是一种贪心算法.
它搜索的方向是从某一个顶点开始,对所有邻接的边进行考察,然后将最轻的边(权重最小的边)加入MST.
决定它下一步搜索方向的,是最轻边的另一端的顶点,从这个顶点开始,它重复上一步,直到所有的顶点访问完毕.
由于普利姆算法每次都贪心地找当前看来最轻的边,它不会综合考量全局,所以它是一种贪心算法.
由于它从最轻边的另一个端点继续它的搜索之旅,所以每一步求出的在MST中的边都会自然地连成一颗树,直到最后长大为MST.
PriorityQueue
在普利姆算法中,一个重要的操作是挑选最轻边,所以一个优先队列可以对这个操作进行优化支持.
优先队列通常基于堆来实现,比如二叉堆.它可以给我们对数级的时间返回队头元素,而这个队头元素具有最高的优先级.
如果我们规定越轻的边的优先级越高,那么一个小根堆实现的升序优先队列就可以用在普利姆算法中.
lazy prim
普利姆算法在找到一条最轻边(v,w)后,这条边就不应该在以后的搜索中成为一个备选,同时点w也被加入了MST,那么优先队列中所有还未访问的但和点w连着的那些边都成了废弃边,它们不应该被再次考察.
那么如何处理这种不再备选的边?
我们可以删除这些边,但是删除这条边后,边的另一端顶点还没有访问,我们的删除操作会波及那些还没有访问的顶点.
那么,一个比较懒而直观的方式是
推迟对所有的废弃边的删除操作,任由它们在优先队列中,作为队列一员参与队列的每次调整操作.
采取懒惰方式的普利姆算法的时间复杂度是O(ElogE).从这里看出,它对边比较稠密的图来说,是低效的.
如果要了解懒惰方式的的普利姆算法,请参考:普利姆算法lazy实现
eager prim
以懒惰方式处理不再备选的边,会使得算法多次考察这样的边,影响了效率.
有没有方法对它进行改进?
考虑一下,我们在找出一条最轻边并将它加入MST后,实际上使得其它的还没有被访问的边被访问的机会增加了.
而我们只对最轻边感兴趣,所以在考察一个顶点时,只需要在优先队列中维护一条目前已知的到这个顶点的最短距离或最小权重就可以了.
为了不将废弃边加入队列,我们需要以索引方式来组织优先队列.
关于索引式的优先队列,请参考:索引式 优先队列
以积极方式队列废弃边的算法,请参考:普利姆算法eager实现
普利姆算法的eager实现的时间复杂度是最差O(ElogV )
kruskal’s algorithm
克鲁斯卡尔算法是求MST的另一种常用算法,它非常简单:
1.每一步都挑选当前看来最轻的边.如果这条边的两个端点的加入,没有在mst中造成回路,将这条边加入mst.
2.对所有的边重复上一步.
算法中比较关键的一个操作是判断是否形成回路(cycle),这可以借助并查集来做,请参考:快速并查集
克鲁斯卡尔算法的时间复杂度为O(ElogE).
这里是一个完成的算法实现,请参考:克鲁斯卡尔算法实现
综述
最小生成树和最小生成森林(minimum spanning forest)技术,对于连通性考察很有意义.
克鲁斯卡尔算法和懒惰方式的普利姆算法形式简单、易于理解,适合处理边不稠密的图.
积极方式的普利姆算法,初次接触会不易理解.但它效率高于懒惰方式,平均适用性更好.
求MST的贪心算法,都离不开优先队列或堆的支持,堆的操作效率决定了这些算法的效率.
如果用斐波那契堆来实现优先队列,则decrease-key操作的摊还代价是O(1 ),普里姆算法将可优化到:O(E+VlogV ).
说说最小生成树(Minimum Spanning Tree)的更多相关文章
- 【算法】关于图论中的最小生成树(Minimum Spanning Tree)详解
本节纲要 什么是图(network) 什么是最小生成树 (minimum spanning tree) 最小生成树的算法 什么是图(network)? 这里的图当然不是我们日常说的图片或者地图.通常情 ...
- 最小生成树(Minimum Spanning Tree)——Prim算法与Kruskal算法+并查集
最小生成树——Minimum Spanning Tree,是图论中比较重要的模型,通常用于解决实际生活中的路径代价最小一类的问题.我们首先用通俗的语言解释它的定义: 对于有n个节点的有权无向连通图,寻 ...
- Prim算法、Kruskal算法和最小生成树 | Minimum Spanning Tree
graph to tree非常有趣! 距离的度量会极大地影响后续的分析,欧式距离会放大差异,相关性会缩小差异,导致某些细胞群分不开. 先直观看一下,第一个是Prim,第二个是Kruskal.但是肯定都 ...
- 算法练习:最小生成树 (Minimum Spanning Tree)
(注:此贴是为了回答同事提出的一个问题而匆匆写就,算法代码只求得出答案为目的,效率方面还有很大的改进空间) 最小生成树是指对于给定的带权无向图,需要生成一个总权重最小的连通图.其问题描述及算法可以详见 ...
- 最小生成树 (Minimum Spanning Tree,MST) --- Prim算法
本文链接:http://www.cnblogs.com/Ash-ly/p/5409904.html 普瑞姆(Prim)算法: 假设N = (V, {E})是连通网,TE是N上最小生成树边的集合,U是是 ...
- 最小生成树 (Minimum Spanning Tree,MST) --- Kruskal算法
本文链接:http://www.cnblogs.com/Ash-ly/p/5409265.html 引导问题: 假设要在N个城市之间建立通信联络网,则连通N个城市只需要N - 1条线路.这时,自然会考 ...
- 【HDU 4408】Minimum Spanning Tree(最小生成树计数)
Problem Description XXX is very interested in algorithm. After learning the Prim algorithm and Krusk ...
- 数据结构与算法分析–Minimum Spanning Tree(最小生成树)
给定一个无向图,如果他的某个子图中,任意两个顶点都能互相连通并且是一棵树,那么这棵树就叫做生成树(spanning tree). 如果边上有权值,那么使得边权和最小的生成树叫做最小生成树(MST,Mi ...
- HDU 4408 Minimum Spanning Tree 最小生成树计数
Minimum Spanning Tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge 最小生成树+树链剖分+线段树
E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...
随机推荐
- 基于消逝时间量的共识机制(POET)
来自于Intel project:Hyperledger Sawtooth,目前版本 PoET 1.0 PoET 其实是属于Nakamoto consenus的一种,利用“可信执行环境”来提高当前解决 ...
- mysql -> 启动&多实例_03
常用的连接方式: 套接字: mysql -uroot -p123 -S /application/mysql/tmp/mysql.sock Tcp/Ip: mysql -uroot -p123 -h ...
- 十八、springboot中hibernate配置sessionFactory访问数据库
前提 在yml或properties文件中配置数据库与数据库连接池 Hibernate配置 几种方式: 方式一: @Configuration public class HibernateConfig ...
- SQLAlchemy-方言(Dialects)
一: Dialects 文档是分为三个部分: SQLAlchemy ORM, SQLAlchemy Core, and Dialects. SQLAlchemy ORM:在SQLAlchemy ORM ...
- 洛谷P2194HXY烧情侣
传送门啦 这个题可以说是tarjan强连通分量的裸题,但需要维护每个强连通分量的最小值,所以做法就很明确了. 我们先明确几个数组的意思: 1.首先是tarjan缩点中的几个数组: dfn[i]:i点的 ...
- cuowu
ngFor不能用于Object rowspan colspan不能绑定变量,要用attr.colspan https://stackoverflow.com/questions/35615751/wh ...
- 进程同步——哲学家进餐问题Java实现
哲学家就餐问题是1965年由Dijkstra提出的一种线程同步的问题. 问题描述:一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条.哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿 ...
- Python学习笔记:startswith & endswith 判断开头结尾是否为指定字符串
作用: 判断字符串是否以指定字符或子字符串结尾,常用于判断文件类型. 如果以指定后缀结尾返回True,否则返回False. 可选参数"start"与"end"为 ...
- 利用CE手动破解百度云下载限速!
一步,你需要打开百度云<ignore_js_op> 第二步,你需要用上面附送的工具选择百度云进程<ignore_js_op> 第三点,不多说,看图<ignore_js_o ...
- 使用Kafka、Elasticsearch、Grafana搭建业务监控系统(三)Elasticsearch
https://blog.csdn.net/tonywu1992/article/details/83576863