...

/

Johnson’s Algorithm

Johnson’s Algorithm

Learn how Johnson’s algorithm uses single-source shortest-paths algorithms for computing all-pairs shortest-paths.

When tasked with finding the shortest paths between all pairs of vertices, calculating the shortest paths between them seems easy enough. In the presence of negative edge weights, our first instinct is to call the Bellman-Ford algorithm from each vertex.

This would certainly guarantee the detection of negative-weight cycles in the digraph. On the other hand, it would take a whopping O(n4)O(n^4) time in the worst case.worstcasejohnson

Press + to interact

Johnson’s algorithm refines this idea of using a single-source shortest-paths algorithm from each vertex to solve the all-pairs shortest-paths problem. The algorithm is named after Donald B. Johnson, who is also credited with generalizing binary heaps to dd-ary heaps.

The central idea

The central idea behind Johnson’s algorithm is to transform the edge weights so that:

  1. The new edge weights are nonnegative.
  2. The shortest paths with respect to the new weights are exactly the shortest paths with respect to the old weights.

Such a reweighting enables us to use the more efficient Dijkstra’s algorithm instead of the Bellman-Ford algorithm from each vertex. Of course, we also need to be sure that the all pairs shortest-paths problem is well-defined for the digraph. So, let’s get that out of the way first.

Motivation for a new vertex

If a negative-weight cycle is present in the graph at all, that’s a problem. Running the Bellman-Ford algorithm from an arbitrary vertex only detects the negative-weight cycles reachable from that vertex.

Press + to interact
Running the Bellman-Ford algorithm from v4 doesn’t detect negative-weight cycles that cannot be reached
Running the Bellman-Ford algorithm from v4 doesn’t detect negative-weight cycles that cannot be reached

We can obtain a digraph HH from GG by creating a new vertex ss and adding zero-weight edges from ss to all other vertices of GG. We observe that no new cycle is created in HH (since ss has no incoming edges). As all vertices in HH are reachable from ss, running the Bellman-Ford algorithm—just once—from ss is guaranteed to detect the presence of any negative-weight cycles in HH and, therefore, in GG.

We show a digraph HH constructed in this manner from the digraph above:

Press + to interact
Constructing H from G
Constructing H from G

In the absence of a negative-weight cycle, we can proceed with the idea of reweighting the edges.

The scheme for reweighting an edge

For each edge, we want to transform its weight by adding some quantity to it. We already ruled out in an earlier exercise that adding some fixed constant doesn’t work.

The telescoping effect

Consider this scheme:

  • Assign an arbitrary number to each vertex.
  • For each edge, ee, change its weight by adding to it the difference of the number assigned to its head from the number assigned to its tail.
Press + to interact
Reweighting an edge by adding to its weight the number assigned to its tail and subtracting from it the number assigned to its head
Reweighting an edge by adding to its weight the number assigned to its tail and subtracting from it the number assigned to its head

Consider a path v0,v1,,vk\langle v_0, v_1, \cdots, v_k \rangle with some number ai ...