<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://70.231.62.181/index.php?action=history&amp;feed=atom&amp;title=Parallel_single-source_shortest_path_algorithm</id>
	<title>Parallel single-source shortest path algorithm - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://70.231.62.181/index.php?action=history&amp;feed=atom&amp;title=Parallel_single-source_shortest_path_algorithm"/>
	<link rel="alternate" type="text/html" href="http://70.231.62.181/index.php?title=Parallel_single-source_shortest_path_algorithm&amp;action=history"/>
	<updated>2026-06-19T11:03:57Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>http://70.231.62.181/index.php?title=Parallel_single-source_shortest_path_algorithm&amp;diff=24510711&amp;oldid=prev</id>
		<title>imported&gt;ChaosTheoryEnthusiast: /* growthexperiments-addlink-summary-summary:0|3|0 */</title>
		<link rel="alternate" type="text/html" href="http://70.231.62.181/index.php?title=Parallel_single-source_shortest_path_algorithm&amp;diff=24510711&amp;oldid=prev"/>
		<updated>2025-10-04T17:30:59Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;growthexperiments-addlink-summary-summary:0|3|0&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Short description|Computational problem of graph theory}}&lt;br /&gt;
A central problem in algorithmic [[graph theory]] is the [[shortest path problem]]. One of the generalizations of the shortest path problem is known as the &amp;#039;&amp;#039;&amp;#039;single-source-shortest-paths (SSSP)&amp;#039;&amp;#039;&amp;#039; problem, which consists of finding the shortest paths from a source vertex &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to all other vertices in the graph. There are classical [[sequential algorithm]]s which solve this problem, such as [[Dijkstra&amp;#039;s algorithm]]. In this article, however, we present two [[parallel algorithm]]s solving this problem.&lt;br /&gt;
&lt;br /&gt;
Another variation of the problem is the all-pairs-shortest-paths (APSP) problem, which also has parallel approaches: [[Parallel all-pairs shortest path algorithm]].&lt;br /&gt;
&lt;br /&gt;
== Problem definition ==&lt;br /&gt;
Let &amp;lt;math&amp;gt;G=(V,E)&amp;lt;/math&amp;gt; be a directed graph with &amp;lt;math&amp;gt;|V|=n&amp;lt;/math&amp;gt; nodes and &amp;lt;math&amp;gt;|E|=m&amp;lt;/math&amp;gt; edges. Let &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; be a distinguished vertex (called &amp;quot;source&amp;quot;) and &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; be a function assigning a non-negative real-valued weight to each edge. The goal of the single-source-shortest-paths problem is to compute, for every vertex &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; reachable from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, the weight of a minimum-weight path from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;, denoted by &amp;lt;math&amp;gt;\operatorname{dist}(s,v)&amp;lt;/math&amp;gt; and abbreviated &amp;lt;math&amp;gt;\operatorname{dist}(v)&amp;lt;/math&amp;gt;. The weight of a path is the sum of the weights of its edges. We set &amp;lt;math&amp;gt;\operatorname{dist}(u,v):=\infty&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; is unreachable from &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;.&amp;lt;ref name=&amp;quot;:0&amp;quot;&amp;gt;{{Cite journal|last1=Meyer|first1=U.|last2=Sanders|first2=P.|date=2003-10-01|title=Δ-stepping: a parallelizable shortest path algorithm|journal=Journal of Algorithms|series=1998 European Symposium on Algorithms|volume=49|issue=1|pages=114–152|doi=10.1016/S0196-6774(03)00076-2|issn=0196-6774|doi-access=free}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential shortest path algorithms commonly apply iterative labeling methods based on maintaining a tentative distance for all nodes; &amp;lt;math&amp;gt;\operatorname{tent}(v)&amp;lt;/math&amp;gt; is always &amp;lt;math&amp;gt;\infty&amp;lt;/math&amp;gt; or the weight of some path from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; and hence an upper bound on &amp;lt;math&amp;gt;\operatorname{dist}(v)&amp;lt;/math&amp;gt;. Tentative distances are improved by performing edge relaxations, i.e., for an edge &amp;lt;math&amp;gt;(v,w)\in E&amp;lt;/math&amp;gt;  the algorithm sets &amp;lt;math&amp;gt;\operatorname{tent}(w):=\min\{\operatorname{tent}(w), \operatorname{tent}(v)+c(v,w)\}&amp;lt;/math&amp;gt;.&amp;lt;ref name=&amp;quot;:0&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For all parallel algorithms we will assume a [[Parallel random-access machine|PRAM]] model with concurrent reads and concurrent writes.&lt;br /&gt;
&lt;br /&gt;
== Delta stepping algorithm ==&lt;br /&gt;
The delta stepping algorithm is a label-correcting algorithm, which means the tentative distance of a vertex can be corrected several times via edge relaxations until the last step of the algorithm, when all tentative distances are fixed.&lt;br /&gt;
&lt;br /&gt;
The algorithm maintains eligible nodes with tentative distances in an array of buckets each of which represents a distance range of size &amp;lt;math&amp;gt;\Delta&amp;lt;/math&amp;gt;. During each phase, the algorithm removes all nodes of the first nonempty bucket and relaxes all outgoing edges of weight at most &amp;lt;math&amp;gt;\Delta&amp;lt;/math&amp;gt;. Edges of a higher weight are only relaxed after their respective starting nodes are surely settled.&amp;lt;ref name=&amp;quot;:0&amp;quot; /&amp;gt; The parameter  &amp;lt;math&amp;gt;\Delta&amp;lt;/math&amp;gt; is a positive real number that is also called the &amp;quot;step width&amp;quot; or &amp;quot;bucket width&amp;quot;.&amp;lt;ref name=&amp;quot;:0&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parallelism is obtained by concurrently removing all nodes of the first nonempty bucket and relaxing their outgoing light edges in a single phase. If a node &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; has been removed from the current bucket &amp;lt;math&amp;gt;B[i]&amp;lt;/math&amp;gt; with non-final distance value then, in some subsequent phase, &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; will eventually be reinserted into &amp;lt;math&amp;gt;B[i]&amp;lt;/math&amp;gt; , and the outgoing light edges of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;  will be re-relaxed. The remaining heavy edges emanating from all nodes that have been removed from &amp;lt;math&amp;gt;B[i]&amp;lt;/math&amp;gt; so far are relaxed once and for all when &amp;lt;math&amp;gt;B[i]&amp;lt;/math&amp;gt; finally remains empty. Subsequently, the algorithm searches for the next nonempty bucket and proceeds as described above.&amp;lt;ref name=&amp;quot;:0&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The maximum shortest path weight for the source node &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is defined as &amp;lt;math&amp;gt;L(s):=\max\{\operatorname{dist}(s,v) : \operatorname{dist}(s,v)&amp;lt;\infty\}&amp;lt;/math&amp;gt;, abbreviated &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt;.&amp;lt;ref name=&amp;quot;:0&amp;quot; /&amp;gt; Also, the size of a path is defined to be the number of edges on the path.&lt;br /&gt;
&lt;br /&gt;
We distinguish light edges from heavy edges, where light edges have weight at most &amp;lt;math&amp;gt;\Delta&amp;lt;/math&amp;gt;  and heavy edges have weight bigger than &amp;lt;math&amp;gt;\Delta&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Following is the delta stepping algorithm in pseudocode:&lt;br /&gt;
 1  &amp;#039;&amp;#039;&amp;#039;foreach&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; &amp;#039;&amp;#039;&amp;#039;do&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;\operatorname{tent}(v):=\infty&amp;lt;/math&amp;gt;&lt;br /&gt;
 2  &amp;lt;math&amp;gt;relax(s, 0)&amp;lt;/math&amp;gt;;                                                    (*Insert source node with distance 0*)&lt;br /&gt;
 3  &amp;#039;&amp;#039;&amp;#039;while&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;\lnot isEmpty(B)&amp;lt;/math&amp;gt; &amp;#039;&amp;#039;&amp;#039;do&amp;#039;&amp;#039;&amp;#039;                           (*A phase: Some queued nodes left (a)*)&lt;br /&gt;
 4      &amp;lt;math&amp;gt;i:=\min\{j\geq 0: B[j]\neq \emptyset\}&amp;lt;/math&amp;gt;                      (*Smallest nonempty bucket (b)*)&lt;br /&gt;
 5      &amp;lt;math&amp;gt;R:=\emptyset&amp;lt;/math&amp;gt;                                                (*No nodes deleted for bucket B[i] yet*)&lt;br /&gt;
 6      &amp;#039;&amp;#039;&amp;#039;while&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;B[i]\neq \emptyset&amp;lt;/math&amp;gt; &amp;#039;&amp;#039;&amp;#039;do&amp;#039;&amp;#039;&amp;#039;                     (*New phase (c)*)&lt;br /&gt;
 7          &amp;lt;math&amp;gt;Req:=findRequests(B[i],light)&amp;lt;/math&amp;gt;                           (*Create requests for light edges (d)*)&lt;br /&gt;
 8          &amp;lt;math&amp;gt;R:=R\cup B[i]&amp;lt;/math&amp;gt;                                           (*Remember deleted nodes (e)*)&lt;br /&gt;
 9          &amp;lt;math&amp;gt;B[i]:=\emptyset&amp;lt;/math&amp;gt;                                         (*Current bucket empty*)&lt;br /&gt;
 10         &amp;lt;math&amp;gt;relaxRequests(Req)&amp;lt;/math&amp;gt;                                      (*Do relaxations, nodes may (re)enter B[i] (f)*)&lt;br /&gt;
 11     &amp;lt;math&amp;gt;Req:=findRequests(R,heavy)&amp;lt;/math&amp;gt;                                  (*Create requests for heavy edges (g)*)&lt;br /&gt;
 12     &amp;lt;math&amp;gt;relaxRequests(Req)&amp;lt;/math&amp;gt;                                          (*Relaxations will not refill B[i] (h)*)&lt;br /&gt;
 13&lt;br /&gt;
 14 &amp;#039;&amp;#039;&amp;#039;function&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;findRequests(V&amp;#039;,kind:\{\text{light}, \text{heavy}\})&amp;lt;/math&amp;gt;:set of Request&lt;br /&gt;
 15     &amp;#039;&amp;#039;&amp;#039;return&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;\{(w, \operatorname{tent}(v)+c(v,w)): v\in V&amp;#039; \land (v,w) \in E_\text{kind}\}&amp;lt;/math&amp;gt;&lt;br /&gt;
 16&lt;br /&gt;
 17 &amp;#039;&amp;#039;&amp;#039;procedure&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;relaxRequests(Req)&amp;lt;/math&amp;gt;&lt;br /&gt;
 18     &amp;#039;&amp;#039;&amp;#039;foreach&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;(w, x)\in Req&amp;lt;/math&amp;gt; &amp;#039;&amp;#039;&amp;#039;do&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;relax(w,x)&amp;lt;/math&amp;gt;&lt;br /&gt;
 19&lt;br /&gt;
 20 &amp;#039;&amp;#039;&amp;#039;procedure&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;relax(w,x)&amp;lt;/math&amp;gt;                                             (*Insert or move w in B if &amp;lt;math&amp;gt;x&amp;lt;\operatorname{tent}(w)&amp;lt;/math&amp;gt;*)&lt;br /&gt;
 21     &amp;#039;&amp;#039;&amp;#039;if&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;x &amp;lt; \operatorname{tent}(w)&amp;lt;/math&amp;gt; &amp;#039;&amp;#039;&amp;#039;then&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 22         &amp;lt;math&amp;gt;B[\lfloor \operatorname{tent}(w)/\Delta\rfloor]:=B[\lfloor \operatorname{tent}(w)/\Delta\rfloor]\setminus \{w\}      &amp;lt;/math&amp;gt;                      (*If in, remove from old bucket*)&lt;br /&gt;
 23         &amp;lt;math&amp;gt;B[\lfloor x/\Delta\rfloor]:=B[\lfloor x/\Delta\rfloor]\cup \{w\}      &amp;lt;/math&amp;gt;                                 (*Insert into new bucket*)&lt;br /&gt;
 24         &amp;lt;math&amp;gt;\operatorname{tent}(w):=x      &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
[[File:Delta_stepping_example_graph.png|alt=|thumb|300x300px|Example graph]]&lt;br /&gt;
Following is a step by step description of the algorithm execution for a small example graph. The source vertex is the vertex A and &amp;lt;math&amp;gt;\Delta&amp;lt;/math&amp;gt; is equal to 3.&lt;br /&gt;
&lt;br /&gt;
At the beginning of the algorithm, all vertices except for the source vertex A have infinite tentative distances.&lt;br /&gt;
&lt;br /&gt;
Bucket &amp;lt;math&amp;gt;B[0]&amp;lt;/math&amp;gt; has range &amp;lt;math&amp;gt;[0,2]&amp;lt;/math&amp;gt;, bucket &amp;lt;math&amp;gt;B[1]&amp;lt;/math&amp;gt; has range &amp;lt;math&amp;gt;[3,5]&amp;lt;/math&amp;gt; and bucket &amp;lt;math&amp;gt;B[2]&amp;lt;/math&amp;gt; has range &amp;lt;math&amp;gt;[6,8]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The bucket &amp;lt;math&amp;gt;B[0]&amp;lt;/math&amp;gt; contains the vertex A. All other buckets are empty.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Node&lt;br /&gt;
!A&lt;br /&gt;
!B&lt;br /&gt;
!C&lt;br /&gt;
!D&lt;br /&gt;
!E&lt;br /&gt;
!F&lt;br /&gt;
!G&lt;br /&gt;
|-&lt;br /&gt;
|Tentative distance&lt;br /&gt;
|0&lt;br /&gt;
|&amp;lt;math&amp;gt;\infty&amp;lt;/math&amp;gt;&lt;br /&gt;
|&amp;lt;math&amp;gt;\infty&amp;lt;/math&amp;gt;&lt;br /&gt;
|&amp;lt;math&amp;gt;\infty&amp;lt;/math&amp;gt;&lt;br /&gt;
|&amp;lt;math&amp;gt;\infty&amp;lt;/math&amp;gt;&lt;br /&gt;
|&amp;lt;math&amp;gt;\infty&amp;lt;/math&amp;gt;&lt;br /&gt;
|&amp;lt;math&amp;gt;\infty&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
The algorithm relaxes all light edges incident to &amp;lt;math&amp;gt;B[0]&amp;lt;/math&amp;gt;, which are the edges connecting A to B, G and E.&lt;br /&gt;
&lt;br /&gt;
The vertices B,G and E are inserted into bucket &amp;lt;math&amp;gt;B[1]&amp;lt;/math&amp;gt;. Since &amp;lt;math&amp;gt;B[0]&amp;lt;/math&amp;gt; is still empty, the heavy edge connecting A to D is also relaxed.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Node&lt;br /&gt;
!A&lt;br /&gt;
!B&lt;br /&gt;
!C&lt;br /&gt;
!D&lt;br /&gt;
!E&lt;br /&gt;
!F&lt;br /&gt;
!G&lt;br /&gt;
|-&lt;br /&gt;
|Tentative distance&lt;br /&gt;
|0&lt;br /&gt;
|3&lt;br /&gt;
|&amp;lt;math&amp;gt;\infty&amp;lt;/math&amp;gt;&lt;br /&gt;
|5&lt;br /&gt;
|3&lt;br /&gt;
|&amp;lt;math&amp;gt;\infty&amp;lt;/math&amp;gt;&lt;br /&gt;
|3&lt;br /&gt;
|}&lt;br /&gt;
Now the light edges incident to &amp;lt;math&amp;gt;B[1]&amp;lt;/math&amp;gt; are relaxed. The vertex C is inserted into bucket &amp;lt;math&amp;gt;B[2]&amp;lt;/math&amp;gt;. Since now &amp;lt;math&amp;gt;B[1]&amp;lt;/math&amp;gt; is empty, the heavy edge connecting E to F can be relaxed.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Node&lt;br /&gt;
!A&lt;br /&gt;
!B&lt;br /&gt;
!C&lt;br /&gt;
!D&lt;br /&gt;
!E&lt;br /&gt;
!F&lt;br /&gt;
!G&lt;br /&gt;
|-&lt;br /&gt;
|Tentative distance&lt;br /&gt;
|0&lt;br /&gt;
|3&lt;br /&gt;
|6&lt;br /&gt;
|5&lt;br /&gt;
|3&lt;br /&gt;
|8&lt;br /&gt;
|3&lt;br /&gt;
|}&lt;br /&gt;
On the next step, the bucket &amp;lt;math&amp;gt;B[2]&amp;lt;/math&amp;gt; is examined, but doesn&amp;#039;t lead to any modifications to the tentative distances.&lt;br /&gt;
&lt;br /&gt;
The algorithm terminates.&lt;br /&gt;
&lt;br /&gt;
=== Runtime ===&lt;br /&gt;
As mentioned earlier, &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; is the maximum shortest path weight.&lt;br /&gt;
&lt;br /&gt;
Let us call a path with total weight at most &amp;lt;math&amp;gt;\Delta&amp;lt;/math&amp;gt; and without edge repetitions a &amp;lt;math&amp;gt;\Delta&amp;lt;/math&amp;gt;-path.&lt;br /&gt;
&lt;br /&gt;
Let &amp;lt;math&amp;gt;C_\Delta&amp;lt;/math&amp;gt; denote the set of all node pairs &amp;lt;math&amp;gt;\langle u,v \rangle&amp;lt;/math&amp;gt; connected by some &amp;lt;math&amp;gt;\Delta&amp;lt;/math&amp;gt;-path &amp;lt;math&amp;gt;(u,\dots, v)&amp;lt;/math&amp;gt;  and let &amp;lt;math&amp;gt;n_\Delta:=|C_{\Delta}|&amp;lt;/math&amp;gt;. Similarly, define &amp;lt;math&amp;gt;C_{\Delta+}&amp;lt;/math&amp;gt; as the set of triples &amp;lt;math&amp;gt;\langle u,v&amp;#039;,v \rangle&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;\langle u,v&amp;#039; \rangle \in C_\Delta&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;(v&amp;#039;,v)&amp;lt;/math&amp;gt; is a light edge and let &amp;lt;math&amp;gt;m_\Delta:=|C_{\Delta+}|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The sequential delta-stepping algorithm needs at most&amp;lt;math&amp;gt;\mathcal{O} (n+m + n_\Delta + m_\Delta + L/\Delta)&amp;lt;/math&amp;gt; operations. A simple parallelization runs in time &amp;lt;math&amp;gt;\mathcal{O} \left(\frac{L}{\Delta}\cdot d\ell_\Delta \log n\right)&amp;lt;/math&amp;gt; .&amp;lt;ref name=&amp;quot;:0&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If we take &amp;lt;math&amp;gt;\Delta = \Theta(1/d)&amp;lt;/math&amp;gt; for graphs with maximum degree &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; and random edge weights uniformly distributed in &amp;lt;math&amp;gt;[0,1]&amp;lt;/math&amp;gt;, the sequential version of the algorithm needs &amp;lt;math&amp;gt;\mathcal{O}(n+m+dL)&amp;lt;/math&amp;gt; total average-case time and a simple parallelization takes on average &amp;lt;math&amp;gt;\mathcal{O}(d^2 L \log^2n)&amp;lt;/math&amp;gt;.&amp;lt;ref name=&amp;quot;:0&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Graph 500 ===&lt;br /&gt;
The third computational kernel of the [[Graph500|Graph 500]] benchmark runs a single-source shortest path computation.&amp;lt;ref&amp;gt;{{Cite web|url=https://graph500.org/?page_id=12#sec-7|title=Graph 500|last=|first=|date=9 March 2017|website=|archive-url=|archive-date=|access-date=}}&amp;lt;/ref&amp;gt; The reference implementation of the Graph 500 benchmark uses the delta stepping algorithm for this computation.&lt;br /&gt;
&lt;br /&gt;
== Radius stepping algorithm ==&lt;br /&gt;
For the radius stepping algorithm, we must assume that our graph &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; is undirected.&lt;br /&gt;
&lt;br /&gt;
The input to the algorithm is a weighted, undirected graph, a source vertex, and a target radius value for every vertex, given as a function &amp;lt;math&amp;gt;r : V \rightarrow \mathbb{R}_+&amp;lt;/math&amp;gt;.&amp;lt;ref name=&amp;quot;:1&amp;quot;&amp;gt;{{Cite book|last1=Blelloch|first1=Guy E.|last2=Gu|first2=Yan|last3=Sun|first3=Yihan|last4=Tangwongsan|first4=Kanat|title=Proceedings of the 28th ACM Symposium on Parallelism in Algorithms and Architectures |chapter=Parallel Shortest Paths Using Radius Stepping |date=2016|pages=443–454|location=New York, New York, USA|publisher=ACM Press|doi=10.1145/2935764.2935765|isbn=978-1-4503-4210-0|doi-access=free}}&amp;lt;/ref&amp;gt; The algorithm visits vertices in increasing distance from the source &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.  On each step &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;, the Radius-Stepping increments the radius centered at &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; from &amp;lt;math&amp;gt;d_{i-1}&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;d_i&amp;lt;/math&amp;gt; , and settles all vertices &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; in the annulus &amp;lt;math&amp;gt;d_{i-1}&amp;lt;d(s,v)\leq d_i&amp;lt;/math&amp;gt;.&amp;lt;ref name=&amp;quot;:1&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Following is the radius stepping algorithm in pseudocode:&lt;br /&gt;
     &amp;#039;&amp;#039;&amp;#039;Input&amp;#039;&amp;#039;&amp;#039;: A graph &amp;lt;math&amp;gt;G=(V,E,w)&amp;lt;/math&amp;gt;, vertex radii &amp;lt;math&amp;gt;r(\cdot)&amp;lt;/math&amp;gt;, and a source node &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
     &amp;#039;&amp;#039;&amp;#039;Output&amp;#039;&amp;#039;&amp;#039;: The graph distances &amp;lt;math&amp;gt;\delta(\cdot)&amp;lt;/math&amp;gt; from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
  1  &amp;lt;math&amp;gt;\delta(\cdot)\leftarrow +\infty&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\delta(s)\leftarrow 0&amp;lt;/math&amp;gt;&lt;br /&gt;
  2  &amp;#039;&amp;#039;&amp;#039;foreach&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;v \in N(s)&amp;lt;/math&amp;gt; &amp;#039;&amp;#039;&amp;#039;do&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;\delta(v)\leftarrow w(s,v)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_0\leftarrow \{s\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
  3  &amp;#039;&amp;#039;&amp;#039;while&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;|S_{i-1}|&amp;lt;|V|&amp;lt;/math&amp;gt; &amp;#039;&amp;#039;&amp;#039;do&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
  4      &amp;lt;math&amp;gt;d_i\leftarrow \min_{v\in V\setminus S_{i-1}}\{\delta(v) + r(v)\}&amp;lt;/math&amp;gt;&lt;br /&gt;
  5      &amp;#039;&amp;#039;&amp;#039;repeat&amp;#039;&amp;#039;&amp;#039;   &lt;br /&gt;
  6          &amp;#039;&amp;#039;&amp;#039;foreach&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;u \in V\setminus S_{i-1}&amp;lt;/math&amp;gt; s.t &amp;lt;math&amp;gt;\delta(u) \leq d_i&amp;lt;/math&amp;gt; &amp;#039;&amp;#039;&amp;#039;do&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
  7              &amp;#039;&amp;#039;&amp;#039;foreach&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;v \in N(u)\setminus S_{i-1}&amp;lt;/math&amp;gt; &amp;#039;&amp;#039;&amp;#039;do&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
  8                  &amp;lt;math&amp;gt;\delta(v) \leftarrow \min\{\delta(v), \delta(u)+w(u,v)\}&amp;lt;/math&amp;gt;&lt;br /&gt;
  9      &amp;#039;&amp;#039;&amp;#039;until&amp;#039;&amp;#039;&amp;#039; no &amp;lt;math&amp;gt;\delta(v)\leq d_i&amp;lt;/math&amp;gt; was updated&lt;br /&gt;
  10     &amp;#039;&amp;#039;&amp;lt;math&amp;gt;S_i=\{v\;|\;\delta(v)\leq d_i\}&amp;lt;/math&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
  11     &amp;lt;math&amp;gt;i=i+1&amp;lt;/math&amp;gt;&lt;br /&gt;
  12 &amp;#039;&amp;#039;&amp;#039;return&amp;#039;&amp;#039;&amp;#039; &amp;lt;math&amp;gt;\delta(\cdot)&amp;lt;/math&amp;gt;&lt;br /&gt;
For all &amp;lt;math&amp;gt;S\subseteq V&amp;lt;/math&amp;gt;, define &amp;lt;math&amp;gt;N(S)=\bigcup_{u\in S}\{v\in V\mid d(u,v)\in E\}&amp;lt;/math&amp;gt; to be the &amp;#039;&amp;#039;&amp;#039;neighbor set&amp;#039;&amp;#039;&amp;#039; of S. During the execution of standard [[breadth-first search]] or [[Dijkstra&amp;#039;s algorithm]], the &amp;#039;&amp;#039;&amp;#039;frontier&amp;#039;&amp;#039;&amp;#039; is the neighbor set of all visited vertices.&amp;lt;ref name=&amp;quot;:1&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the Radius-Stepping algorithm, a new round distance &amp;lt;math&amp;gt;d_i&amp;lt;/math&amp;gt; is decided on each round with the goal of bounding the number of substeps. The algorithm takes a radius &amp;lt;math&amp;gt;r(v)&amp;lt;/math&amp;gt; for each vertex and selects a &amp;lt;math&amp;gt;d_i&amp;lt;/math&amp;gt; on step &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; by taking the minimum &amp;lt;math&amp;gt;\delta(v) + r(v)&amp;lt;/math&amp;gt; over all &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; in the frontier (Line 4).&lt;br /&gt;
&lt;br /&gt;
Lines 5-9 then run the [[Bellman–Ford algorithm|Bellman-Ford]] substeps until all vertices with radius less than &amp;lt;math&amp;gt;d_i&amp;lt;/math&amp;gt; are settled. Vertices within &amp;lt;math&amp;gt;d_i&lt;br /&gt;
&amp;lt;/math&amp;gt; are then added to the visited set &amp;lt;math&amp;gt;S_i&lt;br /&gt;
&amp;lt;/math&amp;gt;.&amp;lt;ref name=&amp;quot;:1&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
[[File:Delta_stepping_example_graph.png|alt=|thumb|300x300px|Example graph]]&lt;br /&gt;
Following is a step by step description of the algorithm execution for a small example graph. The source vertex is the vertex A and the radius of every vertex is equal to 1.&lt;br /&gt;
&lt;br /&gt;
At the beginning of the algorithm, all vertices except for the source vertex A have infinite tentative distances, denoted by &amp;lt;math&amp;gt;\delta&amp;lt;/math&amp;gt; in the pseudocode.&lt;br /&gt;
&lt;br /&gt;
All neighbors of A are relaxed and &amp;lt;math&amp;gt;S_0=\{A\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Node&lt;br /&gt;
!A&lt;br /&gt;
!B&lt;br /&gt;
!C&lt;br /&gt;
!D&lt;br /&gt;
!E&lt;br /&gt;
!F&lt;br /&gt;
!G&lt;br /&gt;
|-&lt;br /&gt;
|Tentative distance&lt;br /&gt;
|0&lt;br /&gt;
|3&lt;br /&gt;
|&amp;lt;math&amp;gt;\infty&amp;lt;/math&amp;gt;&lt;br /&gt;
|5&lt;br /&gt;
|3&lt;br /&gt;
|&amp;lt;math&amp;gt;\infty&amp;lt;/math&amp;gt;&lt;br /&gt;
|3&lt;br /&gt;
|}&lt;br /&gt;
The variable &amp;lt;math&amp;gt;d_1&amp;lt;/math&amp;gt; is chosen to be equal to 4 and the neighbors of the vertices B, E and G are relaxed. &amp;lt;math&amp;gt;S_1=\{A,B,E,G\}&amp;lt;/math&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Node&lt;br /&gt;
!A&lt;br /&gt;
!B&lt;br /&gt;
!C&lt;br /&gt;
!D&lt;br /&gt;
!E&lt;br /&gt;
!F&lt;br /&gt;
!G&lt;br /&gt;
|-&lt;br /&gt;
|Tentative distance&lt;br /&gt;
|0&lt;br /&gt;
|3&lt;br /&gt;
|6&lt;br /&gt;
|5&lt;br /&gt;
|3&lt;br /&gt;
|8&lt;br /&gt;
|3&lt;br /&gt;
|}&lt;br /&gt;
The variable &amp;lt;math&amp;gt;d_2&amp;lt;/math&amp;gt; is chosen to be equal to 6 and no values are changed. &amp;lt;math&amp;gt;S_2=\{A,B,C,D,E,G\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The variable &amp;lt;math&amp;gt;d_3&amp;lt;/math&amp;gt; is chosen to be equal to 9 and no values are changed. &amp;lt;math&amp;gt;S_3=\{A,B,C,D,E,F, G\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The algorithm terminates.&lt;br /&gt;
&lt;br /&gt;
=== Runtime ===&lt;br /&gt;
After a preprocessing phase, the radius stepping algorithm can solve the SSSP problem in &amp;lt;math&amp;gt;\mathcal{O}(m\log n)&amp;lt;/math&amp;gt; work and  &amp;lt;math&amp;gt;\mathcal{O}(\frac{n}{p}\log n\log pL)&amp;lt;/math&amp;gt; depth, for &amp;lt;math&amp;gt;p\leq \sqrt{n}&amp;lt;/math&amp;gt;. In addition, the preprocessing phase takes  &amp;lt;math&amp;gt;\mathcal{O}(m\log n + np^2)&amp;lt;/math&amp;gt; work and  &amp;lt;math&amp;gt;\mathcal{O}(p^2)&amp;lt;/math&amp;gt; depth, or &amp;lt;math&amp;gt;\mathcal{O}(m\log n + np^2\log n)&amp;lt;/math&amp;gt; work and  &amp;lt;math&amp;gt;\mathcal{O}(p\log p)&amp;lt;/math&amp;gt; depth.&amp;lt;ref name=&amp;quot;:1&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Reflist}}&lt;br /&gt;
&amp;lt;references responsive=&amp;quot;1&amp;quot;&amp;gt;&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Graph algorithms]]&lt;/div&gt;</summary>
		<author><name>imported&gt;ChaosTheoryEnthusiast</name></author>
	</entry>
</feed>