Add initial version of dijkstra backend cloudron image
This commit is contained in:
55
helpers/dijkstra_algo.js
Normal file
55
helpers/dijkstra_algo.js
Normal file
@@ -0,0 +1,55 @@
|
||||
const Queue = require('./queue');
|
||||
const Graph = require('./graph');
|
||||
|
||||
function findPathWithDijkstra(cities, roads, startNode, endNode) {
|
||||
const graph = new Graph();
|
||||
|
||||
// Add cities and roads to graph
|
||||
for (let city of cities) {
|
||||
graph.addNode(city.id)
|
||||
}
|
||||
|
||||
for (let { start_city_id, end_city_id, distance } of roads) {
|
||||
graph.addEdge(start_city_id, end_city_id, distance)
|
||||
}
|
||||
|
||||
// Dijkstra path search algo
|
||||
let times = {};
|
||||
let backtrace = {};
|
||||
let queue = new Queue();
|
||||
|
||||
times[startNode] = 0;
|
||||
|
||||
graph.nodes.forEach(node => {
|
||||
if (node !== startNode) {
|
||||
times[node] = Infinity
|
||||
}
|
||||
});
|
||||
|
||||
queue.enqueue([startNode, 0]);
|
||||
|
||||
while (queue.size()) {
|
||||
let shortestStep = queue.dequeue();
|
||||
let currentNode = shortestStep[0];
|
||||
graph.adjacencyList[currentNode].forEach(neighbor => {
|
||||
let time = times[currentNode] + neighbor.distance;
|
||||
|
||||
if (time < times[neighbor.node]) {
|
||||
times[neighbor.node] = time;
|
||||
backtrace[neighbor.node] = currentNode;
|
||||
queue.enqueue([neighbor.node, time]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let path = [endNode];
|
||||
let lastStep = endNode; while(lastStep !== startNode) {
|
||||
path.unshift(backtrace[lastStep])
|
||||
lastStep = backtrace[lastStep]
|
||||
}
|
||||
|
||||
// return `Path is ${path} and time is ${times[endNode]}`
|
||||
return {path, distance: times[endNode]}
|
||||
}
|
||||
|
||||
module.exports = findPathWithDijkstra;
|
||||
18
helpers/graph.js
Normal file
18
helpers/graph.js
Normal file
@@ -0,0 +1,18 @@
|
||||
class Graph {
|
||||
constructor() {
|
||||
this.nodes = [];
|
||||
this.adjacencyList = {};
|
||||
}
|
||||
|
||||
addNode(node) {
|
||||
this.nodes.push(node);
|
||||
this.adjacencyList[node] = [];
|
||||
}
|
||||
|
||||
addEdge(node1, node2, distance) {
|
||||
this.adjacencyList[node1].push({node:node2, distance});
|
||||
this.adjacencyList[node2].push({node:node1, distance});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Graph;
|
||||
21
helpers/queue.js
Normal file
21
helpers/queue.js
Normal file
@@ -0,0 +1,21 @@
|
||||
class Queue {
|
||||
constructor() {
|
||||
this.store = [];
|
||||
}
|
||||
|
||||
size() {
|
||||
return this.store.length
|
||||
}
|
||||
|
||||
enqueue(node) {
|
||||
this.store.push(node);
|
||||
}
|
||||
|
||||
dequeue() {
|
||||
if (this.size() > 0) {
|
||||
return this.store.shift();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Queue;
|
||||
Reference in New Issue
Block a user