def <<(other)
c = Connection.new
c.end = other
+ other.edges << self unless other.edges.include? self
self.connections << c
self
end
# 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
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
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
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
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