abstract_graph 1.1.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +13 -5
- data/Rakefile +11 -1
- data/lib/abstract_graph.rb +1 -0
- data/lib/abstract_graph/composition.rb +1 -1
- data/lib/abstract_graph/composition/edge.rb +5 -0
- data/lib/abstract_graph/composition/edge/initialize.rb +6 -0
- data/lib/abstract_graph/composition/edge/is_coincident.rb +5 -2
- data/lib/abstract_graph/composition/unique_name_collection.rb +28 -0
- data/lib/abstract_graph/composition/unique_name_collection/add.rb +23 -0
- data/lib/abstract_graph/composition/unique_name_collection/delete.rb +20 -0
- data/lib/abstract_graph/composition/unique_name_collection/dup.rb +24 -0
- data/lib/abstract_graph/composition/unique_name_collection/each.rb +18 -0
- data/lib/abstract_graph/composition/unique_name_collection/find.rb +18 -0
- data/lib/abstract_graph/composition/unique_name_collection/initialize.rb +22 -0
- data/lib/abstract_graph/composition/unique_name_collection/link.rb +42 -0
- data/lib/abstract_graph/composition/unique_name_collection/method_missing.rb +18 -0
- data/lib/abstract_graph/composition/unique_name_collection/rename.rb +34 -0
- data/lib/abstract_graph/composition/unique_name_collection/ticket.rb +18 -0
- data/lib/abstract_graph/composition/unique_name_collection/ticket/get.rb +20 -0
- data/lib/abstract_graph/composition/unique_name_collection/ticket/initialize.rb +20 -0
- data/lib/abstract_graph/composition/unique_name_collection/ticket/set.rb +20 -0
- data/lib/abstract_graph/composition/vertex.rb +5 -1
- data/lib/abstract_graph/composition/vertex/initialize.rb +6 -0
- data/lib/abstract_graph/graph.rb +1 -0
- data/lib/abstract_graph/graph/add_edge.rb +9 -8
- data/lib/abstract_graph/graph/add_vertex.rb +5 -2
- data/lib/abstract_graph/graph/adjacency_list.rb +8 -3
- data/lib/abstract_graph/graph/change_edge_name.rb +6 -4
- data/lib/abstract_graph/graph/change_vertex_name.rb +5 -3
- data/lib/abstract_graph/graph/connected.rb +36 -0
- data/lib/abstract_graph/graph/delete_edge.rb +5 -4
- data/lib/abstract_graph/graph/delete_vertex.rb +5 -4
- data/lib/abstract_graph/graph/dup.rb +8 -3
- data/lib/abstract_graph/graph/get_edge_name.rb +7 -4
- data/lib/abstract_graph/graph/has_edge.rb +6 -3
- data/lib/abstract_graph/graph/has_vertex.rb +6 -3
- data/lib/abstract_graph/graph/initialize.rb +5 -1
- data/lib/abstract_graph/graph/is_adjacent.rb +9 -7
- data/lib/abstract_graph/graph/merge_vertices.rb +16 -14
- data/lib/abstract_graph/graph/split_vertex.rb +10 -7
- data/lib/abstract_graph/graph/templates/complete_bipartite_graph.rb +7 -5
- data/lib/abstract_graph/graph/templates/complete_graph.rb +8 -6
- data/lib/abstract_graph/graph/templates/cycle_graph.rb +6 -5
- data/lib/abstract_graph/graph/templates/path_graph.rb +6 -4
- data/lib/abstract_graph/graph/templates/petersen_graph.rb +8 -2
- data/lib/abstract_graph/version.rb +1 -1
- data/spec/abstract_graph/composition/{uniquenamecollection → unique_name_collection}/add_spec.rb +0 -0
- data/spec/abstract_graph/composition/{uniquenamecollection → unique_name_collection}/dup_spec.rb +0 -0
- data/spec/abstract_graph/composition/unique_name_collection/each_spec.rb +38 -0
- data/spec/abstract_graph/composition/unique_name_collection/find_spec.rb +33 -0
- data/spec/abstract_graph/composition/{uniquenamecollection → unique_name_collection}/initialize_spec.rb +0 -0
- data/spec/abstract_graph/composition/{uniquenamecollection → unique_name_collection}/link_spec.rb +0 -0
- data/spec/abstract_graph/composition/{uniquenamecollection → unique_name_collection}/method_missing_spec.rb +4 -15
- data/spec/abstract_graph/composition/{uniquenamecollection → unique_name_collection}/rename_spec.rb +1 -1
- data/spec/abstract_graph/composition/{uniquenamecollection_spec.rb → unique_name_collection_spec.rb} +0 -0
- data/spec/abstract_graph/graph/add_edge_spec.rb +1 -1
- data/spec/abstract_graph/graph/connected_spec.rb +39 -0
- data/tasks/benchmark.rb +47 -0
- data/tasks/create_method.rb +64 -0
- data/tasks/list_methods.rb +5 -0
- metadata +45 -32
- data/lib/abstract_graph/composition/uniquenamecollection.rb +0 -22
- data/lib/abstract_graph/composition/uniquenamecollection/add.rb +0 -19
- data/lib/abstract_graph/composition/uniquenamecollection/dup.rb +0 -20
- data/lib/abstract_graph/composition/uniquenamecollection/initialize.rb +0 -14
- data/lib/abstract_graph/composition/uniquenamecollection/link.rb +0 -32
- data/lib/abstract_graph/composition/uniquenamecollection/method_missing.rb +0 -14
- data/lib/abstract_graph/composition/uniquenamecollection/rename.rb +0 -28
- data/lib/abstract_graph/composition/vertex/delete.rb +0 -12
- data/spec/abstract_graph/composition/vertex/delete_spec.rb +0 -12
@@ -8,6 +8,11 @@ module AbstractGraph
|
|
8
8
|
attr_reader :name
|
9
9
|
attr_accessor :value
|
10
10
|
|
11
|
+
# d: Set the name of vertex.
|
12
|
+
# a: Throw an ArgumentError if the name is not a string
|
13
|
+
# t: constant
|
14
|
+
# p: name should be string
|
15
|
+
# r: The name
|
11
16
|
def name=(name)
|
12
17
|
raise ArgumentError if name.class != String
|
13
18
|
@name = name
|
@@ -18,4 +23,3 @@ module AbstractGraph
|
|
18
23
|
end
|
19
24
|
|
20
25
|
require "abstract_graph/composition/vertex/initialize"
|
21
|
-
require "abstract_graph/composition/vertex/delete"
|
@@ -4,6 +4,12 @@ module AbstractGraph
|
|
4
4
|
module Composition
|
5
5
|
class Vertex
|
6
6
|
|
7
|
+
# d: Create a vertex object with a name.
|
8
|
+
# a:
|
9
|
+
# t: constant
|
10
|
+
# p: name is the name of our vertex, default to "",
|
11
|
+
# optional value that can be tracked
|
12
|
+
# r: The vertex
|
7
13
|
def initialize (name="", value=nil)
|
8
14
|
@name = name
|
9
15
|
@value = value
|
data/lib/abstract_graph/graph.rb
CHANGED
@@ -3,14 +3,15 @@
|
|
3
3
|
module AbstractGraph
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
6
|
+
# d: Add an edge to graph.
|
7
|
+
# a: Ensure the two vertices exist, then add the edge and check it's not coincident with any
|
8
|
+
# other edge.
|
9
|
+
# t: |edges|
|
10
|
+
# p: s is name of edge, v1 and v2 are names of the two vertices
|
11
|
+
# r: returns the graph itself
|
11
12
|
def add_edge( s, v1, v2 )
|
12
|
-
v1 = @vertices
|
13
|
-
v2 = @vertices
|
13
|
+
v1 = @vertices.find(v1) or return nil
|
14
|
+
v2 = @vertices.find(v2) or return nil
|
14
15
|
|
15
16
|
raise Exception.new( "AddEdge: Same vertices passed, #{v1.name}" ) if v1 == v2
|
16
17
|
|
@@ -18,7 +19,7 @@ module AbstractGraph
|
|
18
19
|
edge = Edge.new s, v1, v2
|
19
20
|
|
20
21
|
# check if it's an multiple edge
|
21
|
-
@edges.
|
22
|
+
@edges.each do |e|
|
22
23
|
raise Exception.new( "AddEdge: Multiple edge being added between #{v1.name}, #{v2.name}" ) if e.is_coincident? edge
|
23
24
|
end
|
24
25
|
|
@@ -3,8 +3,11 @@
|
|
3
3
|
module AbstractGraph
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# d: Add a vertex to graph.
|
7
|
+
# a: Adds the new vertex.
|
8
|
+
# t: constant
|
9
|
+
# p: s is the name of the vertex
|
10
|
+
# r: returns the graph itself
|
8
11
|
def add_vertex( s )
|
9
12
|
# create the vertex
|
10
13
|
vertex = Vertex.new s
|
@@ -3,11 +3,16 @@
|
|
3
3
|
module AbstractGraph
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# d: Return adjacent vertices
|
7
|
+
# a: Go through the edges and collect all the vertex names, subtracting our own. Thus, only the
|
8
|
+
# 'vertices' tuples that have one vertex left are adjacent since the other vertex got deleted.
|
9
|
+
# Then, we can use the remaining array and return it.
|
10
|
+
# t: |edges|
|
11
|
+
# p: s is the name of vertex
|
12
|
+
# r: returns nil if nothing, returns array of adjacent vertices' names
|
8
13
|
def adjacency_list( s )
|
9
14
|
# this collects all the edges at first
|
10
|
-
result = @edges.collect do |
|
15
|
+
result = @edges.collect do |e|
|
11
16
|
e.vertices.collect do |v|
|
12
17
|
v.name
|
13
18
|
end - [s]
|
@@ -3,11 +3,13 @@
|
|
3
3
|
module AbstractGraph
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
6
|
+
# d: Change the name of an edge
|
7
|
+
# a: Changes the name of an edge by checking existing names and then adding our own
|
8
|
+
# t: t(rename), which is |edges + vertex|
|
9
|
+
# p: s is current name of edge, snew is requested name of edge
|
10
|
+
# r: returns graph if everything goes well, nil if it failed
|
9
11
|
def change_edge_name( s, snew )
|
10
|
-
return nil
|
12
|
+
return nil unless @edges.rename(s, snew)
|
11
13
|
self
|
12
14
|
end
|
13
15
|
|
@@ -3,9 +3,11 @@
|
|
3
3
|
module AbstractGraph
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
6
|
+
# d: Change the name of an vertex
|
7
|
+
# a: Changes the name of an vertex by checking existing names and then adding our own
|
8
|
+
# t: t(rename), which is |edges + vertex|
|
9
|
+
# p: s is current name of vertex, snew is requested name of vertex
|
10
|
+
# r: returns graph if everything goes well, nil if it failed
|
9
11
|
def change_vertex_name( s, snew )
|
10
12
|
return nil if @vertices.rename(s, snew).nil?
|
11
13
|
self
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# required in "abstract_graph/graph"
|
2
|
+
|
3
|
+
module AbstractGraph
|
4
|
+
class Graph
|
5
|
+
|
6
|
+
# d: Check if graph is connected
|
7
|
+
# a: Do a depth first search. So we push the first vertex, and then keep trying to go to adjacent
|
8
|
+
# vertices until all of them are seen. In the end, check if the list of seen vertices is the
|
9
|
+
# same as the complete vertex list.
|
10
|
+
# t: |vertices| * t(adjacency_list) which is |vertices| * |edges|
|
11
|
+
# p: none
|
12
|
+
# r: returns true if graph is connected, false otherwise
|
13
|
+
def connected?
|
14
|
+
return true if @vertices.empty?
|
15
|
+
seen = []
|
16
|
+
toSee = [@vertices.first.name]
|
17
|
+
|
18
|
+
# go through vertices and if we seen them, don't inspect them
|
19
|
+
# essentially does a depth first search
|
20
|
+
while !toSee.empty? do
|
21
|
+
inspect = toSee.pop
|
22
|
+
seen << inspect
|
23
|
+
|
24
|
+
adjacentVertices = adjacency_list( inspect )
|
25
|
+
break if adjacentVertices.nil?
|
26
|
+
|
27
|
+
# add adjacent vertices if they're not in any of the seen lists
|
28
|
+
adjacentVertices.each do |v|
|
29
|
+
toSee << v if !seen.include?( v ) && !toSee.include?( v )
|
30
|
+
end
|
31
|
+
end
|
32
|
+
seen.size == @vertices.size
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -3,15 +3,16 @@
|
|
3
3
|
module AbstractGraph
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# d: Delete an edge.
|
7
|
+
# a: Deletes the edge.
|
8
|
+
# t: constant
|
9
|
+
# p: s is the edge name
|
10
|
+
# r: graph itself
|
8
11
|
def delete_edge( s )
|
9
12
|
other = self.dup
|
10
13
|
other.delete_edge! s
|
11
14
|
end
|
12
15
|
|
13
|
-
# delete an edge in a current graph
|
14
|
-
# p: String s represents the name of the edge
|
15
16
|
def delete_edge!( s )
|
16
17
|
@edges.delete s
|
17
18
|
self
|
@@ -3,15 +3,16 @@
|
|
3
3
|
module AbstractGraph
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# d: Delete an vertex.
|
7
|
+
# a: Deletes the vertex.
|
8
|
+
# t: constant
|
9
|
+
# p: s is the vertex name
|
10
|
+
# r: graph itself
|
8
11
|
def delete_vertex( s )
|
9
12
|
other = self.dup
|
10
13
|
other.delete_vertex! s
|
11
14
|
end
|
12
15
|
|
13
|
-
# delete a vertex in a current graph
|
14
|
-
# p: String s represents the name of the vertex
|
15
16
|
def delete_vertex!( s )
|
16
17
|
@vertices.delete s
|
17
18
|
self
|
@@ -3,15 +3,20 @@
|
|
3
3
|
module AbstractGraph
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
#
|
6
|
+
# d: Copies the graph.
|
7
|
+
# a: Does a deep copy, but does not dup vertex/edge so modifying them will affect both graphs.
|
8
|
+
# Copies vertices then edges.
|
9
|
+
# t: |vertices| + |edges|
|
10
|
+
# p: none
|
11
|
+
# r: returns the copy graph
|
7
12
|
def dup
|
8
13
|
other = self.class.new
|
9
14
|
# cannot call UniqueNameCollection#dup because we'll lose
|
10
15
|
# link data
|
11
|
-
@vertices.
|
16
|
+
@vertices.each do |v|
|
12
17
|
other.vertices.add v
|
13
18
|
end
|
14
|
-
@edges.
|
19
|
+
@edges.each do |e|
|
15
20
|
other.edges.add e
|
16
21
|
end
|
17
22
|
other
|
@@ -3,13 +3,16 @@
|
|
3
3
|
module AbstractGraph
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
6
|
+
# d: Returns the edge name given two vertex names.
|
7
|
+
# a: Goes through all the edges and see if any of them have the same vertices as
|
8
|
+
# the ones we are requesting.
|
9
|
+
# t: |edges|
|
10
|
+
# p: the names of the two vertices
|
11
|
+
# r: nil if edge if nothing, name of edge(string) if found
|
9
12
|
def get_edge_name( v1, v2 )
|
10
13
|
vertices = [v1, v2].sort!
|
11
14
|
|
12
|
-
@edges.
|
15
|
+
@edges.each do |e|
|
13
16
|
eVertices = e.vertices.map do |v|
|
14
17
|
v.name
|
15
18
|
end.sort
|
@@ -3,10 +3,13 @@
|
|
3
3
|
module AbstractGraph
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# d: Checks if graph has the edge.
|
7
|
+
# a: Run find on @edges and existance it.
|
8
|
+
# t: constant
|
9
|
+
# p: name of edge
|
10
|
+
# r: true/false depending if edge with name s exists
|
8
11
|
def has_edge?( s )
|
9
|
-
@edges.
|
12
|
+
!(@edges.find s).nil?
|
10
13
|
end
|
11
14
|
|
12
15
|
end
|
@@ -3,10 +3,13 @@
|
|
3
3
|
module AbstractGraph
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# d: Checks if the graph has the vertex.
|
7
|
+
# a: Run find on @vertices and existance it.
|
8
|
+
# t: constant
|
9
|
+
# p: name of vertex
|
10
|
+
# r: true/false depending if vertex with name s exists
|
8
11
|
def has_vertex?( s )
|
9
|
-
@vertices.
|
12
|
+
!(@vertices.find s).nil?
|
10
13
|
end
|
11
14
|
|
12
15
|
end
|
@@ -3,7 +3,11 @@
|
|
3
3
|
module AbstractGraph
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
#
|
6
|
+
# d: Initializes a graph
|
7
|
+
# a: Creates a vertex and edge UNC and links them to share namespace
|
8
|
+
# t: constant
|
9
|
+
# p:
|
10
|
+
# r: new graph
|
7
11
|
def initialize
|
8
12
|
|
9
13
|
@vertices = UniqueNameCollection.new
|
@@ -3,17 +3,19 @@
|
|
3
3
|
module AbstractGraph
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# d: Check if two vertices are adjacent.
|
7
|
+
# a: Go through the edges and check if any of the edges have the same vertices as the
|
8
|
+
# two query vertices
|
9
|
+
# t: |edges|
|
10
|
+
# p: v1 and v2 are the names of the vertices
|
11
|
+
# r: true if the vertices are adjacent, false otherwise
|
8
12
|
def is_adjacent?( v1, v2 )
|
9
13
|
vertices = [v1, v2].sort!
|
10
14
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end.sort
|
15
|
+
# note find is overridden on uniqueNameCollection
|
16
|
+
( @edges.each.find do |e|
|
17
|
+
vertices == e.vertices.map(&:name).sort
|
15
18
|
end && true ) || false
|
16
|
-
|
17
19
|
end
|
18
20
|
|
19
21
|
end
|
@@ -3,17 +3,20 @@
|
|
3
3
|
module AbstractGraph
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
6
|
+
# d: Merges vertices together so that any edges are connected to merged vertex
|
7
|
+
# a: First create a list of all edges within the vertices, they will be deleted.
|
8
|
+
# Next create a list of edges to create which will be connected to the final
|
9
|
+
# vertex. This is done by finding the remaining edges connected to the vertices.
|
10
|
+
# Finally, delete the vertices, add the new vertex, and add the edges.
|
11
|
+
# t: |vertices| * |edges|
|
10
12
|
# p: (Array, String)
|
11
|
-
#
|
12
|
-
#
|
13
|
+
# array is the string names of vertices to merge together
|
14
|
+
# string is the name of the final vertex
|
13
15
|
# (String, String, String)
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
16
|
+
# first two strings are the vertices to merge together
|
17
|
+
# last string is the name of the merged vertex
|
18
|
+
# r: the graph itself
|
19
|
+
# *: the edges prioritize v1 to v2 if there are any conflicts
|
17
20
|
def merge_vertices( *args )
|
18
21
|
other = self.dup
|
19
22
|
other.merge_vertices!( *args )
|
@@ -21,7 +24,6 @@ module AbstractGraph
|
|
21
24
|
|
22
25
|
# same as before except operates on the current graph
|
23
26
|
def merge_vertices!( *args )
|
24
|
-
|
25
27
|
# create a list of vertices we want to merge
|
26
28
|
mergeV = []
|
27
29
|
if args[0].class == Array
|
@@ -36,7 +38,7 @@ module AbstractGraph
|
|
36
38
|
# do not need to go through the array of vertices
|
37
39
|
edgesInBetween << get_edge_name( args[0], args[1] )
|
38
40
|
else
|
39
|
-
edgesInBetween = @edges.
|
41
|
+
edgesInBetween = @edges.collect do |e|
|
40
42
|
e.name if ( e.vertices.map do |v|
|
41
43
|
v.name
|
42
44
|
end & mergeV ).count == 2
|
@@ -51,15 +53,15 @@ module AbstractGraph
|
|
51
53
|
# get the list of connections we want vmerged to be merged with
|
52
54
|
finalConnections = {}
|
53
55
|
mergeV.reverse.each do |vCheck|
|
54
|
-
@edges.each do |
|
56
|
+
@edges.each do |e|
|
55
57
|
[0,1].each do |edgeVId|
|
56
58
|
|
57
59
|
# check if the edge contains our vertex
|
58
60
|
if e.vertices[edgeVId].name == vCheck
|
59
61
|
otherVertex = e.vertices[(edgeVId+1)%2].name
|
60
62
|
# track the vertex with the edge name
|
61
|
-
finalConnections[otherVertex] = name
|
62
|
-
delete_edge! name
|
63
|
+
finalConnections[otherVertex] = e.name
|
64
|
+
delete_edge! e.name
|
63
65
|
end
|
64
66
|
|
65
67
|
end
|
@@ -3,10 +3,13 @@
|
|
3
3
|
module AbstractGraph
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
6
|
+
# d: Split a vertex into two and assign adjacent to each of the vertices.
|
7
|
+
# a: Gathers a list of adjacent vertices by going through the edges, then
|
8
|
+
# deletes the vertex and all the adjacent edges. Then goes back, creates
|
9
|
+
# two vertices, and recreates all the adjacent edges.
|
10
|
+
# t: |edges|
|
11
|
+
# p: name of vertex to split
|
12
|
+
# r: graph itself
|
10
13
|
def split_vertex( s )
|
11
14
|
other = self.dup
|
12
15
|
other.split_vertex!( s )
|
@@ -15,10 +18,10 @@ module AbstractGraph
|
|
15
18
|
|
16
19
|
# same as before except operates on the current graph
|
17
20
|
def split_vertex!( s )
|
18
|
-
adjacentVertices = @edges.dup.keep_if do |
|
21
|
+
adjacentVertices = @edges.dup.keep_if do |e|
|
19
22
|
e.vertices.collect(&:name).include? s
|
20
|
-
end.collect do |
|
21
|
-
[
|
23
|
+
end.collect do |e|
|
24
|
+
[ e.name, ( e.vertices.collect(&:name) - [s] )[0] ]
|
22
25
|
end
|
23
26
|
|
24
27
|
delete_vertex! s
|
@@ -4,11 +4,13 @@ module AbstractGraph
|
|
4
4
|
class Graph
|
5
5
|
class << self
|
6
6
|
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
7
|
+
# d: Create a complete bipartite graph K(n,m).
|
8
|
+
# a: It first adds the vertices, then adds the edges. The vertices are named "v(2^i)" from
|
9
|
+
# the first set being i=2^0..n-1, and the second set i=2^n..m+n-1. The edges are sums "e(i)"
|
10
|
+
# where i=sum of two vertices
|
11
|
+
# t: n * m * t(add_edge) + max(n,m) * t(add_vertex)
|
12
|
+
# p: n is the number of vertices in the first set, m is number of vertices in second set
|
13
|
+
# r: a complete bipartite graph
|
12
14
|
def complete_bipartite_graph n, m
|
13
15
|
result = new
|
14
16
|
|