python - 查找图中的所有闭环

标签 python math graph counting

我正在尝试编写一个 Python 代码来识别任意图中的所有闭环。

闭环是指一个循环不访问任何顶点超过一次,循环开始的顶点除外(在 this picture 的情况下,DGHD 是一个示例,如 BCDBBCEFDB 等)。

我尝试用矩阵乘法来做到这一点,将图形写成一个矩阵,其中 2 个顶点相连,1 为 0,不相连的地方为 0,并将它们的 n 次方计算在内,但是这将考虑非封闭也有循环。

这个人似乎有同样的工作,但设法解决了:

我想知道是否有任何建议可以选择哪个方向?

最佳答案

NetworkX是一个流行的 Python 包,用于处理许多科学 Python 发行版中包含的图形。它包括一些用于计算图形循环的算法。特别是,simple_cycles(DiGraph)会回答你的问题。

此方法的一个警告是您必须将图形转换为有向图。这意味着无向图的每条边都将成为有向图的循环。 (一条无向边变为两条有向边。)您可以简单地过滤输出以仅包含长度为三或更大的循环。

这是一个使用您链接到的图表的示例:

from networkx import Graph, DiGraph, simple_cycles

# construct a graph using a dict: {node:[connected_nodes]}
G = Graph(
    {'A':['B','G','H'],
     'B':['A','C','D'],
     'C':['B','D','E'],
     'D':['B','C','E','F','G', 'H'],
     'E':['C','D','F'],
     'F':['D','E','G'],
     'G':['A','D','F','H'],
     'H':['A','D','G'],
    }
)

# optional: draw the graph for verification
#labels = dict(zip(G.nodes(),G.nodes()))
#networkx.draw_networkx(G,labels=labels)

# simple_cycles only accepts DiGraphs. convert G to a bi-directional
# digraph. note that every edge of G will be included in this list!
DG = DiGraph(G)
list(simple_cycles(DG))

(截断的)输出是:

[['B', 'D', 'H', 'G', 'F', 'E', 'C'],
 ['B', 'D', 'H', 'G', 'A'],
 ['B', 'D', 'H', 'A', 'G', 'F', 'E', 'C'],
 ['B', 'D', 'H', 'A'],
 ['B', 'D', 'F', 'G', 'H', 'A'],
 ['B', 'D', 'F', 'G', 'A'],
 ['B', 'D', 'F', 'E', 'C'],
 ['B', 'D', 'G', 'F', 'E', 'C'],
 ...
]

如果您更愿意自己实现而不使用 NetworkX simple_cycles(),请使用 Johnson 算法。 (参见 Donald B. Johnson,查找有向图的所有基本电路,SIAM J. Comput.,4(1),77–84)

关于python - 查找图中的所有闭环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29244965/

相关文章:

java - 单根有向无环图环检测

c++ - 使用 Boost Graph 读取 GraphML 文件时使用 vertex_name

r - 基于一个条形图对并排条形图进行排序,ggplot2

python - 为什么 re.groups() 不为我的一个正确匹配的组提供任何东西?

javascript - Math.floor(Math.random() * 5 + 1) 的操作顺序?

algorithm - 180° 偏移无关紧要时的角度加权平均值 (MATLAB)

c++ - 如果求和是通过循环完成,则以下程序找到正确答案,但如果通过 GP 公式完成,则不正确。为什么?

python - 数据框上的多条件过滤器

python - WIndows:创建新控制台窗口的子进程,丢失标准输入/输出

python - 如何在python中将像293.4662543这样的 float 转换为293.47?