From 86a27ee94fd1e862b0677643d3852a9c7e57ce27 Mon Sep 17 00:00:00 2001 From: Dspade0 Date: Mon, 13 Mar 2017 18:26:09 +0200 Subject: [PATCH 01/10] added eslint configuration --- .eslintrc.yml | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 .eslintrc.yml diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 0000000..de3adce --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,173 @@ +env: + es6: true + node: true +extends: 'eslint:recommended' +globals: + api: false +rules: + indent: + - error + - 2 + - SwitchCase: 1 + VariableDeclarator: + var: 2 + let: 2 + const: 3 + MemberExpression: 1 + linebreak-style: + - error + - unix + quotes: + - error + - single + semi: + - error + - always + eqeqeq: + - error + - always + no-loop-func: + - error + strict: + - error + - global + block-spacing: + - error + - always + brace-style: + - error + - 1tbs + - allowSingleLine: true + camelcase: + - error + comma-style: + - error + - last + comma-spacing: + - error + - before: false + after: true + eol-last: + - error + func-call-spacing: + - error + - never + key-spacing: + - error + - beforeColon: false + afterColon: true + mode: minimum + keyword-spacing: + - error + - before: true + after: true + overrides: + function: + after: false + max-len: + - error + - code: 80 + ignoreUrls: true + max-nested-callbacks: + - error + - max: 7 + new-cap: + - error + - newIsCap: true + capIsNew: true + properties: true + new-parens: + - error + no-lonely-if: + - error + no-trailing-spaces: + - error + no-unneeded-ternary: + - error + no-whitespace-before-property: + - error + object-curly-spacing: + - error + - always + operator-assignment: + - error + - always + operator-linebreak: + - error + - after + semi-spacing: + - error + - before: false + after: true + space-before-blocks: + - error + - always + space-before-function-paren: + - error + - never + space-in-parens: + - error + - never + space-infix-ops: + - error + space-unary-ops: + - error + - words: true + nonwords: false + overrides: + typeof: false + no-unreachable: + - error + no-global-assign: + - error + no-self-compare: + - error + no-unmodified-loop-condition: + - error + no-constant-condition: + - error + - checkLoops: false + no-console: + - off + no-useless-concat: + - error + no-useless-escape: + - error + no-shadow-restricted-names: + - error + no-use-before-define: + - error + - functions: false + arrow-body-style: + - error + - as-needed + arrow-spacing: + - error + no-confusing-arrow: + - error + - allowParens: true + no-useless-computed-key: + - error + no-useless-rename: + - error + no-var: + - error + object-shorthand: + - error + - always + prefer-arrow-callback: + - error + prefer-const: + - error + prefer-numeric-literals: + - error + prefer-rest-params: + - error + prefer-spread: + - error + rest-spread-spacing: + - error + - never + template-curly-spacing: + - error + - never From 66ba948ce1ade3266eab3ffee148b550bdd720ef Mon Sep 17 00:00:00 2001 From: Dspade0 Date: Mon, 13 Mar 2017 19:50:52 +0200 Subject: [PATCH 02/10] implemented primitive methods --- JavaScript/1-directedGraph.js | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 JavaScript/1-directedGraph.js diff --git a/JavaScript/1-directedGraph.js b/JavaScript/1-directedGraph.js new file mode 100644 index 0000000..65d55d5 --- /dev/null +++ b/JavaScript/1-directedGraph.js @@ -0,0 +1,40 @@ +'use strict'; + +class DirectedGraph { + constructor(vertexN) { + this._adjacency = []; // _adjacency[v] = adjacency array for vertex v + this._indegree = []; // _indegree[v] = indegree of vertex v + this._weight = []; // _weight[v][w] = weight of the edge (v; w) + if (vertexN === undefined) return this; + let i; + for (i = 0; i < vertexN; ++i) { + this.addVertex(); + } + return this; + } + addVertex() { + this._adjacency.push([]); + this._weight.push([]); + const vertexIndex = this._adjacency.length - 1; + this._indegree[vertexIndex] = 0; + return this; + } + hasVertex(v) { + if (v < 0 || v >= this.size) { + return false; + } + return true; + } + get size() { + return this._adjacency.length; + } + connect(v1, v2, weight) { + if (!this.hasVertex(v1) || !this.hasVertex(v2)) { + return false; + } + this._adjacency[v1].push(v2); + this._weight[v1][v2] = weight; + ++this._indegree[v2]; + return true; + } +} From 7b1d85d680c1a67de3f69d04f872aad6429096e6 Mon Sep 17 00:00:00 2001 From: Dspade0 Date: Mon, 13 Mar 2017 22:24:48 +0200 Subject: [PATCH 03/10] implemented disconnect method --- JavaScript/1-directedGraph.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/JavaScript/1-directedGraph.js b/JavaScript/1-directedGraph.js index 65d55d5..23b3747 100644 --- a/JavaScript/1-directedGraph.js +++ b/JavaScript/1-directedGraph.js @@ -37,4 +37,14 @@ class DirectedGraph { ++this._indegree[v2]; return true; } + disconnect(v1, v2) { + if (!this.hasVertex(v1) || !this.hasVertex(v2)) { + return false; + } + const vertexIndex = this._adjacency[v1].indexOf(v2); + if (vertexIndex === -1) return false; + this._adjacency[v1].splice(vertexIndex, 1); + this._weight[v1][v2] = undefined; + --this._indegree[v2]; + } } From 93f50b62d93896f3966ab6d8856b3c6a7858fb99 Mon Sep 17 00:00:00 2001 From: Dspade0 Date: Mon, 13 Mar 2017 22:41:24 +0200 Subject: [PATCH 04/10] implemented isConnect method --- JavaScript/1-directedGraph.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/JavaScript/1-directedGraph.js b/JavaScript/1-directedGraph.js index 23b3747..aaec662 100644 --- a/JavaScript/1-directedGraph.js +++ b/JavaScript/1-directedGraph.js @@ -42,9 +42,18 @@ class DirectedGraph { return false; } const vertexIndex = this._adjacency[v1].indexOf(v2); - if (vertexIndex === -1) return false; + if (vertexIndex < 0) return false; this._adjacency[v1].splice(vertexIndex, 1); this._weight[v1][v2] = undefined; --this._indegree[v2]; + return true; + } + isConnected(v1, v2) { + if (!this.hasVertex(v1) || !this.hasVertex(v2)) { + return false; + } + const vertexIndex = this._adjacency[v1].indexOf(v2); + if (vertexIndex < 0) return false; + return true; } } From 99ca51a419564918b4a92647de6cc2629e40380c Mon Sep 17 00:00:00 2001 From: Dspade0 Date: Mon, 13 Mar 2017 23:19:36 +0200 Subject: [PATCH 05/10] implemented getWeight and transpose methods --- JavaScript/1-directedGraph.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/JavaScript/1-directedGraph.js b/JavaScript/1-directedGraph.js index aaec662..09c93bc 100644 --- a/JavaScript/1-directedGraph.js +++ b/JavaScript/1-directedGraph.js @@ -56,4 +56,19 @@ class DirectedGraph { if (vertexIndex < 0) return false; return true; } + getWeight(v1, v2) { + return this._weight[v1][v2]; + } + transpose() { + const size = this.size; + let transposedGraph = new DirectedGraph(size); + let v, w, weight; + for (v = 0; v < size; ++v) { + for (w of this._adjacency[v]) { + weight = this.getWeight(v, w); + transposedGraph.connect(w, v, weight); + } + } + return transposedGraph; + } } From 71959c539dc9be584cab863b1e1860353bcfdec1 Mon Sep 17 00:00:00 2001 From: Dspade0 Date: Tue, 14 Mar 2017 02:59:36 +0200 Subject: [PATCH 06/10] implemented minimumDistance method with Belman-Ford algorithm --- JavaScript/1-directedGraph.js | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/JavaScript/1-directedGraph.js b/JavaScript/1-directedGraph.js index 09c93bc..d186f29 100644 --- a/JavaScript/1-directedGraph.js +++ b/JavaScript/1-directedGraph.js @@ -71,4 +71,44 @@ class DirectedGraph { } return transposedGraph; } + /** + * Computes shortest paths from a single source vertex + * to all of the other vertices (Bellman-Ford inplementation). + * + * @param from = the vertex + * @return distanceArr[v] = minimum distance to v + * parentArr[v] = parent vertex for v in the shortest path + */ + minimunDistance(from) { + if (!this.hasVertex(from)) { + return null; + } + let distance = new Array(this.size); + let parent = new Array(this.size); + let i; + for (i = 0; i < this.size; ++i) { + distance[i] = Infinity; + parent[i] = -1; + } + distance[from] = 0; + for (i = 0; i < this.size - 1; ++i) { + this._adjacency.forEach((adj, v) => { // for each vertex in the graph + adj.forEach(w => { // for each adjacent vertex w to v + if (distance[w] > distance[v] + this.getWeight(v, w)) { + distance[w] = distance[v] + this.getWeight(v, w); + parent[w] = v; + } + }); + }); + } + // if any distance[i] changes, the graph has negative cycles + this._adjacency.forEach((adj, v) => { + adj.forEach(w => { + if (distance[w] > distance[v] + this.getWeight(v, w)) { + return null; + } + }); + }); + return { distanceArr: distance, parentArr: parent }; + } } From 0a21f21b0d1a20fd1a847fac42892fad69f18cf6 Mon Sep 17 00:00:00 2001 From: Dspade0 Date: Tue, 14 Mar 2017 03:02:39 +0200 Subject: [PATCH 07/10] added an example of using DirectedGraph --- JavaScript/1-directedGraph.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/JavaScript/1-directedGraph.js b/JavaScript/1-directedGraph.js index d186f29..d27dacc 100644 --- a/JavaScript/1-directedGraph.js +++ b/JavaScript/1-directedGraph.js @@ -112,3 +112,27 @@ class DirectedGraph { return { distanceArr: distance, parentArr: parent }; } } + +const myGraph = new DirectedGraph(4); +myGraph.connect(0, 1, 2); +myGraph.connect(0, 2, 3); +myGraph.connect(1, 2, -2); +myGraph.connect(1, 3, 2); +myGraph.connect(2, 3, 3); + +const checkVertex = 0; +const checkEdge = [2, 3]; +if (myGraph.hasVertex(checkVertex)) { + console.log('I have vertex ' + checkVertex); +} else { + console.log('I do not have a vertex ' + checkVertex + ' :('); +} +if (myGraph.isConnected(...checkEdge)) { + console.log(checkEdge[0] + ' is connected with ' + checkEdge[1]); + console.log('It has weight ' + myGraph.getWeight(...checkEdge)); +} +console.log('Lets find the shortest paths for checkVertex!'); +console.time('Belman-Ford'); +const result = myGraph.minimunDistance(checkVertex); +console.timeEnd('Belman-Ford'); +console.dir(result); From 4b5fe094fe5843e2a1410b9ddc969254edf48943 Mon Sep 17 00:00:00 2001 From: Dspade0 Date: Wed, 15 Mar 2017 13:36:44 +0200 Subject: [PATCH 08/10] use const instead of let --- JavaScript/1-directedGraph.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/JavaScript/1-directedGraph.js b/JavaScript/1-directedGraph.js index d27dacc..5ee3bbe 100644 --- a/JavaScript/1-directedGraph.js +++ b/JavaScript/1-directedGraph.js @@ -61,7 +61,7 @@ class DirectedGraph { } transpose() { const size = this.size; - let transposedGraph = new DirectedGraph(size); + const transposedGraph = new DirectedGraph(size); let v, w, weight; for (v = 0; v < size; ++v) { for (w of this._adjacency[v]) { @@ -83,8 +83,8 @@ class DirectedGraph { if (!this.hasVertex(from)) { return null; } - let distance = new Array(this.size); - let parent = new Array(this.size); + const distance = new Array(this.size); + const parent = new Array(this.size); let i; for (i = 0; i < this.size; ++i) { distance[i] = Infinity; From 2ee6fab8f94e489404f57c8a18676a3a4b3955b2 Mon Sep 17 00:00:00 2001 From: Dspade0 Date: Wed, 15 Mar 2017 21:41:16 +0200 Subject: [PATCH 09/10] used loops 'for' instead of forEach to correctly return null --- JavaScript/1-directedGraph.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/JavaScript/1-directedGraph.js b/JavaScript/1-directedGraph.js index 5ee3bbe..9126d84 100644 --- a/JavaScript/1-directedGraph.js +++ b/JavaScript/1-directedGraph.js @@ -79,7 +79,7 @@ class DirectedGraph { * @return distanceArr[v] = minimum distance to v * parentArr[v] = parent vertex for v in the shortest path */ - minimunDistance(from) { + minimumDistance(from) { if (!this.hasVertex(from)) { return null; } @@ -92,23 +92,23 @@ class DirectedGraph { } distance[from] = 0; for (i = 0; i < this.size - 1; ++i) { - this._adjacency.forEach((adj, v) => { // for each vertex in the graph - adj.forEach(w => { // for each adjacent vertex w to v + for (let v in this._adjacency) { // for each vertex v + for (let w of this._adjacency[v]) { // for each incident edge for v if (distance[w] > distance[v] + this.getWeight(v, w)) { distance[w] = distance[v] + this.getWeight(v, w); parent[w] = v; } - }); - }); + } + } } // if any distance[i] changes, the graph has negative cycles - this._adjacency.forEach((adj, v) => { - adj.forEach(w => { + for (let v in this._adjacency) { + for (let w of this._adjacency[v]) { if (distance[w] > distance[v] + this.getWeight(v, w)) { return null; } - }); - }); + } + } return { distanceArr: distance, parentArr: parent }; } } @@ -133,6 +133,6 @@ if (myGraph.isConnected(...checkEdge)) { } console.log('Lets find the shortest paths for checkVertex!'); console.time('Belman-Ford'); -const result = myGraph.minimunDistance(checkVertex); +const result = myGraph.minimumDistance(checkVertex); console.timeEnd('Belman-Ford'); console.dir(result); From a5a97827452ea35b082fe04602ca9113a823d187 Mon Sep 17 00:00:00 2001 From: Dspade0 Date: Wed, 15 Mar 2017 23:18:51 +0200 Subject: [PATCH 10/10] added toposort method --- JavaScript/1-directedGraph.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/JavaScript/1-directedGraph.js b/JavaScript/1-directedGraph.js index 9126d84..ff4245f 100644 --- a/JavaScript/1-directedGraph.js +++ b/JavaScript/1-directedGraph.js @@ -111,6 +111,28 @@ class DirectedGraph { } return { distanceArr: distance, parentArr: parent }; } + toposort() { + const grey = 1, + black = 2, + sorted = new Array(), + marked = new Array(this.size); + const dfs = (v) => { + if (marked[v] === grey) return 0; + if (marked[v] === black) return 1; + marked[v] = grey; + for (let w of this._adjacency[v]) { + if (!dfs(w)) return undefined; + } + marked[v] = black; + sorted.unshift(v); + return marked[v]; + }; + for (let v in this._adjacency) { + if (marked[v]) continue; + if (!dfs(v)) return null; + } + return sorted; + } } const myGraph = new DirectedGraph(4); @@ -136,3 +158,5 @@ console.time('Belman-Ford'); const result = myGraph.minimumDistance(checkVertex); console.timeEnd('Belman-Ford'); console.dir(result); + +console.log('Toposort test: ' + myGraph.toposort()); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy