Finding all closed loops in a graph

半城伤御伤魂 提交于 2019-12-04 16:39:27

NetworkX is a popular Python package for working with graphs included in many scientific Python distributions. It includes some algorithms for computing graph cycles. In particular, simple_cycles(DiGraph) would answer your question.

One caveat to this approach is that you have to convert your graph into a digraph. This means that every edge of your undirected graph will become a cycle in your directed version. (An undirected edge becomes two directed edges.) You can simply filter the output to only contain cycles of length three or greater.

Here's an example using the graph you linked to:

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))

The (truncated) output is:

[['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'],
 ...
]

If you'd prefer to implement this yourself without using NetworkX simple_cycles() uses Johnson's algorithm. (See Donald B. Johnson, Finding All the Elementary Circuits of a Directed Graph, SIAM J. Comput., 4(1), 77–84)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!