# Johnson’s Algorithm

April 30, 2023

Johnson’s Algorithm is a graph theory algorithm that finds the shortest paths between pairs of vertices in a weighted, directed graph with or without negative edge weights. The algorithm operates by first transforming the original graph into a new graph without negative edge weights, then using Dijkstra’s algorithm to find the shortest paths between every pair of vertices in the transformed graph. Finally, the algorithm reverses the transformation to obtain the shortest paths in the original graph.

The algorithm has applications in a variety of fields, including transportation network analysis, telecommunications network routing, and computer network routing.

## Brief History and Development

Johnson’s Algorithm was first described by Donald B. Johnson in 1977. The algorithm was motivated by the desire to find a more efficient algorithm for the all-pairs shortest path problem than the Floyd-Warshall algorithm, which has a worst-case time complexity of O(n^3). Johnson’s Algorithm has a worst-case time complexity of O(n^2 log n) and is more efficient than the Floyd-Warshall algorithm for sparse graphs.

## Key Concepts and Principles

The main idea behind Johnson’s Algorithm is to reweight the edges of the original graph in such a way that they become non-negative, while preserving the shortest paths. This is achieved by adding a new vertex to the graph and connecting it to every other vertex with a zero-weight edge. The edges of the resulting graph are then reweighted using the Bellman-Ford algorithm, which finds the shortest paths from the new vertex to every other vertex in the graph.

The reweighting step ensures that every edge in the transformed graph has a non-negative weight. The shortest paths in the transformed graph can then be found using Dijkstra’s algorithm, which has a worst-case time complexity of O(m log n), where m is the number of edges and n is the number of vertices in the graph.

Finally, the algorithm reverses the transformation to obtain the shortest paths in the original graph. This is done by subtracting the zero-weight edge from each path in the transformed graph.

## Pseudocode and Implementation Details

The following pseudocode describes Johnson’s Algorithm:

``````Johnson(G):
n = number of vertices in G
add a new vertex s to G and connect it to every other vertex with a zero-weight edge
run Bellman-Ford algorithm with s as the source vertex to obtain h(v), the shortest path from s to v for every vertex v in G
remove the new vertex s and its corresponding edges from G
for each edge (u, v) in G:
w'(u, v) = w(u, v) + h(u) - h(v)
for each vertex v in G:
run Dijkstra's algorithm with v as the source vertex on the reweighted graph to obtain d(v, w), the shortest path from v to w for every vertex w in G
for each vertex w in G:
d'(v, w) = d(v, w) - h(v) + h(w)
return the matrix of distances d'(v, w)
``````

The implementation of Johnson’s Algorithm requires the implementation of the Bellman-Ford and Dijkstra’s algorithms, as well as the data structures necessary to represent a graph and to store the shortest paths.

## Examples and Use Cases

Johnson’s Algorithm can be used to find the shortest paths between pairs of vertices in a variety of graphs, including road networks, airline networks, and computer networks. For example, suppose we have the following graph:

``````     5   1
A -----> B
|\      /|\
| \2   / | \
|  \  /  |  \3
|   \/   |   \
|   /\   |   /
|  / 1\  |  / 4
| /    \ | /
V/      \V/
C -----> D
6   2
``````

where the numbers next to the edges are the weights. We can apply Johnson’s Algorithm to this graph to find the shortest paths between every pair of vertices. The resulting matrix of distances is:

``````   A  B  C  D
A  0  5  7  9
B  -  0  2  4
C  -  -  0  2
D  -  -  -  0
``````

This matrix tells us that the shortest path from A to D has length 9, and that the shortest path from C to B has length 2.