Finding all closed loops in a graph

徘徊边缘 提交于 2019-12-06 11:04:47

问题


I am trying to write a Python code which will identify all of the closed loops within an arbitrary graph.

By a closed loop, I mean a loop which visits no vertex more than once, with the exception of the vertex the loop starts on (in the case of this picture, DGHD is an example, as is BCDB, or BCEFDB, or etc).

I tried doing this with matrix multiplication, writing the graph as a matrix with 1s where 2 verticies are connected, and a 0 where they aren't, and putting them to the nth power, however this will take into account non closed loops also.

This person seems to have had the same job, but managed to solve it:

  • Finding unique loops in the closed graph

I was wondering if there was any advice on which direction to take?


回答1:


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)



来源:https://stackoverflow.com/questions/29244965/finding-all-closed-loops-in-a-graph

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