1
1
import PriorityQueue from '../../../data-structures/priority-queue/PriorityQueue' ;
2
2
3
3
/**
4
- * @param {Graph } graph
5
- * @param {GraphVertex } startVertex
4
+ * @typedef {Object } ShortestPaths
5
+ * @property {Object } distances - shortest distances to all vertices
6
+ * @property {Object } previousVertices - shortest paths to all vertices.
7
+ */
8
+
9
+ /**
10
+ * Implementation of Dijkstra algorithm of finding the shortest paths to graph nodes.
11
+ * @param {Graph } graph - graph we're going to traverse.
12
+ * @param {GraphVertex } startVertex - traversal start vertex.
13
+ * @return {ShortestPaths }
6
14
*/
7
15
export default function dijkstra ( graph , startVertex ) {
16
+ // Init helper variables that we will need for Dijkstra algorithm.
8
17
const distances = { } ;
9
18
const visitedVertices = { } ;
10
19
const previousVertices = { } ;
11
20
const queue = new PriorityQueue ( ) ;
12
21
13
22
// Init all distances with infinity assuming that currently we can't reach
14
- // any of the vertices except start one.
23
+ // any of the vertices except the start one.
15
24
graph . getAllVertices ( ) . forEach ( ( vertex ) => {
16
25
distances [ vertex . getKey ( ) ] = Infinity ;
17
26
previousVertices [ vertex . getKey ( ) ] = null ;
18
27
} ) ;
28
+
29
+ // We are already at the startVertex so the distance to it is zero.
19
30
distances [ startVertex . getKey ( ) ] = 0 ;
20
31
21
32
// Init vertices queue.
22
33
queue . add ( startVertex , distances [ startVertex . getKey ( ) ] ) ;
23
34
35
+ // Iterate over the priority queue of vertices until it is empty.
24
36
while ( ! queue . isEmpty ( ) ) {
37
+ // Fetch next closest vertex.
25
38
const currentVertex = queue . poll ( ) ;
26
39
27
- graph . getNeighbors ( currentVertex ) . forEach ( ( neighbor ) => {
40
+ // Iterate over every unvisited neighbor of the current vertex.
41
+ currentVertex . getNeighbors ( ) . forEach ( ( neighbor ) => {
28
42
// Don't visit already visited vertices.
29
43
if ( ! visitedVertices [ neighbor . getKey ( ) ] ) {
30
44
// Update distances to every neighbor from current vertex.
@@ -33,15 +47,16 @@ export default function dijkstra(graph, startVertex) {
33
47
const existingDistanceToNeighbor = distances [ neighbor . getKey ( ) ] ;
34
48
const distanceToNeighborFromCurrent = distances [ currentVertex . getKey ( ) ] + edge . weight ;
35
49
50
+ // If we've found shorter path to the neighbor - update it.
36
51
if ( distanceToNeighborFromCurrent < existingDistanceToNeighbor ) {
37
52
distances [ neighbor . getKey ( ) ] = distanceToNeighborFromCurrent ;
38
53
39
- // Change priority.
54
+ // Change priority of the neighbor in a queue since it might have became closer .
40
55
if ( queue . hasValue ( neighbor ) ) {
41
56
queue . changePriority ( neighbor , distances [ neighbor . getKey ( ) ] ) ;
42
57
}
43
58
44
- // Remember previous vertex.
59
+ // Remember previous closest vertex.
45
60
previousVertices [ neighbor . getKey ( ) ] = currentVertex ;
46
61
}
47
62
@@ -52,10 +67,12 @@ export default function dijkstra(graph, startVertex) {
52
67
}
53
68
} ) ;
54
69
55
- // Add current vertex to visited ones.
70
+ // Add current vertex to visited ones to avoid visiting it again later .
56
71
visitedVertices [ currentVertex . getKey ( ) ] = currentVertex ;
57
72
}
58
73
74
+ // Return the set of shortest distances to all vertices and the set of
75
+ // shortest paths to all vertices in a graph.
59
76
return {
60
77
distances,
61
78
previousVertices,
0 commit comments