Permalink
Browse files

Able to merge vertices using 3 strings. Fixed dup. Part of #7

  • Loading branch information...
1 parent dc52970 commit 7aa873eb99094d540e677b843d61020e038a443a @D4L committed Mar 3, 2013
@@ -27,3 +27,5 @@ class Graph
require "abstract_graph/graph/change_edge_name"
require "abstract_graph/graph/is_adjacent"
require "abstract_graph/graph/adjacency_list"
+require "abstract_graph/graph/merge_vertices"
+require "abstract_graph/graph/get_edge_name"
@@ -7,6 +7,7 @@ class Graph
def dup
other = Graph.new
other.vertices = @vertices.dup
+ other.edges = @edges.dup
other
end
@@ -0,0 +1,24 @@
+# required in "abstract_graph/graph"
+
+module AbstractGraph
+ class Graph
+
+ # returns the edge connecting v1 and v2, if there is no
+ # edge, then it returns nil
+ # p: String v1, v2 represents the names of the vertices
+ def get_edge_name( v1, v2 )
+ vertices = [v1, v2].sort!
+
+ @edges.each_value do |e|
+ eVertices = e.vertices.map do |v|
+ v.name
+ end.sort
+
+ return e.name if eVertices == vertices
+ end
+
+ nil
+ end
+
+ end
+end
@@ -0,0 +1,64 @@
+# required in "abstract_graph/graph"
+
+module AbstractGraph
+ class Graph
+
+ # returns a replicated graph where the vertices with names
+ # v1 and v2 merge together to a vertex named vmerged and
+ # the edges that were adjacent to v1 and v2 are now
+ # adjacent to vmerged
+ # p: String v1, v2 represents the names of the vertices
+ # String vmerged represents the name of the merged vertex
+ # e: the edges prioritize v1 to v2 if there are any conflicts
+ def merge_vertices( v1, v2, vmerged )
+ other = self.dup
+ other.merge_vertices! v1, v2, vmerged
+ end
+
+ # same as before except operates on the current graph
+ def merge_vertices!( v1, v2, vmerged )
+
+ # first delete the edge in between
+ edgeInBetween = get_edge_name v1, v2
+ delete_edge!( edgeInBetween ) if edgeInBetween
+
+ # get the list of connections we want vmerged to be merged with
+ finalConnections = {}
+ @edges.each do |name, e|
+ [0, 1].each do |vertexId|
+ [v1, v2].each do |vcheck|
+
+ # check if the edge contains our vertices
+ if e.vertices[vertexId].name == vcheck
+ otherVertex = e.vertices[(vertexId+1)%2].name
+
+ # check if the vertex already existed
+ # if it did, we want to prioritize v1
+ if finalConnections[otherVertex]
+ if vcheck == v1
+ finalConnections[otherVertex] = name
+ end
+ else
+ finalConnections[otherVertex] = name
+ end
+ delete_edge! name
+ end
+ end
+ end
+ end
+
+ # delete the vertices
+ delete_vertex! v1
+ delete_vertex! v2
+
+ # add vmerged and connect it to the adjacent vertices
+ add_vertex vmerged
+ finalConnections.each do |vertexName, name|
+ add_edge name, vertexName, vmerged
+ end
+
+ self
+ end
+
+ end
+end
@@ -7,6 +7,8 @@ module Composition
before :each do
@graph = Graph.new
@graph.add_vertex "MyVertex"
+ @graph.add_vertex "MyOtherVertex"
+ @graph.add_edge "MyEdge", "MyVertex", "MyOtherVertex"
end
describe "#dup" do
@@ -24,10 +26,15 @@ module Composition
graphdup.has_vertex?( "MyVertex" ).should be_true
end
+ it "copies over the existing edges" do
+ graphdup = @graph.dup
+ graphdup.has_edge?( "MyEdge" ).should be_true
+ end
+
it "will not modify the original if it is modified" do
graphdup = @graph.dup
graphdup.vertices.clear
- @graph.vertices.size.should == 1
+ @graph.vertices.size.should == 2
end
end
@@ -0,0 +1,40 @@
+require 'spec_helper'
+
+module AbstractGraph
+ module Composition
+ describe Graph do
+
+ before :all do
+ # create the 3-path
+ @v1 = "v1"
+ @v2 = "v2"
+ @v3 = "v3"
+ @e1 = "e1"
+ @e2 = "e2"
+ end
+
+ before :each do
+ @graph = Graph.new
+ @graph.add_vertex @v1
+ @graph.add_vertex @v2
+ @graph.add_vertex @v3
+ @graph.add_edge @e1, @v1, @v2
+ @graph.add_edge @e2, @v3, @v2
+ end
+
+ describe "#get_edge_name(String,String)" do
+
+ it "returns the name of the edge connecting the two string vertices" do
+ @graph.get_edge_name( @v1, @v2 ).should eql(@e1)
+ @graph.get_edge_name( @v2, @v3 ).should eql(@e2)
+ end
+
+ it "returns nil if the two vertices are not adjacent" do
+ @graph.get_edge_name( @v1, @v3).should be_nil
+ end
+
+ end
+
+ end
+ end
+end
@@ -0,0 +1,125 @@
+require 'spec_helper'
+
+module AbstractGraph
+ module Composition
+ describe Graph do
+
+ before :all do
+ # we're building a 4-cycle!
+ @v1 = "v1"
+ @v2 = "v2"
+ @v3 = "v3"
+ @v4 = "v4"
+ @vmerged = "vMerged"
+ @e1 = "e1"
+ @e2 = "e2"
+ @e3 = "e3"
+ @e4 = "e4"
+ end
+
+ before :each do
+ @g = Graph.new
+ @g.add_vertex @v1
+ @g.add_vertex @v2
+ @g.add_vertex @v3
+ @g.add_vertex @v4
+ @g.add_edge @e1, @v1, @v2
+ @g.add_edge @e2, @v2, @v3
+ @g.add_edge @e3, @v3, @v4
+ @g.add_edge @e4, @v4, @v1
+ end
+
+ describe "#merge_vertices(String,String,String)" do
+
+ it "returns an object of type graph" do
+ @g.merge_vertices( @v1, @v2, @vmerged ).should be_an_instance_of(Graph)
+ end
+
+ it "does not modify the original graph" do
+ @g.merge_vertices @v1, @v2, @vmerged
+ @g.has_vertex?( @v1 ).should be_true
+ @g.has_vertex?( @v2 ).should be_true
+ end
+
+ it "removes the first two vertices" do
+ @gnext = @g.merge_vertices @v1, @v2, @vmerged
+ @gnext.has_vertex?( @v1 ).should be_false
+ @gnext.has_vertex?( @v2 ).should be_false
+ end
+
+ it "creates a vertex of the third string" do
+ @gnext = @g.merge_vertices @v1, @v2, @vmerged
+ @gnext.has_vertex?( @vmerged ).should be_true
+ end
+
+ it "removes the edge connecting the two vertices" do
+ @gnext = @g.merge_vertices @v1, @v2, @vmerged
+ @gnext.has_edge?( @e1 ).should be_false
+ end
+
+ it "connects the merged vertex with the vertices adjacent to the previous two" do
+ @gnext = @g.merge_vertices @v1, @v2, @vmerged
+ @gnext.is_adjacent?( @vmerged, @v3 ).should be_true
+ @gnext.is_adjacent?( @vmerged, @v4 ).should be_true
+ @gnext = @g.merge_vertices @v1, @v3, @vmerged
+ @gnext.is_adjacent?( @vmerged, @v2 ).should be_true
+ @gnext.is_adjacent?( @vmerged, @v4 ).should be_true
+ end
+
+ it "preserves the edges of the first vertex over the second" do
+ @gnext = @g.merge_vertices @v1, @v3, @vmerged
+ @gnext.has_edge?( @e1 ).should be_true
+ @gnext.has_edge?( @e2 ).should be_false
+ @gnext.has_edge?( @e3 ).should be_false
+ @gnext.has_edge?( @e4 ).should be_true
+ end
+
+ end
+
+ describe "#merge_vertices!(String,String,String)" do
+
+ it "returns an object of type graph" do
+ @g.merge_vertices!( @v1, @v2, @vmerged ).should be_an_instance_of(Graph)
+ end
+
+ it "modifies the original graph" do
+ @g.merge_vertices! @v1, @v2, @vmerged
+ @g.has_vertex?( @v1 ).should be_false
+ @g.has_vertex?( @v2 ).should be_false
+ end
+
+ it "removes the first two vertices" do
+ @g.merge_vertices! @v1, @v2, @vmerged
+ @g.has_vertex?( @v1 ).should be_false
+ @g.has_vertex?( @v2 ).should be_false
+ end
+
+ it "creates a vertex of the third string" do
+ @g.merge_vertices! @v1, @v2, @vmerged
+ @g.has_vertex?( @vmerged ).should be_true
+ end
+
+ it "removes the edge connecting the two vertices" do
+ @g.merge_vertices! @v1, @v2, @vmerged
+ @g.has_edge?( @e1 ).should be_false
+ end
+
+ it "connects the merged vertex with the vertices adjacent to the previous two" do
+ @g.merge_vertices! @v1, @v3, @vmerged
+ @g.is_adjacent?( @vmerged, @v2 ).should be_true
+ @g.is_adjacent?( @vmerged, @v4 ).should be_true
+ end
+
+ it "preserves the edges of the first vertex over the second" do
+ @g.merge_vertices! @v1, @v3, @vmerged
+ @g.has_edge?( @e1 ).should be_true
+ @g.has_edge?( @e2 ).should be_false
+ @g.has_edge?( @e3 ).should be_false
+ @g.has_edge?( @e4 ).should be_true
+ end
+
+ end
+
+ end
+ end
+end

0 comments on commit 7aa873e

Please sign in to comment.