-
Notifications
You must be signed in to change notification settings - Fork 17
/
shortestPathWithLogs.js
88 lines (78 loc) · 2.69 KB
/
shortestPathWithLogs.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
const shortestDistanceNode = (distances, visited) => {
let shortest = null;
for (let node in distances) {
let currentIsShortest =
shortest === null || distances[node] < distances[shortest];
if (currentIsShortest && !visited.includes(node)) {
shortest = node;
}
}
return shortest;
};
const findShortestPathWithLogs = (graph, startNode, endNode) => {
// establish object for recording distances from the start node
let distances = {};
distances[endNode] = "Infinity";
distances = Object.assign(distances, graph[startNode]);
// track paths
let parents = { endNode: null };
for (let child in graph[startNode]) {
parents[child] = startNode;
}
// track nodes that have already been visited
let visited = [];
// find the nearest node
let node = shortestDistanceNode(distances, visited);
// for that node
while (node) {
// find its distance from the start node & its child nodes
let distance = distances[node];
let children = graph[node];
// for each of those child nodes
for (let child in children) {
// make sure each child node is not the start node
if (String(child) === String(startNode)) {
console.log("don't return to the start node! 🙅");
continue;
} else {
console.log("startNode: " + startNode);
console.log("distance from node " + parents[node] + " to node " + node + ")");
console.log("previous distance: " + distances[node]);
// save the distance from the start node to the child node
let newdistance = distance + children[child];
console.log("new distance: " + newdistance);
// if there's no recorded distance from the start node to the child node in the distances object
// or if the recorded distance is shorter than the previously stored distance from the start node to the child node
// save the distance to the object
// record the path
if (!distances[child] || distances[child] > newdistance) {
distances[child] = newdistance;
parents[child] = node;
console.log("distance + parents updated");
} else {
console.log("not updating, because a shorter path already exists!");
}
}
}
// move the node to the visited set
visited.push(node);
// move to the nearest neighbor node
node = shortestDistanceNode(distances, visited);
}
// using the stored paths from start node to end node
// record the shortest path
let shortestPath = [endNode];
let parent = parents[endNode];
while (parent) {
shortestPath.push(parent);
parent = parents[parent];
}
shortestPath.reverse();
// return the shortest path from start node to end node & its distance
let results = {
distance: distances[endNode],
path: shortestPath,
};
return results;
};
module.exports = findShortestPathWithLogs;