0

Is all_pairs_dijkstra just a dijkstra_path with a for loop, or are all shortest path routes calculated all at once in the all_pairs_dijkstra?

Is it faster to do one all_pairs_dijkstra or many dijkstra_path in a for loop?

2 Answers2

0

Although I can't specifically speak to how networkx implements this function, using Dijkstra's algorithm to solve the all pairs shortest paths problem just means running one copy of Dijkstra's algorithm starting from each node in the graph to compute the pairwise distances.

In deciding whether to use a for loop around a single call or to use the all_pairs_dijkstra function, I'd recommend using all_pairs_dijkstra unless you have a compelling reason not to do so, as that function explicitly telegraphs your intent. Plus, if there are any optimizations done behind the scenes, you would be able to take advantage of them.

But specifically for networkx, is there any reason not to just use the simpler all_shortest_paths function? I imagine this is even simpler and would be a good call unless you have a specific reason to use all_pairs_dijkstra.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • All pairs will give me every node to ever node right? That means that if I have 10 nodes, I would have 100 paths? (Minus the diagonal (as in node 1 to node 1). By removing nodes in the middle of the graph, can that speed things up or do I need nodes at every edges for the edge to be used? (I’am new to Graphs as you can see.) – Nicolas Cadieux Jun 23 '19 at 22:35
  • Yes, all-pairs shortest paths (APSP) will give you the best paths between all pairs of nodes. If the graph is undirected, by symmetry you can eliminate about half of them (the path from A to B matches the path from B to A). If you only need to know the path lengths between certain pairs of nodes, you can do better than APSP by computing shortest paths just from those nodes. However, you may still need to factor in the other nodes in the graph, as the shortest paths might pass through them even if you aren't interested in them later on. – templatetypedef Jun 23 '19 at 22:38
0

Networkx implementation of all_pairs_dijkstra and alike uses memoization in form of a heap to memorize what node had already been visited. That makes it way faster compared to iterating over the cross product and using nx.shortest_path manually.

import networkx as nx
from itertools import product

G = nx.grid_2d_graph(20,20)
%timeit -n 3 -r 2 sum([nx.shortest_path_length(G, u, v) for u, v in product(G.nodes, G.nodes)])
17.2 s ± 158 ms per loop (mean ± std. dev. of 2 runs, 3 loops each)
%timeit -n 3 -r 2 sum([ d for t in nx.all_pairs_dijkstra_path_length(G) for d in t[1].values() ])
335 ms ± 1.29 ms per loop (mean ± std. dev. of 2 runs, 3 loops each)
Suuuehgi
  • 4,547
  • 3
  • 27
  • 32
  • Yes indeed, I ended up not using the all pairs because of memory constraints. Thanks for the input! – Nicolas Cadieux Oct 21 '21 at 01:57
  • @NicolasCadieux In case it should be a thing again: It happened to be that I [wrote something](https://stackoverflow.com/questions/69649566/how-do-i-speed-up-all-pairs-dijkstra-path-length/) about the all pairs shortest path thing yesterday. The graph-tool part is lighter on memory. – Suuuehgi Oct 21 '21 at 09:09