Complete backend

This commit is contained in:
2020-02-08 19:59:51 +01:00
parent 06b2078e4d
commit 4379b4d231
19 changed files with 1178 additions and 29 deletions

55
helpers/dijkstra_algo.js Normal file
View 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
View 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
View 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;

18
helpers/test_dijkstra.js Normal file
View File

@@ -0,0 +1,18 @@
const searchPath = require('../helpers/dijkstra_algo');
const cities = require('../data/test_data/cities');
const roads = require('../data/test_data/roads');
let { path, distance} = searchPath(cities, roads, 1, 9);
const formatedPath = [];
// I didn't use map or filter because it doesn't preserve the order
for (let path_city of path) {
for (let city of cities) {
if (city.id == path_city) {
formatedPath.push({ id: city.id, name: city.name });
}
}
}
console.log(formatedPath)