Skip to content
Browse files

Added the initial node-graph module for graph theory and node.js fun

  • Loading branch information...
0 parents commit 31377eaadb7ecc31deb810738c07b68de584422b David Coallier committed Oct 6, 2010
Showing with 444 additions and 0 deletions.
  1. +57 −0 README.md
  2. +18 −0 examples/example1.js
  3. +29 −0 lib/edge.js
  4. +263 −0 lib/graph.js
  5. +32 −0 lib/vertex.js
  6. +23 −0 package.json
  7. +22 −0 server.js
57 README.md
@@ -0,0 +1,57 @@
+node.js Graph Theory module
+============================
+
+> Maths is fun and so is node.js so why not use them together!
+
+introduction
+------------
+
+The goal of this "node-graph" module is to provide a framework for working with graphs
+from within node.js.
+
+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).
+
+After building the graphs, it will allow developers to traverse, sort and play with the graphs using the most popular algorithms.
+
+Currently in EXTREMELY early stages, feel free to contribute!
+
+synopsis
+--------
+
+Creating a basic Graph object:
+
+ var sys = require('sys');
+ var graph = require('./lib/graph');
+
+ var Graph = new graph.Graph();
+
+Now that you have your Graph object, you should add vertices. In order to do that, do:
+
+ var vertex = require('./lib/vertex');
+ var vertexOne = new vertex.Vertex('label1', {});
+ Graph.addVertex(vertexOne);
+
+To make that graph more interesting, you'll need to add a second vertex. This time, you can do it inline like such:
+
+ Graph.addVertex(new vertex.Vertex('label2', {}));
+
+Once you are done, you can now create an edge to link those two vertices together:
+
+ Graph.addEdge(new Edge('label1', 'label2', {}));
+
+Now the next step is to build more stuff on top of that :-)
+
+
+license
+-------
+
+Released under the New BSD License.
+
+Copyright (c) 2010 David Coallier
+
+
+disclaimer
+----------
+
+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.
+
18 examples/example1.js
@@ -0,0 +1,18 @@
+var sys = require('sys');
+var edge = require('./lib/edge');
+var graph = require('./lib/graph');
+var vertex = require('./lib/vertex');
+
+var Graph = new graph.Graph();
+var VertexOne = new vertex.Vertex('nameOne', {});
+var VertexTwo = new vertex.Vertex('nameTwo', {});
+var VertexThree = new vertex.Vertex('nameThree', {});
+
+Graph.addVertex(VertexOne);
+Graph.addVertex(VertexTwo);
+Graph.addVertex(VertexThree);
+
+Graph.addEdge(new edge.Edge('nameOne', 'nameTwo', {}));
+Graph.addEdge(new edge.Edge('nameOne', 'nameThree', {}));
+
+var neighbours = Graph.neighbours('nameThree');
29 lib/edge.js
@@ -0,0 +1,29 @@
+/**
+ * This is the class used to build a connection between two Vertices.
+ *
+ * Once created and associated to a graph, the edge becomes part of E(G).
+ *
+ * Author: David Coallier <david.coallier@gmail.com>
+ * License: New BSD <http://www.opensource.org/licenses/bsd-license.php>
+ * Date: 6th October, 2010
+ */
+
+/**
+ * This is the Edge class that is used to do some magicless-magic.
+ *
+ * <code>
+ * var edge = new Edge('vertexLabelOne', 'vertexLabelTwo', {});
+ * </code>
+ *
+ * @param String The label of the first vertex to associate with the second.
+ * @param String The label of the second vertex to associate with the first one.
+ * @param Object A list of attributes. Could be weight, direction, bidirection, etc.
+ */
+var Edge = function(vertexOne, vertexTwo, attributes) {
+ this.vertexOne = vertexOne;
+ this.vertexTwo = vertexTwo;
+ this.attributes = attributes || {};
+};
+
+// And we export to node.js
+exports.Edge = Edge;
263 lib/graph.js
@@ -0,0 +1,263 @@
+/**
+ * As Graph Theory allows mathematicians and computer scientists to study
+ * mathematical structures used to model relations between certain collections
+ * it only makes sense to have something to play with using Node.js as well.
+ *
+ * You can try to build a simple graph by doing the following:
+ *
+ * <code>
+ * var graph = require('./lib/graph');
+ * var vertex = require('./lib/vertex');
+ * var edge = require('./lib/edge');
+ * var sys = require('sys');
+ *
+ * var graph = new graph.Graph();
+ * var VertexOne = new vertex.Vertex('label1', {});
+ * var VertexTwo = new vertex.Vertex('label2', {});
+ *
+ * graph.addVertex(VertexOne);
+ * graph.addVertex(VertexTwo);
+ *
+ * // or inline...
+ * graph.addVertex(new vertex.Vertex('label3', {}));
+ *
+ * var EdgeExample = new edge.Edge('label1', 'label3', {});
+ *
+ * graph.addEdge(EdgeExample);
+ * sys.puts(sys.inspect(graph.edges()));
+ *
+ * </code>
+ *
+ * Granted this code currently does not do much apart from building the Graphs but
+ * the point is to add digraphs in the short future, and then have the ability to
+ * build your graphs but then apply different types of sorting algorithms and build
+ * different types of graphs and traversal, sorting, etc.
+ *
+ * Author: David Coallier <david.coallier@gmail.com>
+ * License: New BSD <http://www.opensource.org/licenses/bsd-license.php>
+ * Date: 6th October, 2010
+ */
+
+/**
+ * This is the main Graph object to instantiate to
+ * do some magicless-magic.
+ *
+ * <code>
+ * var graph = new Graph();
+ * </code>
+ */
+var Graph = function() {
+ this.vertices = {};
+};
+
+/**
+ * Lazyman's comparison of objects
+ *
+ * This method is used to compare two objects together to see
+ * if they have the same properties or if they are the same.
+ *
+ * @param Object The first object to compare.
+ * @param Object The second object to compare.
+ *
+ * @return Boolean whether or not the first object is identical
+ * to the second one.
+ */
+Graph.prototype.compare = function(objectOne, objectTwo) {
+ return JSON.stringify(objectOne) === JSON.stringify(objectTwo);
+};
+
+/**
+ * Get the vertices
+ *
+ * This method returns a list of all the vertices
+ * in the graph.
+ *
+ * @return Array An array of vertices added in teh graph
+ */
+Graph.prototype.vertices = function() {
+ return this.vertices;
+};
+
+/**
+ * Get the neighbours of a vertex
+ *
+ * This method returns a list of the neighbours of a certain
+ * vertex. It basically return the edges of that vertex which
+ * contains the labels of each vertex that are neighbours.
+ *
+ * @param String The label associated to a vertex.
+ * @return Array an array of neighbour vertices.
+ */
+Graph.prototype.neighbours = function(vertexLabel) {
+ return this.vertices[vertexLabel].edges;
+};
+
+/**
+ * Return a list of edges for a graph
+ *
+ * This method is used to return a list of edges associated
+ * to a graph. It returns an array of relation objects.
+ *
+ * @return Array of "relation" objects which contains a list of all
+ * the vertices are related to.
+ */
+Graph.prototype.edges = function() {
+ var i = 0, edges = [];
+ for (var vertex in this.vertices) {
+ if (edges[i] === undefined) {
+ edges[i] = {};
+ edges[i][vertex] = [];
+ }
+
+ for (var x in this.vertices[vertex].edges) {
+ edges[i][vertex].push(x);
+ }
+
+ ++i;
+ }
+
+ return edges;
+};
+
+/**
+ * Check if the graph has a vertex
+ *
+ * This method is used to identify whether or not
+ * a graph has a certain vertex in the set of vertices.
+ *
+ * @param String The label associated to a vertex.
+ * @return boolean Whether or not the vertex exists in the set this.vertices.
+ */
+Graph.prototype.hasVertex = function(vertexLabel) {
+ return vertexLabel in this.vertices;
+};
+
+/**
+ * Add a vertex to the Graph
+ *
+ * This method is used to add a vertex to the graph.
+ * When adding a new vertex to the set of vertices (or to the graph)
+ * the vertex are identified by "label" which is the
+ * identifier of the vertex.
+ *
+ * When instantiating a new "Vertex" the only required parameter
+ * is the first one which is the label.
+ *
+ * <code>
+ * var Graph = new Graph();
+ *
+ * var vertex = new Vertex('labelName', attrs);
+ * Graph.addVertex(vertex);
+ * Graph.addVertex(new Vertex('label2', {});
+ *
+ * </code>
+ *
+ * @param Vertex A Vertex object built from ./lib/vertex
+ * @return void
+ */
+Graph.prototype.addVertex = function(vertex) {
+ if (this.vertices[vertex.label] === undefined) {
+ this.vertices[vertex.label] = vertex;
+ }
+};
+
+/**
+ * Add an edge to the graph.
+ *
+ * This method is used to add an edge to the graph object.
+ * By connecting two vertices together, we create an edge.
+ *
+ * <code>
+ * var graph = new Graph();
+ * graph.addVertex(new Vertex('label1'));
+ * graph.addVertex(new Vertex('label2'));
+ * graph.addEdge(new Edge('label1', 'label2', {}));
+ * </code>
+ *
+ * @param Edge An "Edge" object acquired from ./lib/edge
+ * @return void
+ */
+Graph.prototype.addEdge = function(edge) {
+ var vertexOne = edge.vertexOne;
+ var vertexTwo = edge.vertexTwo;
+
+ if (!(vertexOne in this.vertices[vertexTwo].edges) &&
+ !(vertexTwo in this.vertices[vertexOne].edges))
+ {
+ this.vertices[vertexOne].edges[vertexTwo] = {};
+ this.vertices[vertexTwo].edges[vertexOne] = {};
+ }
+};
+
+/**
+ * Delete a vertex
+ *
+ * This method, as the name suggests, deletes a vertex and it's edges
+ * from a graph object.
+ *
+ * @param String The vertex to delete.
+ * @return void
+ */
+Graph.prototype.deleteVertex = function(vertexLabel) {
+ delete this.vertices[vertexLabel];
+};
+
+/**
+ * Delete an edge
+ *
+ * This method, once again as the name suggests, deletes an
+ * edge from a graph. By passing the edge object to delete, we
+ * can identify which vertices are affected and cherry pick which
+ * edges to remove.
+ *
+ * @param Edge An "Edge" object acquired from ./lib/edge
+ * @return void
+ */
+Graph.prototype.deleteEdge = function(edge) {
+ delete this.vertices[edge.vertexOne].edges[edge.vertexTwo];
+ delete this.vertices[edge.vertexTwo].edges[edge.vertexOne];
+};
+
+/**
+ * Verifies if a graph has a certain edge
+ *
+ * This method is used to verify if a certain graph contains an edge
+ * object that is passed to it - That is a "link" to 2 single vertices.
+ *
+ * @param Edge An "Edge" object acquired from ./lib/edge
+ * @return Boolean Whether it exists or not in the set of vertices and graph.
+ */
+Graph.prototype.hasEdge = function(edge) {
+ var vertexOne = edge.vertexOne;
+ var vertexTwo = edge.vertexTwo;
+
+ for (var vertex in this.vertices) {
+ if (vertex.edges[vertexOne] !== undefined && vertex.edges[vertexTwo] !== undefined) {
+ return true;
+ }
+ }
+
+ return false;
+};
+
+/**
+ * Return the order of a certain vertex
+ *
+ * This method is used only to return the current object
+ * position of a certain vertex in a graph.
+ *
+ * @param String The label associated to a vertex.
+ * @return Int The position of the vertex in the vertices set.
+ */
+Graph.prototype.vertexOrder = function(vertexLabel) {
+ var position = 0;
+ for (var vertex in this.vertices) {
+ if (vertex.label == vertexLabel) {
+ return position;
+ }
+ ++position;
+ }
+};
+
+// And we export to node.js
+exports.Graph = Graph;
32 lib/vertex.js
@@ -0,0 +1,32 @@
+/**
+ * This is the object to create a vertex - or a node - or a dot which are all the same. For
+ * the sake of clarity, this node-graph module is going to exploit the term "vertex" and
+ * "vertices".
+ *
+ * Once created and associated to a graph, the vertex is now a member of the vertex set
+ * of graph G, or V(G).
+ *
+ * Author: David Coallier <david.coallier@gmail.com>
+ * License: New BSD <http://www.opensource.org/licenses/bsd-license.php>
+ * Date: 6th October, 2010
+ */
+
+/**
+ * This is the Vertex class that is used to do some magicless-magic.
+ *
+ * <code>
+ * var VertexOne = new Vertex('vertexLabelOne', {});
+ * </code>
+ *
+ * @param String The label to associate to this vertex v.
+ * @param Object A list of different types of attributes associated
+ * to this vertex.
+ */
+var Vertex = function(label, attributes) {
+ this.label = label;
+ this.edges = {};
+ this.attributes = attributes || {};
+};
+
+// And we export to node.js
+exports.Vertex = Vertex;
23 package.json
@@ -0,0 +1,23 @@
+{
+ "name": "node-graph",
+ "author": "David Coallier",
+ "email": "david.coallier@gmail.com",
+ "dependencies": [],
+ "contributors": [],
+ "keywords": [
+ "mathematics",
+ "computer science",
+ "graph theory",
+ "graph",
+ ],
+ "mappings":{},
+ "overlay": {},
+ "githubName": "node-graph",
+ "engines": {"node":">=0.1.94"},
+ "type": "zip",
+ "version": "0.1",
+ "location": "http://github.com/davidcoallier/node-graph",
+ "license":"BSD"
+}
+
+
22 server.js
@@ -0,0 +1,22 @@
+var sys = require('sys');
+var edge = require('./lib/edge');
+var graph = require('./lib/graph');
+var vertex = require('./lib/vertex');
+
+var Graph = new graph.Graph();
+var VertexOne = new vertex.Vertex('nameOne', {});
+var VertexTwo = new vertex.Vertex('nameTwo', {});
+var VertexThree = new vertex.Vertex('nameThree', {});
+
+Graph.addVertex(VertexOne);
+Graph.addVertex(VertexTwo);
+Graph.addVertex(VertexThree);
+
+Graph.addEdge(new edge.Edge('nameOne', 'nameTwo', {}));
+Graph.addEdge(new edge.Edge('nameOne', 'nameThree', {}));
+
+var neighbours = Graph.neighbours('nameThree');
+
+//sys.puts(sys.inspect(Graph.edges()));
+//sys.puts(sys.inspect(neighbours));
+//sys.puts(sys.inspect(Graph));

0 comments on commit 31377ea

Please sign in to comment.
Something went wrong with that request. Please try again.