-
Notifications
You must be signed in to change notification settings - Fork 0
/
graph.js
92 lines (80 loc) · 2.27 KB
/
graph.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
// GRAPH TRAVERSAL LOGIC
class Node{
constructor(name, neighbours, zone){
this.name = name;
this.neighbours = neighbours;
this.zone = zone;
}
}
// generates graph of 2 dimensional array
// [['name', 'zone', 'neighbourA, neighbourB, ...']]
// => {"a": Node, "b": Node, ...}
exports.generateGraph = function(data){
graph = {};
data.forEach(row => {
var name = row[0];
var zone = row[1];
var neighbours = row[2].split(',');
graph[name] = new Node(name, neighbours, zone);
});
return graph;
}
//collect all shortest paths by tracing back to the start node
function findPaths(paths, path, prev, start, currentNode){
if(currentNode === start){
path = path.slice();
paths.push(path);
return;
}
for (var par of prev[currentNode]){
path.push(graph[currentNode]); // add Node Object to the path
findPaths(paths, path, prev, start, par);
path.pop(par);
}
return;
}
// breadth first search for finding all shortest paths
// returns e.g. [[node1, node2, node3], ...]
exports.bfsAll = function(graph, s, e) {
var start = graph[s];
var end = graph[e];
if(start == null || end == null)
return [];
if(s == e)
return [[start]];
var queue = [start];
var visited = [];
visited.push(start);
var prev = []; // [Nodename : [previous nodenames], ...]
var dist = []; // distances between each node and the start node [Nodename : distance, ...]
// set all distances to maximum (infinity)
for (const [key, value] of Object.entries(graph))
dist[key] = Infinity;
dist[start.name] = 0;
while(queue.length > 0){
var node = queue.shift();
if (node == end)
break;
for(var next of node.neighbours){
if(dist[next] > dist[node.name] + 1){
dist[next] = dist[node.name] + 1;
visited.push(graph[next]);
queue.push(graph[next]);
prev[next] = [node.name];
}else if(dist[node.name] == dist[prev[next]]){
prev[next].push(node.name);
}
}
}
// connect the paths
paths = [];
path = [];
findPaths(paths, path, prev, start.name, end.name);
for (var p of paths){
p.push(start);
p.reverse();
}
return paths;
}
//console.log(bfs(graph, f, j));
//console.log(bfsAll(graph, f, j));