强连通分量分解的Kosaraju算法

今天是算法数据结构专题的第35篇文章,我们来聊聊图论当中的强连通分量分解的Tarjan算法。

Kosaraju算法一看这个名字很奇怪就可以猜到它也是一个根据人名起的算法,它的发明人是S. Rao Kosaraju,这是一个在图论当中非常著名的算法,可以用来拆分有向图当中的强连通分量

背景知识

这里有两个关键词,一个是有向图,另外一个是强连通分量。有向图是它的使用范围,我们只能使用在有向图当中。对于无向图其实也存在强连通分量这个概念,但由于无向图的连通性非常强,只需要用一个集合维护就可以知道连通的情况,所以也没有必要引入一些算法。

有向图我们都了解,那么什么叫做强连通分量呢?强连通分量的英文是strongly connected components。这是一个很直白的翻译,要理解它我们首先需要理解强连通的概念。在有向图当中,如果两个点之间彼此存在一条路径相连,那么我们称这两个点强连通。那么推广一下,如果一张图当中的一个部分中的每两个点都连通,那么这个部分就称为强连通分量。

强连通分量一般是一张完整的图的一个部分,比如下面这张图当中的{1, 2, 3, 4}节点就可以被看成是一个强连通分量。

其实求解强连通分量的算法并不止一种,除了Kosaraju之外还有大名鼎鼎的Tarjan算法可以用来求解。但相比Tarjan算法,Kosaraju算法更加直观,更加容易理解。

算法原理

Kosaraju算法的原理非常简单,简单到只有三个步骤

  1. 我们通过后序遍历的方式遍历整个有向图,并且维护每个点的出栈顺序
  2. 我们将有向图反向,根据出栈顺序从大到小再次遍历反向图
  3. 对于点u来说,在遍历反向图时所有能够到达的v都和u在一个强连通分量当中

怎么样,是不是很简单?

下面我们来详细阐述一下细节,首先后序遍历和维护出栈顺序是一码事。也就是在递归的过程当中当我们遍历完了u这个节点所有连通的点之后,再把u加入序列。其实也就是u在递归出栈的时候才会被加入序列,那么序列当中存储的也就是每个点的出栈顺序。

这里我用一小段代码演示一下,看完也就明白了。

popped 

我们在访问完了所有的v之后再把u加入序列,这也就是后序遍历,和二叉树的后序遍历是类似的。

反向图也很好理解,由于我们求解的范围是有向图,如果原图当中存在一条边从u指向v,那么反向图当中就会有一条边从v指向u。也就是把所有的边都调转反向。

我们用上面的图举个例子,对于原图来说,它的出栈顺序我们用红色笔标出。

也就是[6, 4, 2, 5, 3, 1],我们按照出栈顺序从大到小排序,也就是将它反序一下,得到[1, 3, 5, 2, 4, 6]。1是第一个,也就是最后一个出栈的,也意味着1是遍历的起点。

我们将它反向之后可以得到:

我们再次从1出发可以遍历到2,3, 4,说明{1, 2, 3, 4}是一个强连通分量。

怎么样,整个过程是不是非常简单?

我们将这段逻辑用代码实现,也并不会很复杂。

N 

思考

算法讲完了,代码也写了,但是并没有结束,仍然有一个很大的疑惑没有解开。算法的原理很简单,很容易学会,但问题是为什么这样做就是正确的呢?这其中的原理是什么呢?我们似乎仍然没有弄得非常清楚。

这里面的原理其实很简单,我们来思考一下,如果我们在正向dfs的时候,u点出现在了v点的后面,也就是u点后于v点出栈。有两种可能,一种可能是u点可以连通到v点,说明u是v的上游还有一种可能是u不能连通到v,说明图被分割成了多个部分。对于第二种情况我们先不考虑,因为这时候u和v一定不在一个连通分量里。对于第一种情况,u是v的上游,说明u可以连通到v。

这时候,我们将图反向,如果我们从u还可以访问到v,那说明了什么?很明显,说明了在正向图当中v也有一条路径连向u,不然反向之后u怎么连通到v呢?所以,u和v显然是一个强连通分量当中的一个部分。我们再把这个结论推广,所有u可以访问到的,第一次遍历时在它之前出栈的点,都在一个强连通分量当中。

如果你能理解了这一点,那么整个算法对你来说也就豁然开朗了,相信剩下的细节也都不足为虑了。

今天的文章到这里就结束了,如果喜欢本文的话,请来一波素质三连,给我一点支持吧(关注、转发、点赞)。

算法数据结构 | 三个步骤完成强连通分量分解的Kosaraju算法​mp.weixin.qq.com

- END -

有向图最长路径算法_算法数据结构 | 三个步骤完成强连通分量分解的Kosaraju算法...相关推荐

  1. 机器学习分类算法_达观数据:5分钟带你理解机器学习及分类算法

    1.本文介绍内容:什么是机器学习,机器学习有哪些分类算法,分类算法之k-近邻,决策树,随机森林2.本文适合人群:本文通过通俗易懂的语言和例子介绍核心思想,不拽高大上的名词,适合于不懂机器学习的小白3. ...

  2. matlab 随机森林算法_(六)如何利用Python从头开始实现随机森林算法

    博客地址:https://blog.csdn.net/CoderPai/article/details/96499505 点击阅读原文,更好的阅读体验 CoderPai 是一个专注于人工智能在量化交易 ...

  3. python目标识别算法_深度学习目标检测系列:一文弄懂YOLO算法|附Python源码

    摘要: 本文是目标检测系列文章--YOLO算法,介绍其基本原理及实现细节,并用python实现,方便读者上手体验目标检测的乐趣. 在之前的文章中,介绍了计算机视觉领域中目标检测的相关方法--RCNN系 ...

  4. yolo算法_吴恩达深度学习笔记(100)-目标检测之YOLO 算法讲解

    YOLO 算法(Putting it together: YOLO algorithm) 你们已经学到对象检测算法的大部分组件了,在这个笔记里,我们会把所有组件组装在一起构成YOLO对象检测算法. 我 ...

  5. 什么是陀螺仪的dr算法_一种基于DR/GPS/MM的组合定位系统数据融合算法

    摘 要: 针对盲区中使用INS惯性导航系统进行定位存在误差积累的问题,提出一种基于DR航位推算.GPS全球定位系统和MM地图匹配的组合定位系统数据融合算法.该算法利用GPS和MM中得到的位置信息,一方 ...

  6. java jvm垃圾回收算法_深入理解JVM虚拟机2:JVM垃圾回收基本原理和算法

    本文转自互联网,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 喜欢的话麻烦点下Star哈 文章将同步到我的个人博客: www.how ...

  7. skew算法_一种基于FPGA的多通道高速输入信号自动de‑skew算法的制作方法

    本发明涉及高速数据采集技术,更具体的涉及一种基于FPGA的多通道高速输入信号自动de-skew算法. 背景技术: 随着对精度和速率要求越来越高,目前数据采集系统向着多通道和超高速两个方向发展.多通道高 ...

  8. 总结 贪心算法_这几道经典例题帮你轻松搞透贪心算法

    贪心算法概念叙述 运用贪心算法求解问题时,会将问题分为若干个子问题,可以将其想象成俄罗斯套娃,利用贪心的原则从内向外依次求出当前子问题的最优解,也就是该算法不会直接从整体考虑问题,而是想要达到局部最优 ...

  9. 朴素贝叶斯算法_机器学习第三篇:详解朴素贝叶斯算法

    一.统计知识 01|随机事件: 1.概念 随机事件是在随机试验中,可能出现也可能不出现,而在大量重复试验中具有某种规律性的事件叫做随机事件(简称事件).随机事件通常用大写英文字母A.B.C等表示.随机 ...

最新文章

  1. 装上螺旋桨,加州理工让只能行走的双足机器人「上了天」,还玩起了障碍滑板、走绳索...
  2. 7-5 表格输出 (C语言)
  3. 简单查找,如果找到返回下标,如果找不到返回-1
  4. iOS Xcode4.2代码管理工具的使用
  5. 华为可以分屏吗_华为手机经常弹出“系统更新”提示,可以不更新吗?看完涨知识了...
  6. 机器学习第三篇:详解朴素贝叶斯算法
  7. python ini文件 遍历_【自动化测试】Python 读取 .ini 格式文件
  8. mfc做数独游戏_我终于在iPhone上找到了体验最好的数独游戏
  9. 图片列表模板 html代码,图片列表模板
  10. “最快3个月复制支付宝的核心能力” 解密蚂蚁金服bPaaS
  11. verilog qpsk调制解调
  12. oracle begin 后声明,Oracle BEGIN END 详细用法
  13. 【51单片机快速入门指南】5.2:SPI读取 12位ADC XPT2046 芯片
  14. NVIDIA Jetson TK1学习与开发(一):NVIDIA Jetson TK1介绍
  15. Android 内外边距
  16. 关键链项目管理汇总贴
  17. 文件操作的实例——下载并合并流式视频文件
  18. 【软考-中级】系统集成项目管理工程师-【1信息化知识】
  19. current sink/source, current mirror and current reference
  20. cad中tk什么意思_AutoCAD中“实点”解读:TK命令怎么用? - CAD自学网

热门文章

  1. Machine Learning之Python篇(一)
  2. chrome调试js的小技巧
  3. 第三章——jXLS Excel标记
  4. 配置Chrome支持本地(file协议)的AJAX请求
  5. shell学习三十四天----printf详解
  6. Beginning SDL 2.0(4) YUV加载及渲染
  7. 星巴克REST案例分析读后感
  8. C#_自动化测试 (四) 自动卸载软件
  9. 文件上传下载流程设计
  10. 自动校验控件演示[含源码]