diff --git a/src/algorithms/graph/dijkstra/dijkstra.js b/src/algorithms/graph/dijkstra/dijkstra.js index 3614376e..c5b47b08 100644 --- a/src/algorithms/graph/dijkstra/dijkstra.js +++ b/src/algorithms/graph/dijkstra/dijkstra.js @@ -1,30 +1,44 @@ import PriorityQueue from '../../../data-structures/priority-queue/PriorityQueue'; /** - * @param {Graph} graph - * @param {GraphVertex} startVertex + * @typedef {Object} ShortestPaths + * @property {Object} distances - shortest distances to all vertices + * @property {Object} previousVertices - shortest paths to all vertices. + */ + +/** + * Implementation of Dijkstra algorithm of finding the shortest paths to graph nodes. + * @param {Graph} graph - graph we're going to traverse. + * @param {GraphVertex} startVertex - traversal start vertex. + * @return {ShortestPaths} */ export default function dijkstra(graph, startVertex) { + // Init helper variables that we will need for Dijkstra algorithm. const distances = {}; const visitedVertices = {}; const previousVertices = {}; const queue = new PriorityQueue(); // Init all distances with infinity assuming that currently we can't reach - // any of the vertices except start one. + // any of the vertices except the start one. graph.getAllVertices().forEach((vertex) => { distances[vertex.getKey()] = Infinity; previousVertices[vertex.getKey()] = null; }); + + // We are already at the startVertex so the distance to it is zero. distances[startVertex.getKey()] = 0; // Init vertices queue. queue.add(startVertex, distances[startVertex.getKey()]); + // Iterate over the priority queue of vertices until it is empty. while (!queue.isEmpty()) { + // Fetch next closest vertex. const currentVertex = queue.poll(); - graph.getNeighbors(currentVertex).forEach((neighbor) => { + // Iterate over every unvisited neighbor of the current vertex. + currentVertex.getNeighbors().forEach((neighbor) => { // Don't visit already visited vertices. if (!visitedVertices[neighbor.getKey()]) { // Update distances to every neighbor from current vertex. @@ -33,15 +47,16 @@ export default function dijkstra(graph, startVertex) { const existingDistanceToNeighbor = distances[neighbor.getKey()]; const distanceToNeighborFromCurrent = distances[currentVertex.getKey()] + edge.weight; + // If we've found shorter path to the neighbor - update it. if (distanceToNeighborFromCurrent < existingDistanceToNeighbor) { distances[neighbor.getKey()] = distanceToNeighborFromCurrent; - // Change priority. + // Change priority of the neighbor in a queue since it might have became closer. if (queue.hasValue(neighbor)) { queue.changePriority(neighbor, distances[neighbor.getKey()]); } - // Remember previous vertex. + // Remember previous closest vertex. previousVertices[neighbor.getKey()] = currentVertex; } @@ -52,10 +67,12 @@ export default function dijkstra(graph, startVertex) { } }); - // Add current vertex to visited ones. + // Add current vertex to visited ones to avoid visiting it again later. visitedVertices[currentVertex.getKey()] = currentVertex; } + // Return the set of shortest distances to all vertices and the set of + // shortest paths to all vertices in a graph. return { distances, previousVertices,