From 07a268efa271794b61e442fe600ffc21012a2d7b Mon Sep 17 00:00:00 2001 From: Miltiadis Stouras Date: Sun, 26 Aug 2018 00:38:47 +0300 Subject: [PATCH 1/3] Implement extractPath function --- lib/alg/extract-path.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 lib/alg/extract-path.js diff --git a/lib/alg/extract-path.js b/lib/alg/extract-path.js new file mode 100644 index 00000000..e4e5eba0 --- /dev/null +++ b/lib/alg/extract-path.js @@ -0,0 +1,27 @@ +module.exports = extractPath; + +function extractPath(shortestPaths, source, destination) { + if (shortestPaths[source].predecessor !== undefined) { + throw new Error("Invalid source vertex"); + } + if (shortestPaths[destination].predecessor === undefined && destination !== source) { + throw new Error("Invalid destination vertex"); + } + + return { + weight: shortestPaths[destination].distance, + path: runExtractPath(shortestPaths, source, destination) + }; +} + +function runExtractPath(shortestPaths, source, destination) { + var path = []; + var currentNode = destination; + + while(currentNode !== source) { + path.push(currentNode); + currentNode = shortestPaths[currentNode].predecessor; + } + path.push(source); + return path.reverse(); +} From c2b326e8a90acb13cacc38e1208044e67beed4c9 Mon Sep 17 00:00:00 2001 From: Miltiadis Stouras Date: Sun, 26 Aug 2018 00:39:18 +0300 Subject: [PATCH 2/3] Export extractPath from /lib/alg --- lib/alg/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/alg/index.js b/lib/alg/index.js index 2c3d76f2..46eab8c7 100644 --- a/lib/alg/index.js +++ b/lib/alg/index.js @@ -2,6 +2,7 @@ module.exports = { components: require("./components"), dijkstra: require("./dijkstra"), dijkstraAll: require("./dijkstra-all"), + extractPath: require("./extract-path"), findCycles: require("./find-cycles"), floydWarshall: require("./floyd-warshall"), isAcyclic: require("./is-acyclic"), From 2862de4dda1262025d2290e439b399d3436a0c2b Mon Sep 17 00:00:00 2001 From: Miltiadis Stouras Date: Sun, 26 Aug 2018 00:39:38 +0300 Subject: [PATCH 3/3] Add tests for extractPath --- test/alg/extract-path-tests.js | 49 ++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 test/alg/extract-path-tests.js diff --git a/test/alg/extract-path-tests.js b/test/alg/extract-path-tests.js new file mode 100644 index 00000000..972e36cf --- /dev/null +++ b/test/alg/extract-path-tests.js @@ -0,0 +1,49 @@ +var expect = require("../chai").expect, + extractPath = require("../..").alg.extractPath; + +describe("alg.extractPath", function() { + it("returns weight: 0 and path: [source], from source to source", function() { + var shortestPaths = { + "a": { distance: 0 }, + "b": { distance: 73, predecessor: "a" } + }; + expect(extractPath(shortestPaths, "a", "a")).to.eql( + { weight: 0, + path: ["a"] + }); + }); + + it("returns weight and path from source to destination", function() { + var shortestPaths = { + "a": { distance: 0 }, + "b": { distance: 25, predecessor: "a" }, + "c": { distance: 55, predecessor: "b" }, + "d": { distance: 44, predecessor: "b" }, + "e": { distance: 73, predecessor: "c" }, + "f": { distance: 65, predecessor: "d" }, + "g": { distance: 67, predecessor: "b" }, + }; + expect(extractPath(shortestPaths, "a", "e")).to.eql( + { weight: 73, + path: ["a", "b", "c", "e"] + }); + }); + + it("throws an error when provided with an invalid source vertex", function() { + var shortestPaths = { + "a": { distance: 0 }, + "b": { distance: 17, predecessor: "c" }, + "c": { distance: 42, predecessor: "a" } + }; + expect(function() { extractPath(shortestPaths, "b", "c"); }).to.throw(); + }); + + it("throws an error when given an invalid destination vertex", function() { + var shortestPaths = { + "a": { distance: 0 }, + "b": { distance: 99, predecessor: "a" }, + "c": { distance: 100 } + }; + expect(function() { extractPath(shortestPaths, "a", "c"); }).to.throw(); + }); +});