nismod / snail

spatial networks impact assessment library 🐌
https://nismod.github.io/snail/
MIT License
9 stars 1 forks source link

Exploration of routing libraries #51

Closed tomalrussell closed 1 year ago

tomalrussell commented 1 year ago

Merging to record this exploration - may remove and leave in history rather than dangling PR.

szhorvat commented 1 year ago

igraph developer here. I just noticed this and wanted to encourage you to give feedback regarding igraph's shortest path finding functionality. We try to make the library useful for practical work, so knowing what our users are doing is important.

Note that the igraph C library has some shortest path-related features implemented that are not yet exposed in Python, but could easily be exposed in the next version if requested. Examples include the A* shortest path algorithm, which will perform very well for single source to single target problems in spatial networks; Yen's algorithm for finding the $k$ shortest paths; a special version of the Floyd-Warshall algorithm that is likely to be the fastest solution in very dense graphs; as well as a widest path finder.

  • slight discrepancy in the path that's found with this test data

Between some node pairs, there may be more than one shortest path. Several libraries, including igraph, have functions that can find all shortest paths.

When the graph is weighted, and the weights are high-precision numbers, multiple shortest paths are unlikely to occur. But suppose that weight (length) values are rounded to a few decimals, e.g. given as multiple of 0.1 km. Then a route made of segments of lengths 0.2 and 0.6, and a route with segments of length 0.1 and 0.7 would have the same length, 0.8. However, due to the nature of floating point calculations, you can try in Python that 0.1+0.7 == 0.2+0.6 is false and 0.1+0.7 < 0.2+0.6 is true. igraph uses comparisons with tolerances internally and is able to find both of these shortest paths. As far as I know, igraph is unique in having this capability.

tomalrussell commented 1 year ago

Thanks for the notes, @szhorvat much appreciated ☺️

Points well taken about multiple shortest paths, floating point precision and tolerance.

I'll have a think about the other features you mention.

The main use case we have is to find shortest paths between a subset of nodes in a network for various kinds of transport flow assignment - not quite all-pairs, so a bunch of calls to single-source-shortest-paths with a set of targets seems to be a reasonable solution.

The single a-to-b query is often useful too - yes, I'd expect A to be pretty good, and bidirectional Dijsktra/A maybe worth looking into.

Last time I was looking into this I had some notes on other more specialised algorithm/data structure combinations - https://github.com/UDST/pandana/issues/120#issuecomment-897462773 - from a little reading around on transport routing.