在有向图中找出所有简单环--Johnson算法

article/2025/9/25 18:55:38

注:本算法和计算图所有结点对最短路径的Johnson算法不同。


目录

综述

代码解析

实例解析

引用


综述

Johnson算法由B. Johnson发表于1975年,用于在一个有向图中寻找所有简单环。时间复杂度上界为O((n+e)(c+1)),空间复杂度为O(n+e),其中n为顶点数,e为边数,c为存在环数。在算法执行时,每两个连续的环的输出之间的时间不会超过O(n+e)。

*常用的此类算法的复杂度比较如下:

  1. Tiernan - O(V.const^V)
  2. Tarjan - O(VEC)
  3. Johnson - O(((V+E)C)
  4. Szwarcfiter and Lauer - O(V+EC)

所谓的简单环,即除了第一个和最后一个顶点,其余所有顶点在路径中只出现一次。这里排除了包括像v->v这样的自循环的边和在两个顶点之间的多条边的情况。本算法沿用Tiernan算法的记号,每个简单环都是由根顶点为s的子图构建的,这个子图由s和“大于”s的顶点构成。因此每个输出都根据路径的最小点s来分类。

当从s开始遍历路径,把一个顶点v加入这个路径时,会把这个顶点的状态设为“阻塞”(blocked),直到从v到s的所有路径都完成检索,v会一直保持这种状态,这样保证了一个顶点不会被重复添加。另外除非一个顶点是构造简单环路径的最小的点,这个点不会成为路径的根顶点。这样保证不会无意义的搜索。

算法的输入是一个图结构,图的表示是邻接表形式。假设每个顶点用从1到n的一个数字表示,图表示为AG,则AG(v)是一个数组表示第v个顶点的邻接顶点。算法的过程是这样的:从一个根顶点s开始构建简单环,所经过的路径的顶点保存在一个栈中。算法通过调用CIRCUIT过程添加新顶点,添加时务必将其设置为blocked,并且在过程调用返回时删除这个顶点,但是此时不一定将其阻塞状态去除。

代码解析

下面是算法的伪代码:

algo

如上所述,整个算法包括CIRCUIT主过程, 位于empty stack;语句以上,它又包含一个子过程UNBLOCK用于对一个blocked顶点进行解锁。下面以C++为例谈一下我对这个算法实现的理解:

每个点的ID表示为1到n的一个类型为size_t整数。Ak,B两个数组在开始时被初始化,数组的长度都为n,即顶点数目。这两个数组的元素都是list<size_t>,A数组第i个元素的链表记录从点i出发指向的顶点,即图的邻接表。B的作用是记录因为此点阻塞而被迫阻塞的顶点,一旦点i因为调用unblock过程解锁,那么在B[i]链表中记录的顶点也因此解锁。B的效果是将每个点尽可能的保持阻塞状态以防止重复搜索。blocked是一个长度为n的bool数组,表示在搜索时这个点是否是阻塞。s表示目前搜索到的根结点的编号。

CIRCUIT过程从stack v;语句开始,其输入参数v表示这个CIRCUIT过程所搜索的环都是从v这个顶点开始的。调用开始先将标志量f设为false,f表示这次调用是否发现了一个环。把v放在栈stack中,然后将blocked数组的v设为true,即将此点阻塞。可以看到下方对于CIRCUIT的调用都是将s作为参数,所以stack的栈底一般都是s。下一步遍历Ak中第v个链表,即v出发的边指向的顶点。如果某个顶点与s相等,说明找到了一个环,这时执行输出环并把f设为true。否则如果这个顶点没有阻塞,说明还可以向下走,就递归调用此过程。

如果能够在v的邻接顶点中找到一条环路,则f就是true的,这时可以把v解锁,即调用unblock过程。反之,则说明从包含从v出发的边的路径都是死路,是不可能的形成环的,所以不能解锁v,同时要把与v邻接的顶点置于B数组的第v个链表中,经过v的路径是死路,但经过v的邻接顶点w的不一定死路,应为w可能有另外的上级顶点,所以如果不搜索v了,即解锁v顶点是要把B[v]中记录的顶点也解锁,以供其他路径搜索使用。

对v的调用结束时把v出栈。返回f,标志在这次调用中是否发现环。

下面是如何执行主进程。主进程涉及到寻找强连通分量(scc),这部分可以参考tarjan算法。算法首先清空储存路径节点的栈,将搜寻起点s设为1,注意所有顶点编号从1开始。Ak初始化为在{s, s+1, s+2,...,n}这些顶点构成的子图里面所有强连通分量中,有最小顶点的分量的邻接表。Ak如果为空,说明图已经搜索完,算法结束。否则将s设为上述分量Ak里面最小的顶点,将blocked全置为false,B清空,以s为输入参数调用CIRCUIT。注意此时CIRCUIT只寻找以s开头的环路。调用完成将s加一,再在新的子图中寻找。

实例解析

下面是对上述过程的一个实例,来自YouTube一位Tushar Roy的视频主的教程(此君在YouTube上多有图论方面教程,可以学习,这个算法的视频我搬运到了B站,供诸君参考)。

step1&2

Step1是一个有向图G,Step2表示分解后的三个强连通分量,所谓强连通分量,就是在一个有向图中,任选两个顶点都可以互相到达。分解scc的tarjan算法在此不再赘述。

step3

发现1是最小的顶点,选取1所在的scc开始搜索,第一个调用顶点是1。step3-5是从1开始的3条遍历路径。上图所示,红色边表示搜索的路径,从1开始依次搜索1,2,3,到3的时候,栈里存储了这三个节点,并且blocked数组将这三个元素设为true。3有3个邻接顶点。首先搜索1,发现1是出发的顶点,表明找到了一个环,就将环输出,并把3这里调用的变量f设为true。

step4

回到顶点3后搜索下一个邻接顶点4,4没有阻塞说明还没有探索过,4只有一个邻接点5,走到5之后已经无路可走,因为5的唯一邻接顶点2处于blocked状态,所以以f为false返回这次调用,表明没有找到环。调用从2返回到5的时候看到返回值是false,这时把5放到B[2]的链表中。这种做法相当于告诉2节点:兄弟你解锁的时候把我也解锁了,你不解锁我也堵着算了,反正下次再找到我的时候,我的下家都是死路,找也是白找。所以,只有在调用UNBLOCK(2)的时候5才能解锁,这时blocked[5]还是保持blocked状态。返回的4的时候也是如此。需要把4保持阻塞,并把4放到B[5]的链表中。这时调用返回到了3节点。

step5

检索3的下一个邻居6,发现6的下家4还是阻塞的,于是这次调用也以失败返回。返回到3,3的邻居已经检索完,发现了一个环,所以f是true的,把3的阻塞解除,调用返回到2。因为3找到了一个环所以2的f也是true的,所以调用UNBLOCK(2),这个过程把blocked[2]设为false之后,检索B[2]发现里面有一个元素5,因此递归调用把5也解锁了。依次调用,B就被清空了。

这就是一次1->2这个边开头的检索的完整过程。

本人水平有限,解读如果有失误之处欢迎交流。

引用

[1] Donald B. Johnson, Finding all the elementary circuits of a directed graph, SIAM Journal on Computing, 1975.

[2] BiliBili搬运视频:https://www.bilibili.com/video/BV13Q4y1K7bx

[3] 一个Github的C++实现:https://github.com/hellogcc/circuit-finding-algorithm(其实现无论方式还是算法都有不少和原算法的出入,大家批判性鉴赏。


http://chatgpt.dhexx.cn/article/vLtFx2LL.shtml

相关文章

C#,图论与图算法,寻找加权有向图中所有顶点对之间的最短路径的约翰逊算法(Johnson‘s Algorithm)与源程序

一、最短路径问题 问题是找到给定加权有向图中每对顶点之间的最短路径&#xff0c;权重可能为负。我们已经讨论了这个问题的Floyd-Warshall算法。Floyd-Warshall算法的时间复杂度为Θ&#xff08;V3&#xff09;。利用Johnson算法&#xff0c;我们可以在O&#xff08;V2log VV…

最短路径算法——Dijkstra,Bellman-Ford,Floyd-Warshall,Johnson

本文内容框架&#xff1a; 1 Dijkstra算法 2 Bellman-Ford算法 3 Floyd-Warshall算法 4 Johnson算算法 5 问题归约 6 小结 常用的最短路径算法有&#xff1a;Dijkstra算法、Bellman-Ford算法、Floyd-Warshall算法、Johnson算法 最短路径算法可以分为单源点最短路径和全源最短路…

0018算法笔记——【动态规划】流水作业调度问题与Johnson法则

1、问题描述&#xff1a; n个作业{1&#xff0c;2&#xff0c;…&#xff0c;n}要在由2台机器M1和M2组成的流水线上完成加工。每个作业加工的顺序都是先在M1上加工&#xff0c;然后在M2上加工。M1和M2加工作业i所需的时间分别为ai和bi。流水作业调度问题要求确定这n个作业的…

转:johnson算法的现实意义

Johnson算法是一种用于解决边数与节点数之间关系为O(n^2)的带权图的最短路径问题的算法。它是一种结合了Dijkstra算法和Bellman-Ford算法的技术&#xff0c;通过使用一个负权重的环检测器来消除负权重的影响。这种算法的时间复杂度为O(n^2m log n)。 Johnson算法是一种用于解决…

软件定义网络SDN基础实验:MiniNet常用命令、创建网络拓扑、OpenFlow流表操作

此实验基于《软件定义网络实验1-5》&#xff0c;主要内容为&#xff1a; MiniNet常用命令如何创建网络拓扑OpenFlow流表操作 00x1 搭建SDN环境 SDN 环境配置&#xff1a;Mininet Ryu 1. 测试环境是否搭建成功 启动Ryu&#xff0c;进入 /ryu/app&#xff0c;启动一个交换机…

软件定义网络基础(SDN②)

一.传统网络设备 1.传统设备控制平面和数据平面 2.数据平面的任务 在传统网络中&#xff0c;数据平面是指实际传输和处理数据的部分。它包括网络设备&#xff08;如交换机和路由器&#xff09;&#xff0c;它们通过将数据包从一个接口转发到另一个接口来实现数据传输。数据平面…

软件定义网络SDN

一、为什么使用软件定义网络 传统网络及其设备只可配置&#xff0c;不可编程。网络的分布式控制与管理架构带来的制约&#xff0c;网络的部署、配置与管理需要落到每台设备上去手工完成&#xff0c;每个设备下都紧耦合了三个平面&#xff08;管理平面、控制平面、数据平面&…

软件定义网络技术现状分析

作者&#xff1a;郭春梅&#xff0c;启明星辰资深研究员&#xff0c;研究方向为云计算、虚拟化、SDN技术及安全 转载自&#xff1a;https://mp.weixin.qq.com/s?__bizMzAxNzExNjQ5NA&mid211287920&idx1&snd49893e9187e6055e79db8bb37e44408&scene1&fromg…

SDN软件定义网络相关概念

总结 软件定义网络&#xff0c;已经逐渐成为云计算所依赖的重要技术支一&#xff0c;软件定义网络作为一种新型的网络架构&#xff0c;把网络控制平面和数据平面进行分离&#xff0c;其中控制平面拥有网络全局视图&#xff0c;集中控制网络资源&#xff0c;数据平面只转发数据…

软件定义网络基础(SDN④)

一&#xff1a;SDN控制平面 一个或多个SDN控制器组成&#xff0c;是网络的大脑。 对底层网络交换设备进行集中管理&#xff0c;状态监测、转发决策以及处理和调 度数据平面的流量&#xff1b;通过北向接口向上层应用开放多个层次的可编程能力。 1.典型的SDN控制器体系架构 SDN控…

软件定义网络(SDN)工作原理

传统网络分布式控制架构: 管理平面: 管理设备&#xff08;SNMP&#xff09; 主要包括设备管理系统和业务管理系统&#xff0c;设备管理系统负责网络拓扑、设备接口、设备特性的管理&#xff0c;同时可以给设备下发配置脚本。业务管理系统用于对业务进行管理&#xff0c;比如业务…

认识软件定义网络(SDN)(一)

一、SDN体系结构简介 在传统IP网络中&#xff0c;网络设备内部同时集成了控制逻辑和数据逻辑&#xff0c;控制平面需要实现各种类型的网络协议和功能&#xff0c;为数据平面构造和配置路由转发表&#xff0c;而数据平面则根据路由转发表实现数据包的转发。一般来说&#xff0c…

SDN(Software Defined Network) 软件定义网络学习

SDN&#xff08;Software Defined Network&#xff09; 软件定义网络学习 SDN是啥&#xff1f; 简单来说就是软件定义网络&#xff01;其旨在对现有的网络架构进行重构&#xff0c;使得我们能够像安装软件一样对网络进行修改&#xff0c;加快部署&#xff0c;提高网络可编程能…

软件定义网络 Software Defined Network (一)概述

软件定义网络 Software Defined Network 本文将从以下3个问题对SDN进行阐述 1、为什么要有SDN&#xff1f; 伴随云计算、移动互联网和物联网的蓬勃兴起&#xff0c;应用与业务日益多元&#xff0c;而且快速且多变。网络系统的亚健康问题逐渐明显起来。传统网络工程的弊端日益…

浅谈软件定义网络(SDN)技术研究现状和发展趋势

浅谈软件定义网络(SDN)技术研究现状和发展趋势 友情全文PDF链接&#xff1a;浅谈软件定义网络(SDN)技术研究现状和发展趋势.pdf-网络基础文档类资源-CSDN下载 长久以来&#xff0c;硬件在网络世界中保持着至高无上的地位。直到2008年斯坦福大学的学者提出 OpenFlow[1]&#xf…

软件定义的网络(中)

SDN的出现打破了传统网络设备制造商独立而封闭的控制面结构体系&#xff0c;将改变网络设备形态和网络运营商的工作模式&#xff0c;对网络的应用和发展将产生直接影响。 从技术层面和应用层面来看&#xff0c;SDN的特点主要体现在以下几个方面&#xff1a; 数据平面与控制平…

软件定义网络(PART 3)

软件定义网络PART 3 数据平面SDN数据平面传统网络数据平面传统网络数据平面的特点SDN数据平面SDN数据平面的特点OpenFlow Switch通用转发模型通用可编程转发模型 OpenFlow 概述OpenFlow架构三个组成部分OpenFlow主要版本及特性单流表到多级流表的架构 Open Flow 流表什么是流表…

软件定义网络SDN----新型网络体系结构

1.传统路由器 传统路由器的功能&#xff1a; 为主机间的通信提供转发服务路由选择 路由器之间的传送信息&#xff1a; 主机间的分组路由信息 SDN这种新型网络体系结构的核心思想&#xff1a;把网络的控制层面和数据层面分离&#xff0c;而让控制层面利用软件来控制数据层面…

软件定义网络SDN(计算机网络-网络层)

目录 软件定义网络SDN 数据平面和控制平面 SDN 最重要的三个特征 控制平面与数据平面分离 SDN 的数据平面 软件定义网络SDN SDN的本质特点是控制平面和数据平面的分离以及网络的可编程性&#xff0c;从而实现了网络流量的灵活控制&#xff0c;方便用户管理和配置网络以及部…