Created
May 5, 2018 10:12
-
-
Save Mati365/cb8c53566f36a1743d66b8ac66de4938 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Vertex { | |
constructor(name, value = 0) { | |
this.name = name; | |
this.value = value; | |
this.edges = []; | |
} | |
/** | |
* Links both vertices | |
* | |
* @param v1 First vertex | |
* @param v2 Second vertex | |
* @param weight Edge weight | |
*/ | |
static linkVertices(v1, v2, weight) { | |
v1.addEdge({ | |
vertex: v2, | |
weight, | |
}); | |
v2.addEdge({ | |
vertex: v1, | |
weight, | |
}); | |
} | |
/** | |
* Adds edge and checks if unique | |
* | |
* @param edge | |
* @return | |
*/ | |
addEdge(edge) { | |
if (!edge) | |
throw new Error('Edge cannot be null!'); | |
const found = this.edges.find( | |
({vertex: {name}}) => name === edge.vertex.name, | |
); | |
if (found) | |
return this; | |
this.edges.push(edge); | |
return this; | |
} | |
/** | |
* Attach vertex to edges list | |
* | |
* @param vertex | |
* @param weight Edge weight | |
* | |
* @return Vertex | |
*/ | |
linkTo(vertex, weight) { | |
Vertex.linkVertices(this, vertex, weight); | |
return this; | |
} | |
}; | |
class VertexGraph { | |
constructor(matrix) { | |
this.vertices = VertexGraph.pickVertices(matrix); | |
} | |
toString() { | |
return this | |
.vertices | |
.map(({name, edges}) => ( | |
`${name}: ${edges.map( | |
({weight, vertex}) => `${vertex.name}(${weight})`).join(', ') | |
}` | |
)) | |
.join('\n'); | |
} | |
/** | |
* Picks vertices from linked matrix | |
* | |
* @param matrix | |
* @return Array of Vertex | |
*/ | |
static pickVertices(matrix) { | |
if (!matrix || !matrix.length || matrix[0].edges.length !== matrix.length) | |
throw new Error('Wrong matrix size! It must be square!'); | |
const vertices = []; | |
matrix.forEach(({name, edges}, index) => { | |
vertices[index] = new Vertex(name); | |
edges.forEach((weight, linkVertexIndex) => { | |
// ignore 0 weight in matrix | |
if (!weight) | |
return; | |
const linkVertex = ( | |
vertices[linkVertexIndex] || (vertices[linkVertexIndex] = new Vertex(matrix[linkVertexIndex].name)) | |
); | |
// link both vertices | |
vertices[index].linkTo(linkVertex, weight); | |
}); | |
}); | |
return vertices; | |
} | |
}; | |
(() => { | |
const graph = new VertexGraph( | |
[ | |
{name: 'A', edges: [0, 1, 0, 0, 0, 0, 0, 1]}, | |
{name: 'B', edges: [1, 0, 1, 0, 1, 0, 0, 0]}, | |
{name: 'C', edges: [0, 1, 0, 0, 1, 0, 0, 0]}, | |
{name: 'D', edges: [0, 0, 1, 0, 1, 0, 0, 0]}, | |
{name: 'E', edges: [0, 1, 0, 1, 0, 0, 0, 0]}, | |
{name: 'F', edges: [0, 0, 0, 0, 0, 0, 1, 0]}, | |
{name: 'G', edges: [0, 0, 0, 0, 0, 1, 0, 1]}, | |
{name: 'H', edges: [1, 0, 0, 0, 0, 0, 1, 0]}, | |
], | |
); | |
console.log(graph.toString()); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment