C++ Boost

johnson_all_pairs_shortest_paths

Graphs: directed or undirected
Properties: distance matrix, distance, weight, color, vertex index
Complexity: O(V E log V) or O(V2 log V + V E)

template <class VertexAndEdgeListGraph, class DistanceMatrix,
          class DistanceMap, class WeightMap, class ColorMap,
          class VertexIndexMap>
bool
johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g, 
  DistanceMatrix& D,
  DistanceMap d, DistanceMap h,
  WeightMap w, ColorMap c, VertexIndexMap id)

This algorithm finds the shortest distance between every pair of vertices in the graph. The algorithm returns false if there is a negative weight cycle in the graph and true otherwise. The distance between each pair of vertices is stored in the distance matrix D. This is one of the more time intensive graph algorithms, having a time complexity of O(V E log V) if a binary heap is used within Dijkstra's or O(V2 log V + V E) if a fibonacci heap is used (the algorithm can be configured to use either). It is a wonder that London taxi-cab drivers are able to instantaneously compute this kind of information in their heads!

Where Defined

boost/graph/johnson_all_pairs_shortest.hpp

Example

Johnson's algorithm for all-pairs shortest paths applied to the example graph from page 568 of the CLR [8]. The resulting distance matrix D[u][v] gives the shortest path from vertex u to v.

  typedef adjacency_list<vecS,vecS,directedS,no_property,
    property<edge_weight_t,int> > Graph;
  const int V = 6;

  typedef std::pair<int,int> Edge;
  Edge edge_array[] =
    { Edge(0,1), Edge(0,2), Edge(0,3), Edge(0,4), Edge(0,5),
      Edge(1, 2), Edge(1,5), Edge(1,3),
      Edge(2, 4), Edge(2,5),
      Edge(3, 2), 
      Edge(4, 3), Edge(4,1),
      Edge(5, 4)
    };
  const int E = sizeof(edge_array)/sizeof(Edge);

  Graph g(V, edge_array, edge_array + E);

  property_map<Graph,edge_weight_t>::type w = get(edge_weight, g);

  int weights[] = { 0, 0, 0, 0, 0,
                    3, -4, 8,
                    1, 7,
                    4,
                    -5, 2,
                    6 };
  int* wp = weights;
  
  Graph::edge_iterator e,e_end;
  for (boost::tie(e,e_end) = edges(g); e != e_end; ++e)
    w[*e] = *wp++;

  std::vector<int> d(V, std::numeric_limits<int>::max());
  std::vector<int> h(V);
  std::vector<default_color_type> c(V);

  int D[V][V];

  johnson_all_pairs_shortest_paths
    (g, D, d.begin(), h.begin(), w, c.begin(), get(vertex_index, g));

  // output matrix D ...
The output is:
            0       1       2       3       4       5       
  0 ->      0       0       -1      -5      0       -4      
  1 ->      inf     0       1       -3      2       -4      
  2 ->      inf     3       0       -4      1       -1      
  3 ->      inf     7       4       0       5       3       
  4 ->      inf     2       -1      -5      0       -2      
  5 ->      inf     8       5       1       6       0


Copyright © 2000 Jeremy Siek, Univ.of Notre Dame (jsiek@lsc.nd.edu)