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 diff --git a/JavaScript/1-directedGraph.js b/JavaScript/1-directedGraph.js new file mode 100644 index 0000000..ff4245f --- /dev/null +++ b/JavaScript/1-directedGraph.js @@ -0,0 +1,162 @@ +'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; + } + disconnect(v1, v2) { + if (!this.hasVertex(v1) || !this.hasVertex(v2)) { + return false; + } + const vertexIndex = this._adjacency[v1].indexOf(v2); + 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; + } + getWeight(v1, v2) { + return this._weight[v1][v2]; + } + transpose() { + const size = this.size; + const 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; + } + /** + * 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 + */ + minimumDistance(from) { + if (!this.hasVertex(from)) { + return null; + } + const distance = new Array(this.size); + const 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) { + 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 + 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 }; + } + 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); +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.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