Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding all paths/walks of given length in a networkx graph

I'm using networkx and trying to find all the walks with length 3 in the graph, specifically the paths with three edges. I tried to find some information about the algorithms in the networkx documentation but I could only find the algorithms for the shortest path in the graph. Can I find a length of a path trough specific nodes, for example a path trough nodes 14 -> 11 -> 12 -> 16 if the shortest path is 14 -> 15 -> 16? Here's an image of a graph for an example:

example graph

like image 829
Josip Kolarić Avatar asked Jan 22 '15 18:01

Josip Kolarić


People also ask

How do you find the path length of a graph?

In a graph, a path is a sequence of nodes in which each node is connected by an edge to the next. The path length corresponds to the number of edges in the path. For example, in the network above the paths between A and F are: ACDF, ACEF, ABCDF, ABCEF, with path lengths 3,3,4,4 respectively.

Which method can be used to get the shortest path in NetworkX library?

Returns the shortest weighted path from source to target in G. Uses Dijkstra's Method to compute the shortest weighted path between two nodes in a graph. If this is a string, then edge weights will be accessed via the edge attribute with this key (that is, the weight of the edge joining u to v will be G.

What is path graph in NetworkX?

A path graph is a connected graph denoted by Pn if it contains n nodes. Nodes are connected in form of a straight line in a path graph. Here we will discuss how networkx module can be used to generate one using its inbuilt path_graph() function.

Can NetworkX handle large graphs?

For NetworkX, a graph with more than 100K nodes may be too large. I'll demonstrate that it can handle a network with 187K nodes in this post, but the centrality calculations were prolonged. Luckily, there are some other packages available to help us with even larger graphs.


1 Answers

Simplest version (another version is below which I think is faster):

def findPaths(G,u,n):
    if n==0:
        return [[u]]
    paths = [[u]+path for neighbor in G.neighbors(u) for path in findPaths(G,neighbor,n-1) if u not in path]
    return paths

This takes a network G and a node u and a length n. It recursively finds all paths of length n-1 starting from neighbors of u that don't include u. Then it sticks u at the front of each such path and returns a list of those paths.

Note, each path is an ordered list. They all start from the specified node. So for what you want, just wrap a loop around this:

allpaths = []
for node in G:
    allpaths.extend(findPaths(G,node,3))

Note that this will have any a-b-c-d path as well as the reverse d-c-b-a path.

If you find the "list comprehension" to be a challenge to interpret, here's an equivalent option:

def findPathsNoLC(G,u,n):
    if n==0:
        return [[u]]
    paths = []
    for neighbor in G.neighbors(u):
        for path in findPathsNoLC(G,neighbor,n-1):
            if u not in path:
                paths.append([u]+path)
    return paths

For optimizing this, especially if there are many cycles, it may be worth sending in a set of disallowed nodes. At each nested call it would know not to include any nodes from higher up in the recursion. This would work instead of the if u not in path check. The code would be a bit more difficult to understand, but it would run faster.

def findPaths2(G,u,n,excludeSet = None):
    if excludeSet == None:
        excludeSet = set([u])
    else:
        excludeSet.add(u)
    if n==0:
        return [[u]]
    paths = [[u]+path for neighbor in G.neighbors(u) if neighbor not in excludeSet for path in findPaths2(G,neighbor,n-1,excludeSet)]
    excludeSet.remove(u)
    return paths

Note that I have to add u to excludeSet before the recursive call and then remove it before returning.

like image 126
Joel Avatar answered Oct 20 '22 16:10

Joel