NetworkX 是一个流行的 Python 包,用于处理图形,在许多科学 Python 发行版中都包含了它。它包括一些计算图形循环的算法。特别是
simple_cycles(DiGraph)
可以回答你的问题。
这种方法的一个注意点是,你必须将你的图形转换成有向图。这意味着你无向图的每条边在有向版本中都会变成一个循环。(一个无向边变成两个有向边。)你可以简单地过滤输出,只包含长度大于三的循环。
以下是使用你提供的图形的示例:
from networkx import Graph, DiGraph, simple_cycles
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'],
}
)
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,可以自己实现此功能,使用Johnson算法的simple_cycles()
。 (参见Donald B. Johnson,“Finding All the Elementary Circuits of a Directed Graph”,SIAM J. Comput。,4(1),77-84)