Skip to content
Advertisement

Find all shortest paths between all pairs of nodes in NetworkX

I am trying to get all shortest paths between all pairs of nodes in an undirected unweighted graph. I am currently using nx.all_pairs_shortest_path(), but I don’t understand why it only returns one shortest path for every pair of nodes. There are cycles in my graph so there should exist multiple shortest paths between certain nodes. Any suggestions?

Advertisement

Answer

I stumbled upon this problem myself and arrived her in my quest for a solution. unfortunately networkx doesn’t have a function to calculate all the shortest pathes for every pair of node. Moreover the answer from Igor Michetti wasn’t giving what i wanted at all but it might have been tweekable.

The answer from math_noob was good because it was close enough for me to make up a solution but the problem was that it was way way too slow.

def single_source_shortest_paths(graph,source):
    shortest_paths_dict = {}
    for node in graph:
        shortest_paths_dict[node] = list(nx.all_shortest_paths(graph,source,node))
    return shortest_paths_dict

def all_shortest_paths(graph):
    for source in graph:
        yield source, single_source_shortest_paths(source)

So i went back on networkx documentation and try to find one last time if there was any function i could use. but there was none so i decided i would implment it myself.So i first tried to implement everything by had which was a bit chaotic to only realise that it was a bit better but not that much so i decided i would try to look into the source code and found there a holy grail which is the nx.predecessor function.

This function is called on the graph and the source node only so it doesn’t depends on the target node and it is the one doing most of the hard work. So i just recreated the function single_source_shortest_paths but by calling only once nx.predecessor per source node and then doing the same as all_shortest_path which only consist of calling another function with the right arguments.

def single_source_shortest_paths_pred(graph,source):
    shortest_paths_dict = {}
    pred = nx.predecessor(graph,source)
    for node in graph:
        shortest_paths_dict[node] = list(nx.algorithms.shortest_paths.generic._build_paths_from_predecessors([source], node, pred))
    return shortest_paths_dict

In terms of time nx.predecessor takes the majority of the time to execute so the second function is around n times faster where n is the number of nodes in the graph

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement