Product graphs working initially
authorNeil Smith <neil.github@njae.me.uk>
Fri, 10 Feb 2012 20:02:29 +0000 (20:02 +0000)
committerNeil Smith <neil.github@njae.me.uk>
Fri, 10 Feb 2012 20:02:29 +0000 (20:02 +0000)
lib/graph.njae/edge.rb
lib/graph.njae/graph.rb
lib/graph.njae/vertex.rb
spec/graph/edge_spec.rb
spec/graph/graph_spec.rb

index 814360ba818818cd43df1cf0859208d324098c20..4a1ba790d4f33570f53525cbd3f3c23660135240 100644 (file)
@@ -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
index b1de59b324be4297ceed4ef6c1a8dd2fdfe890df..09d6137f0d96edc4b6a9936ad74adac38d972a17 100644 (file)
@@ -24,18 +24,38 @@ module GraphNjae
       self
     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 new graph.
     def product(other)
       product_graph = Graph.new
       self.vertices.each do |v1|
         other.vertices.each do |v2|
-          product_vertex = Vertex.new
-          product_vertex.left_node = v1
-          product_vertex.right_node = v2
-          product_graph << product_vertex
+          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]}
+          pe1 = 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]}
+          pe2 = product_graph.connect source, destination
         end
       end
+      product_graph
     end
     
   end # class
index 6b34351740c04c0754a5e431f1ea38bd7773a0a0..aeabe30559be5f1f0a4cf1acf19a7607ff6a1249 100644 (file)
@@ -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
     
index d139667126886b8c382368378ab1c43aafe44fc5..837386421ef66ae70e726a8404b9e9a9f6669121 100644 (file)
@@ -35,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
index 5da61f5ef1b2bd627e0d285bb873401c6ea28c17..670d252892cbf0a3d1f6bbc09f0a04915ed61d63 100644 (file)
@@ -84,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