├── package.json ├── examples ├── isNeighbourOf.js ├── example3.js ├── example2.js ├── example1.js └── example4.js ├── solver.js ├── lib ├── edge.js ├── searches │ ├── dijkstra.js │ └── depthfirstsearch.js ├── vertex.js ├── matrices │ └── adjacency.js └── graph.js └── README.md /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-graph", 3 | "author": "David Coallier", 4 | "email": "david.coallier@gmail.com", 5 | "dependencies": [], 6 | "contributors": [], 7 | "keywords": [ 8 | "mathematics", 9 | "computer science", 10 | "graph theory", 11 | "graph", 12 | ], 13 | "mappings":{}, 14 | "overlay": {}, 15 | "githubName": "node-graph", 16 | "engines": {"node":">=0.1.94"}, 17 | "type": "zip", 18 | "version": "0.1", 19 | "location": "http://github.com/davidcoallier/node-graph", 20 | "license":"BSD" 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/isNeighbourOf.js: -------------------------------------------------------------------------------- 1 | var sys = require('sys'); 2 | var edge = require('../lib/edge'); 3 | var graph = require('../lib/graph'); 4 | var vertex = require('../lib/vertex'); 5 | 6 | var Graph = new graph.Graph(); 7 | var VertexOne = new vertex.Vertex('nameOne', {}); 8 | var VertexTwo = new vertex.Vertex('nameTwo', {}); 9 | var VertexThree = new vertex.Vertex('nameThree', {}); 10 | 11 | Graph.addVertex(VertexOne); 12 | Graph.addVertex(VertexTwo); 13 | Graph.addVertex(VertexThree); 14 | 15 | Graph.addEdge(new edge.Edge('nameOne', 'nameTwo', {})); 16 | Graph.addEdge(new edge.Edge('nameOne', 'nameThree', {})); 17 | 18 | var verts = Graph.getVertices(); 19 | sys.puts(sys.inspect(VertexTwo.isNeighbourOf('nameOnex'))); 20 | -------------------------------------------------------------------------------- /solver.js: -------------------------------------------------------------------------------- 1 | var sys = require('sys'); 2 | var edge = require('./lib/edge'); 3 | var graph = require('./lib/graph'); 4 | var vertex = require('./lib/vertex'); 5 | 6 | var Graph = new graph.Graph(); 7 | var VertexOne = new vertex.Vertex('nameOne', {}); 8 | var VertexTwo = new vertex.Vertex('nameTwo', {}); 9 | var VertexThree = new vertex.Vertex('nameThree', {}); 10 | 11 | Graph.addVertex(VertexOne); 12 | Graph.addVertex(VertexTwo); 13 | Graph.addVertex(VertexThree); 14 | 15 | Graph.addEdge(new edge.Edge('nameOne', 'nameTwo', {})); 16 | Graph.addEdge(new edge.Edge('nameOne', 'nameThree', {})); 17 | 18 | var neighbours = VertexThree.getNeighbours(); 19 | 20 | //sys.puts(sys.inspect(Graph.edges())); 21 | //sys.puts(sys.inspect(neighbours)); 22 | //sys.puts(sys.inspect(Graph)); 23 | -------------------------------------------------------------------------------- /examples/example3.js: -------------------------------------------------------------------------------- 1 | var sys = require('sys'); 2 | var edge = require('../lib/edge'); 3 | var graph = require('../lib/graph'); 4 | var vertex = require('../lib/vertex'); 5 | var matrix = require('../lib/matrices/adjacency'); 6 | 7 | var Graph = new graph.Graph(); 8 | var VertexOne = new vertex.Vertex('nameOne', {}); 9 | var VertexTwo = new vertex.Vertex('nameTwo', {}); 10 | var VertexThree = new vertex.Vertex('nameThree', {}); 11 | 12 | Graph.addVertex(VertexOne); 13 | Graph.addVertex(VertexTwo); 14 | Graph.addVertex(VertexThree); 15 | 16 | Graph.addEdge(new edge.Edge('nameOne', 'nameTwo', {})); 17 | Graph.addEdge(new edge.Edge('nameOne', 'nameThree', {})); 18 | 19 | var Vertices = Graph.getVertices(); 20 | var Matrix = new matrix.Adjacency(Vertices); 21 | sys.puts(sys.inspect(Matrix)); 22 | -------------------------------------------------------------------------------- /examples/example2.js: -------------------------------------------------------------------------------- 1 | var sys = require('sys'); 2 | var edge = require('../lib/edge'); 3 | var graph = require('../lib/graph'); 4 | var vertex = require('../lib/vertex'); 5 | var dfs = require('../lib/searches/depthfirstsearch'); 6 | 7 | var Graph = new graph.Graph(); 8 | var VertexOne = new vertex.Vertex('nameOne', {}); 9 | var VertexTwo = new vertex.Vertex('nameTwo', {}); 10 | var VertexThree = new vertex.Vertex('nameThree', {}); 11 | 12 | Graph.addVertex(VertexOne); 13 | Graph.addVertex(VertexTwo); 14 | Graph.addVertex(VertexThree); 15 | 16 | Graph.addEdge(new edge.Edge('nameOne', 'nameTwo', {})); 17 | Graph.addEdge(new edge.Edge('nameOne', 'nameThree', {})); 18 | 19 | var vertices = Graph.getVertices(); 20 | var dfs = new dfs.DepthFirstSearch(vertices); 21 | sys.puts(sys.inspect(dfs)); 22 | -------------------------------------------------------------------------------- /examples/example1.js: -------------------------------------------------------------------------------- 1 | var sys = require('sys'); 2 | var edge = require('../lib/edge'); 3 | var graph = require('../lib/graph'); 4 | var vertex = require('../lib/vertex'); 5 | 6 | var Graph = new graph.Graph(); 7 | var VertexOne = new vertex.Vertex('nameOne', {}); 8 | var VertexTwo = new vertex.Vertex('nameTwo', {}); 9 | var VertexThree = new vertex.Vertex('nameThree', {}); 10 | 11 | Graph.addVertex(VertexOne); 12 | Graph.addVertex(VertexTwo); 13 | Graph.addVertex(VertexThree); 14 | 15 | Graph.addEdge(new edge.Edge('nameOne', 'nameTwo', {})); 16 | Graph.addEdge(new edge.Edge('nameOne', 'nameThree', {})); 17 | 18 | // This should give me nameTwo and nameThree as the neighbours. 19 | var neighboursOne = VertexOne.getNeighbours(); 20 | sys.puts(sys.inspect(neighboursOne)); 21 | 22 | // This should only give us nameOne 23 | var neighboursThree = VertexThree.getNeighbours(); 24 | sys.puts(sys.inspect(neighboursThree)); 25 | -------------------------------------------------------------------------------- /examples/example4.js: -------------------------------------------------------------------------------- 1 | var sys = require('sys'); 2 | var edge = require('../lib/edge'); 3 | var graph = require('../lib/graph'); 4 | var vertex = require('../lib/vertex'); 5 | var matrix = require('../lib/matrices/adjacency'); 6 | 7 | var Graph = new graph.Graph(); 8 | var VertexOne = new vertex.Vertex('nameOne', {}); 9 | var VertexTwo = new vertex.Vertex('nameTwo', {}); 10 | var VertexThree = new vertex.Vertex('nameThree', {}); 11 | 12 | Graph.addVertex(VertexOne); 13 | Graph.addVertex(VertexTwo); 14 | Graph.addVertex(VertexThree); 15 | 16 | for (var i = 0; i < 100; i++) { 17 | Graph.addVertex(new vertex.Vertex('generated' + i)); 18 | } 19 | 20 | 21 | Graph.addEdge(new edge.Edge('nameOne', 'nameTwo', {})); 22 | Graph.addEdge(new edge.Edge('nameOne', 'nameThree', {})); 23 | Graph.addEdge(new edge.Edge('generated77', 'generated52')); 24 | 25 | var Vertices = Graph.getVertices(); 26 | var Matrix = new matrix.Adjacency(Vertices); 27 | sys.puts(sys.inspect(Matrix)); 28 | -------------------------------------------------------------------------------- /lib/edge.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This is the class used to build a connection between two Vertices. 3 | * 4 | * Once created and associated to a graph, the edge becomes part of E(G). 5 | * 6 | * Author: David Coallier 7 | * License: New BSD 8 | * Date: 6th October, 2010 9 | */ 10 | 11 | /** 12 | * This is the Edge class that is used to do some magicless-magic. 13 | * 14 | * 15 | * var edge = new Edge('vertexLabelOne', 'vertexLabelTwo', {}); 16 | * 17 | * 18 | * @param String The label of the first vertex to associate with the second. 19 | * @param String The label of the second vertex to associate with the first one. 20 | * @param Object A list of attributes. Could be weight, direction, bidirection, etc. 21 | */ 22 | var Edge = function(vertexOne, vertexTwo, attributes) { 23 | this.vertexOne = vertexOne; 24 | this.vertexTwo = vertexTwo; 25 | this.pair = [vertexOne, vertexTwo]; 26 | 27 | this.attributes = attributes || {}; 28 | return this; 29 | }; 30 | 31 | // And we export to node.js 32 | exports.Edge = Edge; 33 | -------------------------------------------------------------------------------- /lib/searches/dijkstra.js: -------------------------------------------------------------------------------- 1 | var sys = require('sys'); 2 | 3 | /** 4 | * This object is used to execute apply the dijkstra shortest-path algorithm on 5 | * single-sourced graphs. 6 | * 7 | * Author: David Coallier 8 | * License: New BSD 9 | * Date: 1st November, 2010 10 | */ 11 | 12 | /** 13 | * The Dijkstra Shortest-path search object is used to identify the 14 | * shortest distance between two vertices (A source and a destination) 15 | * 16 | * Once this is found the main search returns a list of nodes in order 17 | * of the path that is the shortest path. 18 | * 19 | * @param Graph The graph to use to identify the shortest path 20 | * from source to destination. 21 | * @param string The source (Where to start from in the graph) 22 | * @param string The destination to reach and identify the shortest path to. 23 | * 24 | * @return Object A list of vertices that constitute the shortest path from 25 | * source-to-destination 26 | */ 27 | var Dijkstra = function(graph, source, destination, max) { 28 | this.infinity = max || Infinity; 29 | this.dist = this.infinity; 30 | 31 | this.graph = graph; 32 | 33 | this.search = function (source, destination) { 34 | this.costs[source] = 0; 35 | var open = {'0': [source]}; 36 | var previous = {}; 37 | 38 | var costDifferentiator = function(costA, costB) { 39 | return parseFloat(costA) - parseFloat(costB); 40 | }; 41 | 42 | for (vertices in graph) { 43 | 44 | } 45 | }; 46 | }; 47 | 48 | // And now we export to node.js 49 | exports.Dijkstra = Dijkstra; 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | node.js Graph Theory module 2 | ============================ 3 | 4 | > Maths is fun and so is node.js so why not use them together! 5 | 6 | introduction 7 | ------------ 8 | 9 | The goal of this "node-graph" module is to provide a framework for working with graphs 10 | from within node.js. 11 | 12 | It allow (will) developers to build different types of graphs G, create vertices associated to that graph V(G), and create edges to associate/link the vertices together E(G). 13 | 14 | After building the graphs, it will allow developers to traverse, sort and play with the graphs using the most popular algorithms. 15 | 16 | Currently in EXTREMELY early stages, feel free to contribute! 17 | 18 | synopsis 19 | -------- 20 | 21 | Creating a basic Graph object: 22 | 23 | var sys = require('sys'); 24 | var graph = require('./lib/graph'); 25 | 26 | var Graph = new graph.Graph(); 27 | 28 | Now that you have your Graph object, you should add vertices. In order to do that, do: 29 | 30 | var vertex = require('./lib/vertex'); 31 | var vertexOne = new vertex.Vertex('label1', {}); 32 | Graph.addVertex(vertexOne); 33 | 34 | To make that graph more interesting, you'll need to add a second vertex. This time, you can do it inline like such: 35 | 36 | Graph.addVertex(new vertex.Vertex('label2', {})); 37 | 38 | Once you are done, you can now create an edge to link those two vertices together: 39 | 40 | Graph.addEdge(new Edge('label1', 'label2', {})); 41 | 42 | Now the next step is to build more stuff on top of that :-) 43 | 44 | 45 | license 46 | ------- 47 | 48 | Released under the New BSD License. 49 | 50 | Copyright (c) 2010 David Coallier 51 | 52 | 53 | disclaimer 54 | ---------- 55 | 56 | Very likely to be broken. Feel free to contribute, there's still a lot to do, this is merely teh beginning of the whole graph engine. 57 | 58 | -------------------------------------------------------------------------------- /lib/vertex.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This is the object to create a vertex - or a node - or a dot which are all the same. For 3 | * the sake of clarity, this node-graph module is going to exploit the term "vertex" and 4 | * "vertices". 5 | * 6 | * Once created and associated to a graph, the vertex is now a member of the vertex set 7 | * of graph G, or V(G). 8 | * 9 | * Author: David Coallier 10 | * License: New BSD 11 | * Date: 6th October, 2010 12 | */ 13 | 14 | /** 15 | * This is the Vertex class that is used to do some magicless-magic. 16 | * 17 | * 18 | * var VertexOne = new Vertex('vertexLabelOne', {}); 19 | * 20 | * 21 | * @param String The label to associate to this vertex v. 22 | * @param Object A list of different types of attributes associated 23 | * to this vertex. 24 | */ 25 | var Vertex = function(label, attributes) { 26 | this.label = label; 27 | this.edges = {}; 28 | this.attributes = attributes || {}; 29 | return this; 30 | }; 31 | 32 | /** 33 | * Get the neighbours edges of a certain vertex 34 | * 35 | * This method is used to retrieve an array/List (L) 36 | * of the edges associated to a vertex. 37 | * 38 | * @return List A list of edges associated to a certain vertex. 39 | */ 40 | Vertex.prototype.getNeighbours = function() { 41 | return this.edges; 42 | }; 43 | 44 | /** 45 | * Am I it's neighbour? 46 | * 47 | * This method is used to retrieve wheter or not a certain other 48 | * vertex is a neighbour of this vertex. 49 | * 50 | * @param string vertexLabel The vertex to retrieve. 51 | * @return boolean true or false. 52 | */ 53 | Vertex.prototype.isNeighbourOf = function(vertexLabel) { 54 | if (this.edges !== undefined) { 55 | if (vertexLabel in this.edges) { 56 | return true; 57 | } 58 | } 59 | 60 | return false; 61 | }; 62 | 63 | // And we export to node.js 64 | exports.Vertex = Vertex; 65 | -------------------------------------------------------------------------------- /lib/matrices/adjacency.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The adjacency matrix module is used to build... an adjacency matrix 3 | * of the graph. Using an adjancy matrix, it makes it fairly simple to 4 | * identify paths in a graph. 5 | * 6 | * 7 | * var graph = require('./lib/graph'); 8 | * var adjacency = require('./lib/matrices/adjacency'); 9 | * // Create a graph and add vertices.... 10 | * var matrix = new adjacency.Adjacency( 11 | * new graph.Graph().addVertex( 12 | * new vertex.Vertex('name')).addVertex( 13 | * new vertex.Vertex('name2')).addVertex( 14 | * new vertex.Vertex('name3')).addEdge( 15 | * new edge.Edge('name', 'name3')) 16 | * ); 17 | * 18 | * 19 | * The previous code will create an adjacency list that 20 | * looks very similar to: 21 | * 22 | * name name2 name3 23 | * name [0] [0] [1] 24 | * name2 [0] [0] [0] 25 | * name3 [1] [0] [0] 26 | * 27 | * Author: David Coallier 28 | * License: New BSD 29 | * Date: 10th October, 2010 30 | */ 31 | 32 | /** 33 | * Build an adjacency matrix of the graph and passed 34 | * vertices. 35 | * 36 | * @param List A list of Vertices to establish "relationships" or rather 37 | * build the matrix around. 38 | * 39 | * @return An adjacency list. 40 | */ 41 | var Adjacency = function(vertices) { 42 | this.vertices = vertices; 43 | this.matrix = {}; 44 | 45 | var self = this; 46 | 47 | /** 48 | * Build the adjacency matrix 49 | * 50 | * This lamda receives a vertex object, uses 51 | * the other local objects from "self" which is merely a copy 52 | * of "this" and creates an array of vertex and their relation. 53 | * 54 | * @param Vertex A vertex object 55 | * @return Object An array of information about a certain vertex and it's 56 | * associations in the adjacency list. 57 | */ 58 | this.build = function(vertex) { 59 | var matrix = {}; 60 | var neighbours = vertex.getNeighbours(); 61 | for (var vertexLabel in self.vertices) { 62 | matrix[vertexLabel] = 0; 63 | if (vertexLabel in neighbours) { 64 | matrix[vertexLabel] = 1; 65 | } 66 | } 67 | 68 | return matrix; 69 | }; 70 | 71 | for (var vertex in vertices) { 72 | self.matrix[vertex] = self.build(vertices[vertex]); 73 | } 74 | 75 | return self.matrix; 76 | }; 77 | 78 | // And we export to node.js 79 | exports.Adjacency = Adjacency; 80 | -------------------------------------------------------------------------------- /lib/searches/depthfirstsearch.js: -------------------------------------------------------------------------------- 1 | var sys = require('sys'); 2 | 3 | /** 4 | * This object is used to execute depth first search traversals on graphs. It 5 | * returns an object containing a spanning tree, a postorder and a preorder. 6 | * 7 | * Author: David Coallier 8 | * License: New BSD 9 | * Date: 7th October, 2010 10 | */ 11 | 12 | /** 13 | * This is the depth first search class that is used to traverse graphs 14 | * using a depth first search traversal algorithms. 15 | * 16 | * The reason why the spanning tree is an object instead of an array like 17 | * preorder and postorder is because the spanning tree can return relevant 18 | * and interesting data about the vertices traversed in the graph. 19 | * 20 | * @param Object An object containing a list of vertices. 21 | */ 22 | var DepthFirstSearch = function(vertices) { 23 | this.vertices = vertices; 24 | this.visited = {}; 25 | this.spanningTree = {}; 26 | this.preorder = []; 27 | this.postorder = []; 28 | 29 | var self = this; 30 | 31 | /** 32 | * Execute the DFS search on a vertex. 33 | * 34 | * This method receives a vertex and subsequantly it's edges/neighbours. 35 | * by using a list of neighbours, we recursively build a list of edges 36 | * being traversed and visited. 37 | * 38 | * See the self.visited property if you want to know who's been visited. 39 | * 40 | * 1 41 | * / \ 42 | * 2 3 43 | * 44 | * @param Object A vertex object and it's ability to retrieve neighbours 45 | * @return Mixed Either nothing and appends to the post order or a recursive 46 | * call to itself passing the vertex object associated to a neighbour. 47 | */ 48 | this.search = function(vertex) { 49 | if (typeof(vertex) === 'undefined') return false; 50 | 51 | self.visited[vertex.label] = 1; 52 | self.preorder.push(vertex.label); 53 | 54 | if (self.vertices[vertex.label] !== undefined) { 55 | for (neighbour in self.vertices[vertex.label].getNeighbours()) { 56 | if (!(neighbour in self.visited) && self.vertices[neighbour] !== undefined) { 57 | self.spanningTree[neighbour] = self.vertices[neighbour]; 58 | self.search(self.vertices[neighbour]); 59 | } 60 | } 61 | } 62 | 63 | self.postorder.push(vertex.label); 64 | }; 65 | 66 | for (var vertex in vertices) { 67 | if (!(vertex in self.visited)) { 68 | self.spanningTree[vertex] = null; 69 | self.search(vertices[vertex]); 70 | } 71 | } 72 | 73 | return { 74 | spanningTree: self.spanningTree, 75 | preorder: self.preorder, 76 | postorder: self.postorder 77 | } 78 | }; 79 | 80 | // And we export to node.js 81 | exports.DepthFirstSearch = DepthFirstSearch; 82 | -------------------------------------------------------------------------------- /lib/graph.js: -------------------------------------------------------------------------------- 1 | /** 2 | * As Graph Theory allows mathematicians and computer scientists to study 3 | * mathematical structures used to model relations between certain collections 4 | * it only makes sense to have something to play with using Node.js as well. 5 | * 6 | * You can try to build a simple graph by doing the following: 7 | * 8 | * 9 | * var graph = require('./lib/graph'); 10 | * var vertex = require('./lib/vertex'); 11 | * var edge = require('./lib/edge'); 12 | * var sys = require('sys'); 13 | * 14 | * var graph = new graph.Graph(); 15 | * var VertexOne = new vertex.Vertex('label1', {}); 16 | * var VertexTwo = new vertex.Vertex('label2', {}); 17 | * 18 | * graph.addVertex(VertexOne); 19 | * graph.addVertex(VertexTwo); 20 | * 21 | * // or inline... 22 | * graph.addVertex(new vertex.Vertex('label3', {})); 23 | * 24 | * var EdgeExample = new edge.Edge('label1', 'label3', {}); 25 | * 26 | * graph.addEdge(EdgeExample); 27 | * sys.puts(sys.inspect(graph.edges())); 28 | * 29 | * 30 | * 31 | * Granted this code currently does not do much apart from building the Graphs but 32 | * the point is to add digraphs in the short future, and then have the ability to 33 | * build your graphs but then apply different types of sorting algorithms and build 34 | * different types of graphs and traversal, sorting, etc. 35 | * 36 | * Author: David Coallier 37 | * License: New BSD 38 | * Date: 6th October, 2010 39 | */ 40 | 41 | /** 42 | * This is the main Graph object to instantiate to 43 | * do some magicless-magic. 44 | * 45 | * 46 | * var graph = new Graph(); 47 | * 48 | */ 49 | var Graph = function() { 50 | this.vertices = {}; 51 | return this; 52 | }; 53 | 54 | /** 55 | * Lazyman's comparison of objects 56 | * 57 | * This method is used to compare two objects together to see 58 | * if they have the same properties or if they are the same. 59 | * 60 | * @param Object The first object to compare. 61 | * @param Object The second object to compare. 62 | * 63 | * @return Boolean whether or not the first object is identical 64 | * to the second one. 65 | */ 66 | Graph.prototype.compare = function(objectOne, objectTwo) { 67 | return JSON.stringify(objectOne) === JSON.stringify(objectTwo); 68 | }; 69 | 70 | /** 71 | * Get the vertices 72 | * 73 | * This method returns a list of all the vertices 74 | * in the graph. 75 | * 76 | * @return Array An array of vertices added in teh graph 77 | */ 78 | Graph.prototype.getVertices = function() { 79 | return this.vertices; 80 | }; 81 | 82 | /** 83 | * Return a list of edges for a graph 84 | * 85 | * This method is used to return a list of edges associated 86 | * to a graph. It returns an array of relation objects. 87 | * 88 | * @return Array of "relation" objects which contains a list of all 89 | * the vertices are related to. 90 | */ 91 | Graph.prototype.getEdges = function() { 92 | var i = 0, edges = []; 93 | for (var vertex in this.vertices) { 94 | if (edges[i] === undefined) { 95 | edges[i] = {}; 96 | edges[i][vertex] = []; 97 | } 98 | 99 | for (var x in this.vertices[vertex].edges) { 100 | edges[i][vertex].push(x); 101 | } 102 | 103 | ++i; 104 | } 105 | 106 | return edges; 107 | }; 108 | 109 | /** 110 | * Check if the graph has a vertex 111 | * 112 | * This method is used to identify whether or not 113 | * a graph has a certain vertex in the set of vertices. 114 | * 115 | * @param String The label associated to a vertex. 116 | * @return boolean Whether or not the vertex exists in the set this.vertices. 117 | */ 118 | Graph.prototype.hasVertex = function(vertexLabel) { 119 | return vertexLabel in this.vertices; 120 | }; 121 | 122 | /** 123 | * Add a vertex to the Graph 124 | * 125 | * This method is used to add a vertex to the graph. 126 | * When adding a new vertex to the set of vertices (or to the graph) 127 | * the vertex are identified by "label" which is the 128 | * identifier of the vertex. 129 | * 130 | * When instantiating a new "Vertex" the only required parameter 131 | * is the first one which is the label. 132 | * 133 | * 134 | * var Graph = new Graph(); 135 | * 136 | * var vertex = new Vertex('labelName', attrs); 137 | * Graph.addVertex(vertex); 138 | * Graph.addVertex(new Vertex('label2', {}); 139 | * 140 | * 141 | * 142 | * @param Vertex A Vertex object built from ./lib/vertex 143 | * @return void 144 | */ 145 | Graph.prototype.addVertex = function(vertex) { 146 | if (this.vertices[vertex.label] === undefined) { 147 | this.vertices[vertex.label] = vertex; 148 | } 149 | }; 150 | 151 | /** 152 | * Add an edge to the graph. 153 | * 154 | * This method is used to add an edge to the graph object. 155 | * By connecting two vertices together, we create an edge. 156 | * 157 | * 158 | * var graph = new Graph(); 159 | * graph.addVertex(new Vertex('label1')); 160 | * graph.addVertex(new Vertex('label2')); 161 | * graph.addEdge(new Edge('label1', 'label2', {})); 162 | * 163 | * 164 | * @param Edge An "Edge" object acquired from ./lib/edge 165 | * @return void 166 | */ 167 | Graph.prototype.addEdge = function(edge) { 168 | var vertexOne = edge.vertexOne; 169 | var vertexTwo = edge.vertexTwo; 170 | 171 | if (!(vertexOne in this.vertices[vertexTwo].edges) && 172 | !(vertexTwo in this.vertices[vertexOne].edges)) 173 | { 174 | this.vertices[vertexOne].edges[vertexTwo] = {}; 175 | this.vertices[vertexTwo].edges[vertexOne] = {}; 176 | } 177 | }; 178 | 179 | /** 180 | * Delete a vertex 181 | * 182 | * This method, as the name suggests, deletes a vertex and it's edges 183 | * from a graph object. 184 | * 185 | * @param String The vertex to delete. 186 | * @return void 187 | */ 188 | Graph.prototype.deleteVertex = function(vertexLabel) { 189 | delete this.vertices[vertexLabel]; 190 | }; 191 | 192 | /** 193 | * Delete an edge 194 | * 195 | * This method, once again as the name suggests, deletes an 196 | * edge from a graph. By passing the edge object to delete, we 197 | * can identify which vertices are affected and cherry pick which 198 | * edges to remove. 199 | * 200 | * @param Edge An "Edge" object acquired from ./lib/edge 201 | * @return void 202 | */ 203 | Graph.prototype.deleteEdge = function(edge) { 204 | delete this.vertices[edge.vertexOne].edges[edge.vertexTwo]; 205 | delete this.vertices[edge.vertexTwo].edges[edge.vertexOne]; 206 | }; 207 | 208 | /** 209 | * Verifies if a graph has a certain edge 210 | * 211 | * This method is used to verify if a certain graph contains an edge 212 | * object that is passed to it - That is a "link" to 2 single vertices. 213 | * 214 | * @param Edge An "Edge" object acquired from ./lib/edge 215 | * @return Boolean Whether it exists or not in the set of vertices and graph. 216 | */ 217 | Graph.prototype.hasEdge = function(edge) { 218 | var vertexOne = edge.vertexOne; 219 | var vertexTwo = edge.vertexTwo; 220 | 221 | for (var vertex in this.vertices) { 222 | if (vertex.edges[vertexOne] !== undefined && vertex.edges[vertexTwo] !== undefined) { 223 | return true; 224 | } 225 | } 226 | 227 | return false; 228 | }; 229 | 230 | /** 231 | * Return the order of a certain vertex 232 | * 233 | * This method is used only to return the current object 234 | * position of a certain vertex in a graph. 235 | * 236 | * @param String The label associated to a vertex. 237 | * @return Int The position of the vertex in the vertices set. 238 | */ 239 | Graph.prototype.vertexOrder = function(vertexLabel) { 240 | var position = 0; 241 | for (var vertex in this.vertices) { 242 | if (vertex.label == vertexLabel) { 243 | return position; 244 | } 245 | ++position; 246 | } 247 | }; 248 | 249 | // And we export to node.js 250 | exports.Graph = Graph; 251 | --------------------------------------------------------------------------------