There is no single fastest shortest-path algorithm for every large graph. Choose first by query shape and edge weights: use BFS for unweighted paths, Dijkstra for non-negative weights, and an algorithm that supports negative weights when they occur. For one source–target route, test bidirectional search; for many queries on a stable graph, compare preprocessing methods such as contraction hierarchies. Measure query time alongside preprocessing, memory, update cost, and correctness on your actual workload.
Start by matching the algorithm to the query
Before optimizing, specify what the application asks the graph to return. A route between two vertices, distances from one source to every reachable vertex, and distances between all pairs are different workloads. Also record whether the graph is directed, whether weights can be negative, and whether callers need a distance, a reconstructed path, or both. The NetworkX shortest-path overview distinguishes these query types and algorithms.
As an Amazon Associate I earn from qualifying purchases.
| Method | Suitable use | Documented theoretical complexity |
|---|---|---|
| Breadth-first search (BFS) | Unweighted graphs; shortest paths measured by number of edges | O(V + E) |
| Dijkstra | Non-negative edge weights | O((V + E) log V) |
| Bellman–Ford | Graphs with negative weights | O(VE) |
| Floyd–Warshall | All-pairs paths; NetworkX recommends it for dense graphs or all-pairs work | O(V³) |
| Johnson | All-pairs paths in cases suited to the algorithm, including graphs with negative weights | O(V(V + E) log V) |
Here V is the number of vertices and E the number of edges. These are documented asymptotic costs, not runtime predictions for a particular language, graph representation, or machine. NetworkX recommends BFS for unweighted paths, Dijkstra for non-negative weights, and Bellman–Ford when negative weights require support. Its Dijkstra documentation puts the key constraint plainly: “Because Dijkstra’s algorithm works only with non-negative edge weights, alternative algorithms such as Bellman-Ford or Johnson’s algorithm are used for graphs with negative weights.”
How can you speed up a single source–target search?
Try bidirectional search
Instead of searching only outward from the source, bidirectional search explores from both the source and target. Test bidirectional BFS for unweighted graphs and bidirectional Dijkstra for non-negative weighted graphs. NetworkX lists bidirectional variants in its shortest-path methods. Google OR-Tools describes bounded Dijkstra as its preferred generic choice for most needs and says its bidirectional Dijkstra implementation might be faster for large graphs. That is a reason to benchmark it—not a guarantee of a speedup.
#1 Best Overall
Terminate only when it is safe
A point-to-point query need not compute results for every vertex, but stopping early must follow a correct stopping condition for the algorithm being used. Do not stop merely because one frontier has encountered a vertex from the other search; the meeting point is not necessarily enough to establish that the best route has been found. Profile the search and path reconstruction together, including graph representation, weight lookup, and priority-queue behavior, because their relative cost depends on the implementation and workload.
When are contraction hierarchies worth preprocessing?
Contraction hierarchies (CH) are designed for repeated route queries on a graph that stays stable long enough for preprocessing to pay off. The approach separates an upfront preparation phase from later queries; RoutingKit’s documentation describes that separation.
Rank #2
What preprocessing and queries do
During preprocessing, the method contracts vertices in an order and adds shortcut edges when needed to preserve shortest-path distances. A query then runs bidirectional Dijkstra subject to vertex ranks; shortcuts preserve the routes needed for that restricted search to return exact results. The foundational Geisberger et al. paper on exact routing with contraction hierarchies discusses ordering heuristics that seek to limit edge difference and shortcut growth. Too many shortcuts can increase preprocessing time and index space as well as affect query cost.
Recommended Free Tools
When to test CH—and what can invalidate the index
CH is a candidate when many point-to-point queries reuse the same topology and weights. Compare the time and resources spent preparing the index with the savings across the queries it will serve. Changes to topology or weights can mean rebuilding or customizing precomputed data; a static index should not be assumed to remain valid after the graph changes. RoutingKit identifies customizable contraction hierarchies as a separate line of work, but the sources here do not establish current update APIs or comparable rebuild costs across implementations.
How do hub labeling and transit-node routing compare?
Hub labeling and transit-node routing also trade preprocessing and storage for fast repeated queries, but organize their indexes differently.
| Method | How a query uses the index | Main space consideration |
|---|---|---|
| Hub labeling | Each vertex stores hubs and distances. A query intersects the source and target labels and selects a common hub minimizing the sum of the two distances. | For sorted labels, query time is O(|L(s)| + |L(t)|); total storage depends on the sizes of all labels. |
| Transit-node routing | Routes leaving a local region use access nodes; a query combines local access distances with precomputed distances between transit nodes. | The transit-node-to-transit-node lookup table grows quadratically with the number of transit nodes. |
These properties are described in the article on sublinear search spaces for shortest-path planning in grid and road networks. Its theoretical bounds and experiments apply to the graph models and assumptions studied there, not automatically to every production graph. Label sizes and useful index structures depend on graph structure. Consider these methods when very fast repeated queries justify a larger precomputed index, then compare actual index size, preparation time, update cost, query time, and the required exactness.
Rank #4
How should you benchmark candidate methods?
Run comparisons on the graph, query mix, software, and hardware the system will actually use. No general-purpose benchmark figure can establish a winner for an unspecified graph and workload. Make the benchmark answer operational questions, not just which method has the lowest median query latency.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problems- Hold the workload constant: use representative source–target pairs or source sets, including the expected distribution of short and long routes.
- Record the graph and weights: note directedness, graph size, weight properties, and whether topology or weights changed before the run.
- Measure the full trade-off: record query latency, settled or expanded nodes, preprocessing time, shortcut or index size, memory use, and the cost of updates or rebuilding.
- Check output and correctness: verify exact distances and reconstructed paths where required; if approximation is acceptable, define and measure the tolerance. The methods discussed here are exact, and the sources do not establish a recommended approximate alternative.
- Profile the implementation: measure the deployed library and graph representation on the target hardware. Algorithm labels alone do not reveal whether search, weight access, queue operations, or path reconstruction dominates.
Keep preprocessing outside query-latency measurements, but report it and the index’s memory cost. For repeated-query systems, also calculate whether the observed query savings repay preprocessing before the graph or its weights need to change.
Quick Recap
Best Value
A practical decision sequence
- Classify the query: single-pair, single-source, single-target, multi-source, or all-pairs; decide whether the result needs a distance, a path, or both.
- Check the weights: use BFS for unweighted paths, Dijkstra for non-negative weights, and a negative-weight-capable method such as Bellman–Ford where needed.
- Set a baseline: measure the simplest correct method on representative queries before adding an index or specialized search.
- For point-to-point queries, test two frontiers: compare bidirectional BFS or Dijkstra against the one-direction baseline.
- For repeated routes, test preprocessing: evaluate CH, hub labeling, or transit-node routing against the expected query volume, memory budget, and graph-update cadence.
- Choose from measured operating costs: include latency, preparation, storage, updates, and exactness—not query speed alone.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




