From: Neil Smith <neil.github@njae.me.uk>
Date: Mon, 5 Mar 2012 16:56:49 +0000 (+0000)
Subject: Merge branch 'master' into graph-product
X-Git-Url: https://git.njae.me.uk/?a=commitdiff_plain;h=29f4392b0058eb16dc326ae5629af4afc480987e;hp=5afeed673400a0d1e2c1c0d6b6f286f65723f405;p=graph.njae.git

Merge branch 'master' into graph-product
---

diff --git a/Gemfile b/Gemfile
index d6b498f..f677f3d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -6,9 +6,8 @@ source "http://rubygems.org"
 # Add dependencies to develop your gem here.
 # Include everything needed to run rake, tests, features, etc.
 group :development do
-  gem "rspec", "~> 2.6.0"
-  gem "bundler", "~> 1.0.0"
-  gem "jeweler", "~> 1.6.2"
-  gem "rcov", ">= 0"
+  gem "rspec"
+  gem "bundler"
+  gem "jeweler"
   gem "rdoc"
 end
diff --git a/Gemfile.lock b/Gemfile.lock
index 024a43a..9b1b95b 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,30 +1,31 @@
 GEM
   remote: http://rubygems.org/
   specs:
-    diff-lcs (1.1.2)
+    diff-lcs (1.1.3)
     git (1.2.5)
-    jeweler (1.6.2)
+    jeweler (1.8.3)
       bundler (~> 1.0)
       git (>= 1.2.5)
       rake
-    rake (0.9.2)
-    rcov (0.9.9)
-    rdoc (3.7)
-    rspec (2.6.0)
-      rspec-core (~> 2.6.0)
-      rspec-expectations (~> 2.6.0)
-      rspec-mocks (~> 2.6.0)
-    rspec-core (2.6.4)
-    rspec-expectations (2.6.0)
+      rdoc
+    json (1.6.5)
+    rake (0.9.2.2)
+    rdoc (3.12)
+      json (~> 1.4)
+    rspec (2.8.0)
+      rspec-core (~> 2.8.0)
+      rspec-expectations (~> 2.8.0)
+      rspec-mocks (~> 2.8.0)
+    rspec-core (2.8.0)
+    rspec-expectations (2.8.0)
       diff-lcs (~> 1.1.2)
-    rspec-mocks (2.6.0)
+    rspec-mocks (2.8.0)
 
 PLATFORMS
   ruby
 
 DEPENDENCIES
-  bundler (~> 1.0.0)
-  jeweler (~> 1.6.2)
-  rcov
+  bundler
+  jeweler
   rdoc
-  rspec (~> 2.6.0)
+  rspec
diff --git a/lib/graph.njae/edge.rb b/lib/graph.njae/edge.rb
index f38a32b..4a1ba79 100644
--- a/lib/graph.njae/edge.rb
+++ b/lib/graph.njae/edge.rb
@@ -10,8 +10,8 @@ module GraphNjae
   # Each connection is handled by a Graph::Connection object, so that each end
   # of the Edge can have it's own attributes.
   class Edge < OpenStruct
-    def initialize
-      super
+    def initialize(values = {})
+      super(values)
       self.connections = []
       self
     end
@@ -20,6 +20,7 @@ module GraphNjae
     def <<(other)
       c = Connection.new
       c.end = other
+      other.edges << self unless other.edges.include? self
       self.connections << c
       self
     end
@@ -38,8 +39,8 @@ module GraphNjae
   # A connection between an Edge and a Vertex.The connection can have arbitrary attributes,
   # treated as method names.
   class Connection < OpenStruct
-    def initialize
-      super
+    def initialize(values = {})
+      super(values)
       self
     end
   end
diff --git a/lib/graph.njae/graph.rb b/lib/graph.njae/graph.rb
index e08a1ad..faaaf46 100644
--- a/lib/graph.njae/graph.rb
+++ b/lib/graph.njae/graph.rb
@@ -7,8 +7,8 @@ module GraphNjae
   # A container for all the parts of a graph.  The graph can have arbitrary attributes,
   # treated as method names.
   class Graph < OpenStruct
-    def initialize
-      super
+    def initialize(values = {})
+      super(values)
       self.edges = Array.new
       self.vertices = Array.new
       self
@@ -23,5 +23,40 @@ module GraphNjae
       end
       self
     end
-  end
+    
+    # Connects two vertices, creating and storing a new edge
+    # Also adds the vertices, unless they're already in the graph
+    def connect(vertex1, vertex2)
+      self.vertices << vertex1 unless self.vertices.include? vertex1
+      self.vertices << vertex2 unless self.vertices.include? vertex2
+      edge = Edge.new
+      self.edges << edge
+      edge << vertex1 << vertex2
+    end
+    
+    # Form a product graph of this graph and the other.
+    # Return the product graph.
+    def product(other)
+      product_graph = Graph.new
+      self.vertices.each do |v1|
+        other.vertices.each do |v2|
+          product_graph << Vertex.new({:g1_vertex => v1, :g2_vertex => v2})
+        end
+      end
+      self.edges.each do |e1|
+        e1_vertices = e1.vertices
+        other.edges.each do |e2|
+          e2_vertices = e2.vertices
+          source = product_graph.vertices.find {|v| v.g1_vertex == e1_vertices[0] and v.g2_vertex == e2_vertices[0]}
+          destination = product_graph.vertices.find {|v| v.g1_vertex == e1_vertices[1] and v.g2_vertex == e2_vertices[1]}
+          product_graph.connect source, destination
+          source = product_graph.vertices.find {|v| v.g1_vertex == e1_vertices[0] and v.g2_vertex == e2_vertices[1]}
+          destination = product_graph.vertices.find {|v| v.g1_vertex == e1_vertices[1] and v.g2_vertex == e2_vertices[0]}
+          product_graph.connect source, destination
+        end
+      end
+      product_graph
+    end
+    
+  end # class
 end
diff --git a/lib/graph.njae/vertex.rb b/lib/graph.njae/vertex.rb
index 4a75b6d..aeabe30 100644
--- a/lib/graph.njae/vertex.rb
+++ b/lib/graph.njae/vertex.rb
@@ -6,8 +6,8 @@ module GraphNjae
   # A vertex in a graph. The edge can have arbitrary attributes,treated as 
   # method names.
   class Vertex < OpenStruct
-    def initialize
-      super
+    def initialize(values = {})
+      super(values)
       self.edges = []
       self
     end
@@ -17,8 +17,8 @@ module GraphNjae
     def connect(other)
       e = Edge.new
       e << self << other
-      self.edges << e
-      other.edges << e unless self === other
+      # self.edges << e
+      # other.edges << e unless self === other
       e
     end
     
diff --git a/spec/graph/edge_spec.rb b/spec/graph/edge_spec.rb
index 2e7dbfc..8373864 100644
--- a/spec/graph/edge_spec.rb
+++ b/spec/graph/edge_spec.rb
@@ -8,6 +8,15 @@ module GraphNjae
         e = Edge.new
         e.connections.should be_empty
       end
+      
+      it "creates an edge with some parameters" do
+        e = Edge.new :value1 => 1, :value2 => "value2", :value3 => :v3
+        e.value1.should == 1
+        e.value2.should == "value2"
+        e.value3.should == :v3
+        e.value4.should be_nil
+      end
+
     end # #initialize
     
     describe "adds attribues" do
@@ -26,11 +35,13 @@ module GraphNjae
         e.should have(1).connections
         e.should have(1).vertices
         e.vertices.should include(v1)
+        v1.edges.should include(e)
         e << v2
         e.should have(2).connections
         e.should have(2).vertices
         e.vertices.should include(v1)
         e.vertices.should include(v2)
+        v2.edges.should include(e)
       end
       
       it "adds several vertices to an edge" do
diff --git a/spec/graph/graph_spec.rb b/spec/graph/graph_spec.rb
index 09cc6a4..670d252 100644
--- a/spec/graph/graph_spec.rb
+++ b/spec/graph/graph_spec.rb
@@ -16,6 +16,15 @@ module GraphNjae
         g.edges.should be_empty
         g.vertices.should be_empty
       end
+      
+      it "creates a graph with some parameters" do
+        g = Graph.new :value1 => 1, :value2 => "value2", :value3 => :v3
+        g.value1.should == 1
+        g.value2.should == "value2"
+        g.value3.should == :v3
+        g.value4.should be_nil
+      end
+
     end # #initialize
       
     describe "adds attribues" do
@@ -75,8 +84,51 @@ module GraphNjae
 
     describe "connect" do
       it "adds and records an edge between vertices" do
+        g.vertices.should be_empty
+        g.edges.should be_empty
+        v1 = Vertex.new(:name => :v1)
+        v2 = Vertex.new(:name => :v2)
+        g.connect(v1, v2)
+        
+        g.should have(2).vertices
+        g.vertices.should include(v1)
+        g.vertices.should include(v2)
+        g.should have(1).edges
       end
     end # #connect
     
+    describe "product" do
+      it "finds a product graph of a pair of one-vertex graphs" do
+        g1 = Graph.new
+        g2 = Graph.new
+        g1v1 = Vertex.new
+        g1 << g1v1
+        g2v1 = Vertex.new
+        g2 << g2v1
+        product = g1.product g2
+        
+        product.should have(1).vertices
+        product.vertices.first.g1_vertex.should == g1v1
+        product.vertices.first.g2_vertex.should == g2v1
+        product.edges.should be_empty
+      end
+
+      it "finds a product graph of a pair of simple graphs" do
+        g1 = Graph.new
+        g2 = Graph.new
+        g1v1 = Vertex.new(:name => :g1v1)
+        g1v2 = Vertex.new(:name => :g1v2)
+        g1.connect(g1v1, g1v2)
+        g2v1 = Vertex.new(:name => :g2v1)
+        g2v2 = Vertex.new(:name => :g2v2)
+        g2.connect(g2v1, g2v2)
+        pg = g1.product g2
+        
+        pg.should have(4).vertices
+        pg.should have(2).edges
+      end
+
+    end
+    
   end
 end
diff --git a/spec/graph/vertex_spec.rb b/spec/graph/vertex_spec.rb
index 49ce58c..b193bc8 100644
--- a/spec/graph/vertex_spec.rb
+++ b/spec/graph/vertex_spec.rb
@@ -9,6 +9,14 @@ module GraphNjae
         v = Vertex.new
         v.edges.should be_empty
       end
+      
+      it "creates a vertex with some parameters" do
+        v = Vertex.new :value1 => 1, :value2 => "value2", :value3 => :v3
+        v.value1.should == 1
+        v.value2.should == "value2"
+        v.value3.should == :v3
+        v.value4.should be_nil
+      end
     end # #initialize
     
     describe "adds attribues" do