Content deleted Content added
No edit summary |
Grapesurgeon (talk | contribs) not necessarily strictly computer based, and not just pathfinding but shortest paths |
||
(74 intermediate revisions by 53 users not shown) | |||
Line 1:
{{Short description|Method to find shortest paths}}
{{
{{Infobox Algorithm
|class=[[All-pairs shortest path problem]] (for weighted graphs)
|image=
|caption =
|data=[[Graph (data structure)|Graph]]
|time=<math>O (|V|^2 \log |V| + |V||E|)</math>
|space=
}}
'''Johnson's algorithm''' is a way to find the [[shortest path]]s between [[all-pairs shortest path problem|all pairs of vertices]] in
A similar reweighting technique is also used in a version of the successive shortest paths algorithm for the [[minimum cost flow]] problem due to Edmonds and Karp,<ref>{{citation|first1=J.|last1=Edmonds|first2=Richard M.|last2=Karp|title=Theoretical Improvements in Algorithmic Efficiency for Network Flow Problems|journal=[[Journal of the ACM]]|volume=19|issue=2|pages=248–264|year=1972|doi=10.1145/321694.321699}}.</ref> as well as in [[Suurballe's algorithm]] for finding two disjoint paths of minimum total length between the same two vertices in a graph with non-negative edge weights.<ref>{{citation|first=J. W.|last=Suurballe|title=Disjoint paths in a network|journal=Networks|volume=14|pages=125–145|year=1974|doi=10.1002/net.3230040204|issue=2}}.</ref>
==Algorithm description==▼
Johnson's algorithm consists of the following steps:▼
#First, a new [[Vertex (graph theory)|node]] ''q'' is added to the graph, connected by zero-weight [[Edge (graph theory)|edge]] to each other node.▼
#Second, the [[Bellman-Ford algorithm]] is used, starting from the new vertex ''q'', to find for each vertex ''v'' the least weight ''h''(''v'') of a path from ''q'' to ''v''. If this step detects a negative cycle, the algorithm is terminated.▼
#Next the edges of the original graph are reweighted using the values computed by the Bellman-Ford algorithm: an edge from ''u'' to ''v'', having length ''w(u,v)'', is given the new length ''w(u,v)'' + ''h(u)'' −''h(v)''.▼
▲==Algorithm description==
▲Johnson's algorithm consists of the following steps:<ref name="clrs"/><ref name="black"/>
▲#First, a new [[Vertex (graph theory)|node]]
==Analysis==▼
▲#Second, the [[
The [[time complexity]] of this algorithm, using [[Fibonacci heap]]s in the implementation of Dijkstra's algorithm, is O(''V''<sup>2</sup>log ''V'' + ''VE''): the algorithm uses O(''VE'') time for the Bellman-Ford stage of the algorithm, and O(''V'' log ''V'' + ''E'') for each of ''V'' instantiations of Dijkstra's algorithm. Thus, when the graph is sparse, the total time can be faster than the [[Floyd-Warshall algorithm]], which solves the same problem in time O(''V''<sup>3</sup>).▼
▲#Next the edges of the original graph are reweighted using the values computed by the
#Finally, {{mvar|q}} is removed, and [[Dijkstra's algorithm]] is used to find the shortest paths from each node {{mvar|s}} to every other vertex in the reweighted graph. The distance in the original graph is then computed for each distance {{mvar|D}}({{mvar|u}}, {{mvar|v}}), by adding {{mvar|''h''(''v'') − ''h''(''u'')}} to the distance returned by Dijkstra's algorithm.
==Example==
Line 21 ⟶ 26:
[[File:Johnson's algorithm.svg|540px|center]]
The graph on the left of the illustration has two negative edges, but no negative cycles.
==References==▼
==Correctness==
In the reweighted graph, all paths between a pair {{mvar|s}} and {{mvar|t}} of nodes have the same quantity {{math|''h''(''s'') − ''h''(''t'')}} added to them. The previous statement can be proven as follows: Let {{mvar|p}} be an {{tmath|s-t}} path. Its weight W in the reweighted graph is given by the following expression:
<math display="block">\left(w(s, p_1) + h(s) - h(p_1)\right) + \left(w(p_1, p_2) + h(p_1) - h(p_2)\right) + ... + \left(w(p_n, t) + h(p_n) - h(t)\right).</math>
Every <math>+h(p_i)</math> is cancelled by <math>-h(p_i)</math> in the previous bracketed expression; therefore, we are left with the following expression for ''W'':
<math display="block">\left(w(s, p_1) + w(p_1, p_2) + \cdots + w(p_n, t)\right)+ h(s) - h(t)</math>
[[Category:Graph algorithms]]▼
The bracketed expression is the weight of ''p'' in the original weighting.
Since the reweighting adds the same amount to the weight of every {{tmath|s-t}} path, a path is a shortest path in the original weighting if and only if it is a shortest path after reweighting. The weight of edges that belong to a shortest path from ''q'' to any node is zero, and therefore the lengths of the shortest paths from ''q'' to every node become zero in the reweighted graph; however, they still remain shortest paths. Therefore, there can be no negative edges: if edge ''uv'' had a negative weight after the reweighting, then the zero-length path from ''q'' to ''u'' together with this edge would form a negative-length path from ''q'' to ''v'', contradicting the fact that all vertices have zero distance from ''q''. The non-existence of negative edges ensures the optimality of the paths found by Dijkstra's algorithm. The distances in the original graph may be calculated from the distances calculated by Dijkstra's algorithm in the reweighted graph by reversing the reweighting transformation.<ref name="clrs"/>
== External Links ==▼
▲==Analysis==
▲The [[time complexity]] of this algorithm, using [[Fibonacci heap]]s in the implementation of Dijkstra's algorithm, is <math>O(
▲==References==
{{reflist}}
*[http://www.boost.org/doc/libs/1_40_0/libs/graph/doc/johnson_all_pairs_shortest.html Boost: All Pairs Shortest Paths]
{{Graph traversal algorithms}}
▲[[Category:Graph algorithms]]
[[Category:Search algorithms]]
[[Category:Graph distance]]
|