4

I want to compute all shortest paths between all pairs in a graph. To achieve this, I am using graph_tool's all_shortest_paths function for every node pair in the graph. According to the documentation, the function is able to respect edge weights, if given. At first glance this works fine. I found, however, that the returned list of shortest paths is incomplete. It seemingly only includes shortest paths, which also use the least amount of hops from the complete set of shortest paths.

Here is a small example:

import graph_tool
import graph_tool.topology

#setup graph
g = graph_tool.Graph()
g.add_vertex(5)
edges = [(0,1),(1,2),(3,2),(0,4),(4,3)]
metrics = [3, 4, 2, 1, 3]
g.edge_properties["metric"] = g.new_edge_property("int")
for i in range(len(metrics)):
    e = g.add_edge(*(edges[i]))
    g.edge_properties["metric"][e] = metrics[i]

#compute all shortest paths from 0 to 2
paths = graph_tool.topology.all_shortest_paths(g, 0, 2, weights=g.edge_properties["metric"])

for path in paths:
    print(path)

print("-"*10)

#increase metric of edge 0-4
g.edge_properties["metric"][g.edge(0,4)] = 2

#recompute all shortest paths from 0 to 2
paths = graph_tool.topology.all_shortest_paths(g, 0, 2, weights=g.edge_properties["metric"])

for path in paths:
    print(path)

It generates a graph with 5 vertices and edges that form 2 paths from vertex 0 to vertex 2 like so:

0 --- 1 --- 2
 \         /
  \       /
   4 --- 3

Obviously, the path [0, 1, 2] is shorter than [0, 4, 3, 2] in terms of hop count. If no metric is given, this is correctly recognized (not demonstrated here).

In the beginning of the example, the edges are weighted in such a way, that the second path, which has more hops, is 'shorter'. The sum of the metrics is 6, whereas the other path has a total value of 7. Consequently, the algorithm correctly returns [0, 4, 3, 2].

Then, the metric of the edge between 0 and 4 is increased by 1. Now both paths have the same total value and should both be returned. Yet, the algorithm only returns [0, 1, 2]. I can only assume that hop count is still somehow factored in, even though I specified a metric, and this is why the second path is neglected. As far as I've seen, there is no mention of this behavior in the official documentation.

Am I overlooking something? Is there a better function to do this, perhaps even if a different library? I already looked into igraph as an alternative, but it does appear to only be capable of computing one shortest path per node pair.

1 Answers1

3

This is behavior is indeed a bug in graph-tool, that occurs when weights are being used! I have just committed a fix that solves it: https://git.skewed.de/count0/graph-tool/commit/dc06771604dfd8f38d40e68ce16b537bc1afc272

Thanks for catching this, and for the very clear example!

Tiago Peixoto
  • 5,149
  • 2
  • 28
  • 28