You are looking for all paths between one node and another in a directed acyclic graph (DAG).
A tree is always a DAG, but a DAG isn't always a tree. The difference is that a tree's branches are not allowed to join, only divide, while a DAG's branches can flow together, so long as no cycles are introduced.
Your solution can be found as find_all_paths()
in "Python Patterns - Implementing Graphs." This requires a little adaptation to use with igraph. I don't have igraph installed, but using mocks, this seems to work:
def adjlist_find_paths(a, n, m, path=[]):
"Find paths from node index n to m using adjacency list a."
path = path + [n]
if n == m:
return [path]
paths = []
for child in a[n]:
if child not in path:
child_paths = adjlist_find_paths(a, child, m, path)
for child_path in child_paths:
paths.append(child_path)
return paths
def paths_from_to(graph, source, dest):
"Find paths in graph from vertex source to vertex dest."
a = graph.get_adjlist()
n = source.index
m = dest.index
return adjlist_find_paths(a, n, m)
It was unclear from the documentation whether the adjlist is a list of lists of vertex indices or a list of list of vertex objects themselves. I assumed that the lists contained indices to simplify using the adjlist. As a result, the returned paths are in terms of vertex indices. You will have to map these back to vertex objects if you need those instead, or adapt the code to append the vertex rather than its index.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…