mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-12-26 07:01:18 +08:00
Add more comments for Dijkstra.
This commit is contained in:
parent
1f393551c7
commit
881e3ae5aa
@ -1,30 +1,44 @@
|
|||||||
import PriorityQueue from '../../../data-structures/priority-queue/PriorityQueue';
|
import PriorityQueue from '../../../data-structures/priority-queue/PriorityQueue';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Graph} graph
|
* @typedef {Object} ShortestPaths
|
||||||
* @param {GraphVertex} startVertex
|
* @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) {
|
export default function dijkstra(graph, startVertex) {
|
||||||
|
// Init helper variables that we will need for Dijkstra algorithm.
|
||||||
const distances = {};
|
const distances = {};
|
||||||
const visitedVertices = {};
|
const visitedVertices = {};
|
||||||
const previousVertices = {};
|
const previousVertices = {};
|
||||||
const queue = new PriorityQueue();
|
const queue = new PriorityQueue();
|
||||||
|
|
||||||
// Init all distances with infinity assuming that currently we can't reach
|
// 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) => {
|
graph.getAllVertices().forEach((vertex) => {
|
||||||
distances[vertex.getKey()] = Infinity;
|
distances[vertex.getKey()] = Infinity;
|
||||||
previousVertices[vertex.getKey()] = null;
|
previousVertices[vertex.getKey()] = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// We are already at the startVertex so the distance to it is zero.
|
||||||
distances[startVertex.getKey()] = 0;
|
distances[startVertex.getKey()] = 0;
|
||||||
|
|
||||||
// Init vertices queue.
|
// Init vertices queue.
|
||||||
queue.add(startVertex, distances[startVertex.getKey()]);
|
queue.add(startVertex, distances[startVertex.getKey()]);
|
||||||
|
|
||||||
|
// Iterate over the priority queue of vertices until it is empty.
|
||||||
while (!queue.isEmpty()) {
|
while (!queue.isEmpty()) {
|
||||||
|
// Fetch next closest vertex.
|
||||||
const currentVertex = queue.poll();
|
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.
|
// Don't visit already visited vertices.
|
||||||
if (!visitedVertices[neighbor.getKey()]) {
|
if (!visitedVertices[neighbor.getKey()]) {
|
||||||
// Update distances to every neighbor from current vertex.
|
// Update distances to every neighbor from current vertex.
|
||||||
@ -33,15 +47,16 @@ export default function dijkstra(graph, startVertex) {
|
|||||||
const existingDistanceToNeighbor = distances[neighbor.getKey()];
|
const existingDistanceToNeighbor = distances[neighbor.getKey()];
|
||||||
const distanceToNeighborFromCurrent = distances[currentVertex.getKey()] + edge.weight;
|
const distanceToNeighborFromCurrent = distances[currentVertex.getKey()] + edge.weight;
|
||||||
|
|
||||||
|
// If we've found shorter path to the neighbor - update it.
|
||||||
if (distanceToNeighborFromCurrent < existingDistanceToNeighbor) {
|
if (distanceToNeighborFromCurrent < existingDistanceToNeighbor) {
|
||||||
distances[neighbor.getKey()] = distanceToNeighborFromCurrent;
|
distances[neighbor.getKey()] = distanceToNeighborFromCurrent;
|
||||||
|
|
||||||
// Change priority.
|
// Change priority of the neighbor in a queue since it might have became closer.
|
||||||
if (queue.hasValue(neighbor)) {
|
if (queue.hasValue(neighbor)) {
|
||||||
queue.changePriority(neighbor, distances[neighbor.getKey()]);
|
queue.changePriority(neighbor, distances[neighbor.getKey()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember previous vertex.
|
// Remember previous closest vertex.
|
||||||
previousVertices[neighbor.getKey()] = currentVertex;
|
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;
|
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 {
|
return {
|
||||||
distances,
|
distances,
|
||||||
previousVertices,
|
previousVertices,
|
||||||
|
Loading…
Reference in New Issue
Block a user