-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdijkstra-algorithm.js
124 lines (106 loc) · 3.58 KB
/
dijkstra-algorithm.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// dijkstra algorithm: It helps find the shortest path
class PriorityQueue {
constructor() {
this.values = [];
}
enqueue(value, priority) {
this.values.push({ value, priority });
this.sort();
}
dequeue() {
return this.values.shift();
}
sort() {
this.values.sort((a, b) => a.priority - b.priority);
}
}
class WeightedGraph {
constructor() {
this.adjacencyList = {};
}
addVertex(vertex) {
if (!this.adjacencyList[vertex]) this.adjacencyList[vertex] = [];
}
addEdge(vertex1, vertex2, weight) {
// save each node as object with node and weight property
this.adjacencyList[vertex1].push({ node: vertex2, weight });
this.adjacencyList[vertex2].push({ node: vertex1, weight });
}
Dijkstra(startingVertex, endingVertex) {
// create an empty priority queue
const nodes = new PriorityQueue();
// create a distance object that would hold distance from every vertex
const distances = {};
// create a previous object that would hold the last shortest distance from one point to another
const previous = {};
// create path array that would hold the list
let path = []; //to return at end
// save the smallest distance in this
let smallest;
// populate the priority queue, distances object and previous object
for (let vertex in this.adjacencyList) {
// Zero for the starting vertex
if (vertex === startingVertex) {
distances[vertex] = 0;
nodes.enqueue(vertex, 0);
} else {
// Infinity for the remaining ones
distances[vertex] = Infinity;
nodes.enqueue(vertex, Infinity);
}
// Set the key to null for previous object
previous[vertex] = null;
}
// as long as there is something to visit
while (nodes.values.length) {
// get the node's value with the least priority count
smallest = nodes.dequeue().value;
// check if starting and ending vertex are same
if (startingVertex === endingVertex) {
// Build up the path to the end by iterating to the end
while (previous[smallest]) {
path.push(smallest);
smallest = previous[smallest];
}
break;
}
// check if smallest is not null and that it is not having Infinity as distance
if (smallest || distances[smallest] !== Infinity) {
// Loop through all the neighbours of the smallest node
for (let neighbor in this.adjacencyList[smallest]) {
//find neighboring node
let nextNode = this.adjacencyList[smallest][neighbor];
//calculate new distance to neighboring node
let candidate = distances[smallest] + nextNode.weight;
let nextNeighbor = nextNode.node;
if (candidate < distances[nextNeighbor]) {
//updating new smallest distance to neighbor
distances[nextNeighbor] = candidate;
//updating previous - How we got to neighbor
previous[nextNeighbor] = smallest;
//enqueue in priority queue with new priority
nodes.enqueue(nextNeighbor, candidate);
}
}
}
}
// return the path list
return path.concat(smallest).reverse();
}
}
const graph = new WeightedGraph();
graph.addVertex("A");
graph.addVertex("B");
graph.addVertex("C");
graph.addVertex("D");
graph.addVertex("E");
graph.addVertex("F");
graph.addEdge("A", "B", 4);
graph.addEdge("A", "C", 2);
graph.addEdge("B", "E", 3);
graph.addEdge("C", "D", 2);
graph.addEdge("C", "F", 4);
graph.addEdge("D", "E", 3);
graph.addEdge("D", "F", 1);
graph.addEdge("E", "F", 1);
graph.Dijkstra("A", "E");