plexus 0.5.4 → 0.5.5

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.
Files changed (70) hide show
  1. data/Gemfile +3 -0
  2. data/LICENSE +37 -0
  3. data/README.md +208 -0
  4. data/Rakefile +25 -0
  5. data/lib/plexus.rb +90 -0
  6. data/lib/plexus/adjacency_graph.rb +225 -0
  7. data/lib/plexus/arc.rb +60 -0
  8. data/lib/plexus/arc_number.rb +50 -0
  9. data/lib/plexus/biconnected.rb +84 -0
  10. data/lib/plexus/chinese_postman.rb +91 -0
  11. data/lib/plexus/classes/graph_classes.rb +28 -0
  12. data/lib/plexus/common.rb +63 -0
  13. data/lib/plexus/comparability.rb +63 -0
  14. data/lib/plexus/directed_graph.rb +78 -0
  15. data/lib/plexus/directed_graph/algorithms.rb +95 -0
  16. data/lib/plexus/directed_graph/distance.rb +167 -0
  17. data/lib/plexus/dot.rb +94 -0
  18. data/lib/plexus/edge.rb +38 -0
  19. data/lib/plexus/ext.rb +79 -0
  20. data/lib/plexus/graph.rb +628 -0
  21. data/lib/plexus/graph_api.rb +35 -0
  22. data/lib/plexus/labels.rb +112 -0
  23. data/lib/plexus/maximum_flow.rb +77 -0
  24. data/lib/plexus/ruby_compatibility.rb +17 -0
  25. data/lib/plexus/search.rb +510 -0
  26. data/lib/plexus/strong_components.rb +93 -0
  27. data/lib/plexus/support/support.rb +9 -0
  28. data/lib/plexus/undirected_graph.rb +56 -0
  29. data/lib/plexus/undirected_graph/algorithms.rb +90 -0
  30. data/lib/plexus/version.rb +6 -0
  31. data/spec/biconnected_spec.rb +27 -0
  32. data/spec/chinese_postman_spec.rb +27 -0
  33. data/spec/community_spec.rb +44 -0
  34. data/spec/complement_spec.rb +27 -0
  35. data/spec/digraph_distance_spec.rb +121 -0
  36. data/spec/digraph_spec.rb +339 -0
  37. data/spec/dot_spec.rb +48 -0
  38. data/spec/edge_spec.rb +158 -0
  39. data/spec/inspection_spec.rb +38 -0
  40. data/spec/multi_edge_spec.rb +32 -0
  41. data/spec/neighborhood_spec.rb +36 -0
  42. data/spec/properties_spec.rb +146 -0
  43. data/spec/search_spec.rb +227 -0
  44. data/spec/spec.opts +4 -0
  45. data/spec/spec_helper.rb +59 -0
  46. data/spec/strong_components_spec.rb +61 -0
  47. data/spec/triangulated_spec.rb +125 -0
  48. data/spec/undirected_graph_spec.rb +220 -0
  49. data/vendor/priority-queue/CHANGELOG +33 -0
  50. data/vendor/priority-queue/Makefile +140 -0
  51. data/vendor/priority-queue/README +133 -0
  52. data/vendor/priority-queue/benchmark/dijkstra.rb +171 -0
  53. data/vendor/priority-queue/compare_comments.rb +49 -0
  54. data/vendor/priority-queue/doc/c-vs-rb.png +0 -0
  55. data/vendor/priority-queue/doc/compare_big.gp +14 -0
  56. data/vendor/priority-queue/doc/compare_big.png +0 -0
  57. data/vendor/priority-queue/doc/compare_small.gp +15 -0
  58. data/vendor/priority-queue/doc/compare_small.png +0 -0
  59. data/vendor/priority-queue/doc/results.csv +37 -0
  60. data/vendor/priority-queue/ext/priority_queue/CPriorityQueue/extconf.rb +2 -0
  61. data/vendor/priority-queue/ext/priority_queue/CPriorityQueue/priority_queue.c +947 -0
  62. data/vendor/priority-queue/lib/priority_queue.rb +14 -0
  63. data/vendor/priority-queue/lib/priority_queue/c_priority_queue.rb +1 -0
  64. data/vendor/priority-queue/lib/priority_queue/poor_priority_queue.rb +46 -0
  65. data/vendor/priority-queue/lib/priority_queue/ruby_priority_queue.rb +526 -0
  66. data/vendor/priority-queue/priority_queue.so +0 -0
  67. data/vendor/priority-queue/setup.rb +1551 -0
  68. data/vendor/priority-queue/test/priority_queue_test.rb +371 -0
  69. data/vendor/rdot.rb +360 -0
  70. metadata +100 -10
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Inspection" do # :nodoc:
4
+ before do
5
+ @dg = DirectedMultiGraph[
6
+ [0,0,1] => 1,
7
+ [1,2,2] => 2,
8
+ [1,3,3] => 4,
9
+ [1,4,4] => nil,
10
+ [4,1,5] => 8,
11
+ [1,2,6] => 16,
12
+ [3,3,7] => 32,
13
+ [3,3,8] => 64
14
+ ]
15
+ @dg[3] = 128
16
+ @dg[0] = 256
17
+ end
18
+
19
+ describe "inspection_without_labels" do
20
+ it do
21
+ @dg = Digraph[1,2,3,4,5,6]
22
+ reflect = eval @dg.inspect
23
+ reflect.should == @dg
24
+ end
25
+ end
26
+
27
+ describe "inspection_with_labels" do
28
+ it do
29
+ inspect = @dg.inspect
30
+ @dg.vertices.inject(0) {|a,v| a += (@dg[v] || 0)}.should == 384
31
+ @dg.edges.inject(0) {|a,e| a += (@dg[e] || 0)}.should == 127
32
+ reflect = eval inspect
33
+ reflect.should == @dg
34
+ reflect.edges.inject(0) { |a,e| a += (reflect[e] || 0)}.should == 127
35
+ reflect.vertices.inject(0) {|a,v| a += (reflect[v] || 0)}.should == 384
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,32 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe "MultiArc" do # :nodoc:
4
+
5
+ describe "directed_pseudo_graph" do
6
+ it do
7
+ dpg = DirectedPseudoGraph[ :a,:b,
8
+ :a,:b,
9
+ :a,:b ]
10
+ dpg.edges.size.should == 3
11
+ x = 0
12
+ dpg.edges.each {|e| dpg[e] = (x+=1)}
13
+ dpg.edges.inject(0) {|a,v| a+=dpg[v]}.should == 6
14
+ end
15
+ end
16
+
17
+ describe "directed_multi_graph" do
18
+ it do
19
+ dmg = DirectedMultiGraph[ :a,:a,
20
+ :a,:a,
21
+ :a,:b,
22
+ :a,:b,
23
+ :b,:b,
24
+ :b,:b ]
25
+ dmg.edges.size.should == 6
26
+ x = 0
27
+ dmg.edges.each { |e| dmg[e] = (x+=1) }
28
+ dmg.edges.inject(0) {|a,v| a+=dmg[v]}.should == 21
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,36 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe "Neighborhood" do
4
+ before do
5
+ @d = Digraph[:a,:b, :a,:f,
6
+ :b,:g,
7
+ :c,:b, :c,:g,
8
+ :d,:c, :d,:g,
9
+ :e,:d,
10
+ :f,:e, :f,:g,
11
+ :g,:a, :g,:e]
12
+ @w = [:a,:b]
13
+ end
14
+
15
+ describe "open_out_neighborhood" do
16
+ it do
17
+ @d.set_neighborhood([:a], :in).should == [:g]
18
+ ([:f,:g] - @d.set_neighborhood(@w, :out)).should == []
19
+ (@w - @d.open_pth_neighborhood(@w, 0, :out)).should == []
20
+ ([:f, :g] - @d.open_pth_neighborhood(@w, 1, :out)).should == []
21
+ ([:e] - @d.open_pth_neighborhood(@w, 2, :out)).should == []
22
+ ([:d] - @d.open_pth_neighborhood(@w, 3, :out)).should == []
23
+ ([:c] - @d.open_pth_neighborhood(@w, 4, :out)).should == []
24
+ end
25
+ end
26
+
27
+ describe "closed_out_neighborhood" do
28
+ it do
29
+ (@w - @d.closed_pth_neighborhood(@w, 0, :out)).should == []
30
+ ([:a,:b,:f,:g] - @d.closed_pth_neighborhood(@w, 1, :out)).should == []
31
+ ([:a,:b,:e,:f,:g] - @d.closed_pth_neighborhood(@w, 2, :out)).should == []
32
+ ([:a,:b,:d,:e,:f,:g] - @d.closed_pth_neighborhood(@w, 3, :out)).should == []
33
+ ([:a,:b,:c,:d,:e,:f,:g] - @d.closed_pth_neighborhood(@w, 4, :out)).should == []
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,146 @@
1
+
2
+ require File.join(File.dirname(__FILE__), 'spec_helper')
3
+ require 'plexus/dot'
4
+
5
+ # This test runs the classes from Appendix F in
6
+ # _Algorithmic_Graph_Theory_and_Perfect_Graphs,
7
+ # by Martin Charles Golumbic
8
+ describe "Properties" do # :nodoc:
9
+
10
+ describe "g1" do
11
+ it do
12
+ g1 = UndirectedGraph[ :a,:b, :a,:d, :a,:e, :a,:i, :a,:g, :a,:h,
13
+ :b,:c, :b,:f,
14
+ :c,:d, :c,:h,
15
+ :d,:h, :d,:e,
16
+ :e,:f,
17
+ :f,:g, :f,:h, :f,:i,
18
+ :h,:i ]
19
+
20
+ g1.should_not be_triangulated
21
+ g1.complement.should_not be_triangulated # Disagrees with Golumbic!
22
+ g1.should_not be_comparability
23
+ g1.complement.should_not be_comparability
24
+ g1.should_not be_interval
25
+ g1.complement.should_not be_interval
26
+ g1.should_not be_permutation
27
+ g1.should_not be_split
28
+
29
+ # g1.write_to_graphic_file('jpg','g1')
30
+ # g1.complement.write_to_graphic_file('jpg','g1_complement')
31
+ end
32
+ end
33
+
34
+ describe "g2" do
35
+ it do
36
+ g2 = UndirectedGraph[ :a,:b, :a,:e,
37
+ :b,:c, :b,:e, :b,:f,
38
+ :c,:d, :c,:f, :c,:g,
39
+ :d,:g,
40
+ :e,:f,
41
+ :f,:g]
42
+
43
+ g2.should be_triangulated
44
+ g2.complement.should_not be_triangulated
45
+ g2.should_not be_comparability
46
+ g2.complement.should be_comparability
47
+ g2.should be_interval
48
+ g2.complement.should_not be_interval
49
+ g2.should_not be_permutation
50
+ g2.should_not be_split
51
+ end
52
+ end
53
+
54
+ describe "g3" do
55
+ it do
56
+ g3 = UndirectedGraph[ :a,:c,
57
+ :b,:e,
58
+ :c,:d, :c,:f,
59
+ :d,:f, :d,:g, :d,:e,
60
+ :e,:g,
61
+ :f,:g ]
62
+ g3.should be_triangulated
63
+ g3.complement.should_not be_triangulated
64
+ g3.should_not be_comparability
65
+ g3.complement.should be_comparability
66
+ g3.should be_interval
67
+ g3.complement.should_not be_interval
68
+ g3.should_not be_permutation
69
+ g3.should_not be_split
70
+ end
71
+ end
72
+
73
+ describe "g4" do
74
+ it do
75
+ g4 = UndirectedGraph[ :a,:b,
76
+ :b,:c,
77
+ :c,:d, :c,:e,
78
+ :d,:f,
79
+ :e,:g]
80
+ g4.should be_triangulated
81
+ g4.complement.should_not be_triangulated
82
+ g4.should be_comparability
83
+ g4.complement.should_not be_comparability
84
+ g4.should_not be_interval
85
+ g4.complement.should_not be_interval
86
+ g4.should_not be_permutation
87
+ g4.should_not be_split
88
+ end
89
+ end
90
+
91
+ describe "g5" do
92
+ it do
93
+ g5 = UndirectedGraph[ :a,:b, :a,:c,
94
+ :b,:c, :b,:d, :b,:f, :b,:g,
95
+ :c,:e, :c,:f, :c,:g,
96
+ :d,:f,
97
+ :e,:g,
98
+ :f,:g]
99
+ g5.should be_triangulated
100
+ g5.complement.should be_triangulated
101
+ g5.should be_comparability
102
+ g5.complement.should_not be_comparability
103
+ g5.should_not be_interval
104
+ g5.complement.should be_interval
105
+ g5.should_not be_permutation
106
+ g5.should be_split
107
+ end
108
+ end
109
+
110
+ describe "g6" do
111
+ it do
112
+ g6 = UndirectedGraph[ :a,:c, :a,:d,
113
+ :b,:c,
114
+ :c,:f,
115
+ :d,:e, :d,:f]
116
+ g6.should_not be_triangulated
117
+ g6.complement.should_not be_triangulated
118
+ g6.should be_comparability
119
+ g6.complement.should be_comparability
120
+ g6.should_not be_interval
121
+ g6.complement.should_not be_interval
122
+ g6.should be_permutation
123
+ g6.should_not be_split
124
+ end
125
+ end
126
+
127
+ describe "g7" do
128
+ it do
129
+ g7 = UndirectedGraph[ :a,:b, :a,:c,
130
+ :b,:c, :b,:d, :b,:e,
131
+ :c,:e, :c,:f,
132
+ :d,:e,
133
+ :e,:f]
134
+ g7.should be_triangulated
135
+ g7.complement.should be_triangulated
136
+ g7.should_not be_comparability
137
+ g7.complement.should_not be_comparability
138
+ g7.should_not be_interval
139
+ g7.complement.should_not be_interval
140
+ g7.should_not be_permutation
141
+ g7.should be_split
142
+ end
143
+
144
+ end
145
+
146
+ end
@@ -0,0 +1,227 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe "Search" do # :nodoc:
4
+
5
+ before do
6
+ @directed = Digraph[1,2, 2,3, 2,4, 4,5, 1,6, 6,4]
7
+ @undirected = UndirectedGraph[1,2, 2,3, 2,4, 4,5, 1,6]
8
+ @tree = Digraph[ 1,2, 1,3, 1,4, 2,5, 2,4, 2,6, 6,7, 23,24 ]
9
+ end
10
+
11
+ # "Algorithmic Graph Theory and Perfect Graphs", Martin Charles
12
+ # Golumbic, 1980, Academic Press, page 39, Propery (D1) and (D2) of
13
+ # depth first search
14
+ describe "dfs_properties" do
15
+ it do
16
+ dfs = {}
17
+ father = {}
18
+ @directed.each do |vertex|
19
+ assign_dfsnumber_ancestry(@directed, dfs, father, vertex)
20
+ # Property (D1)
21
+ father.keys.each {|v| dfs[father[v]].should be < dfs[v] }
22
+ # Property (D2)
23
+ # FIXME: Huh? Doesn't work
24
+ #@directed.edges.each {|e| related?(father, e.source, e.target).should be_true }
25
+ #@directed.edges.each {|e| dfs[e.source].should be < dfs[e.target] }
26
+ end
27
+ @directed.dfs.size.should == 6
28
+ @directed.dfs.sort.should == @directed.vertices.sort
29
+ end
30
+ end
31
+
32
+ # "Algorithmic Graph Theory and Perfect Graphs", Martin Charles
33
+ # Golumbic, 1980, Academic Press, page 40, Propery (B1), (B2) and (B3) of
34
+ # breadth first search
35
+ describe "bfs_properties" do
36
+ it do
37
+ level = {}
38
+ father = {}
39
+ bfs = {}
40
+ @directed.each do |vertex|
41
+ assign_bfsnumber_ancestry(@directed, bfs, level, father, vertex)
42
+ # Property (B1)
43
+ father.keys.each do |v|
44
+ bfs[father[v]].should be < bfs[v]
45
+ end
46
+ # Property (B2)
47
+ @directed.edges.each do |e|
48
+ (level[e.source]-level[e.target]).abs.should be < 2
49
+ end
50
+ # Property (B3)
51
+ # FIXME: How can one test this?
52
+ # @directed.vertex.each { |e| (level[e.source]-level[e.target]).abs.should be < 2 }
53
+ end
54
+ @directed.dfs.size.should == 6
55
+ @directed.dfs.sort.should == @directed.vertices.sort
56
+ end
57
+ end
58
+
59
+ describe "cyclic" do
60
+ it do
61
+ @directed.should be_acyclic
62
+ @undirected.should be_acyclic
63
+ @directed.should_not be_cyclic
64
+ @undirected.should_not be_cyclic
65
+ @undirected.add_edge!(4,6)
66
+ @directed.add_edge!(3,1)
67
+ @directed.should_not be_acyclic
68
+ @undirected.should_not be_acyclic
69
+ @directed.should be_cyclic
70
+ @undirected.should be_cyclic
71
+
72
+ # Test empty graph
73
+ x = Digraph.new
74
+ x.should_not be_cyclic
75
+ x.should be_acyclic
76
+ end
77
+ end
78
+
79
+ describe "astar" do
80
+ it do
81
+ # Graph from "Artificial Intelligence: A Modern Approach" by Stuart
82
+ # Russell ande Peter Norvig, Prentice-Hall 2nd Edition, pg 63
83
+ romania = UndirectedGraph.new.
84
+ add_edge!('Oradea', 'Zerind', 71).
85
+ add_edge!('Oradea', 'Sibiu', 151).
86
+ add_edge!('Zerind', 'Arad', 75).
87
+ add_edge!('Arad', 'Sibiu', 99).
88
+ add_edge!('Arad', 'Timisoara', 138).
89
+ add_edge!('Timisoara', 'Lugoj', 111).
90
+ add_edge!('Lugoj', 'Mehadia', 70).
91
+ add_edge!('Mehadia', 'Dobreta', 75).
92
+ add_edge!('Dobreta', 'Craiova', 120).
93
+ add_edge!('Sibiu', 'Fagaras', 99).
94
+ add_edge!('Fagaras', 'Bucharest', 211).
95
+ add_edge!('Sibiu', 'Rimnicu Vilcea', 80).
96
+ add_edge!('Rimnicu Vilcea', 'Craiova', 146).
97
+ add_edge!('Rimnicu Vilcea', 'Pitesti', 97).
98
+ add_edge!('Craiova', 'Pitesti', 138).
99
+ add_edge!('Pitesti', 'Bucharest', 101).
100
+ add_edge!('Bucharest', 'Giurgin', 90).
101
+ add_edge!('Bucharest', 'Urzieni', 85).
102
+ add_edge!('Urzieni', 'Hirsova', 98).
103
+ add_edge!('Urzieni', 'Vaslui', 142).
104
+ add_edge!('Hirsova', 'Eforie', 86).
105
+ add_edge!('Vaslui', 'Iasi', 92).
106
+ add_edge!('Iasi', 'Neamt', 87)
107
+
108
+ # Heuristic from "Artificial Intelligence: A Modern Approach" by Stuart
109
+ # Russell ande Peter Norvig, Prentice-Hall 2nd Edition, pg 95
110
+ straight_line_to_Bucharest =
111
+ {
112
+ 'Arad' => 366,
113
+ 'Bucharest' => 0,
114
+ 'Craiova' => 160,
115
+ 'Dobreta' => 242,
116
+ 'Eforie' => 161,
117
+ 'Fagaras' => 176,
118
+ 'Giurgiu' => 77,
119
+ 'Hirsova' => 151,
120
+ 'Iasi' => 226,
121
+ 'Lugoj' => 244,
122
+ 'Mehadia' => 241,
123
+ 'Neamt' => 234,
124
+ 'Oradea' => 380,
125
+ 'Pitesti' => 100,
126
+ 'Rimnicu Vilcea' => 193,
127
+ 'Sibiu' => 253,
128
+ 'Timisoara' => 329,
129
+ 'Urziceni' => 80,
130
+ 'Vaslui' => 199,
131
+ 'Zerind' => 374
132
+ }
133
+
134
+ # Heuristic is distance as crow flies, always under estimates costs.
135
+ h = Proc.new {|v| straight_line_to_Bucharest[v]}
136
+
137
+ list = []
138
+
139
+ dv = Proc.new {|v| list << "dv #{v}" }
140
+ ev = Proc.new {|v| list << "ev #{v}" }
141
+ bt = Proc.new {|v| list << "bt #{v}" }
142
+ fv = Proc.new {|v| list << "fv #{v}" }
143
+ er = Proc.new {|e| list << "er #{e}" }
144
+ enr = Proc.new {|e| list << "enr #{e}" }
145
+
146
+ options = { :discover_vertex => dv,
147
+ :examine_vertex => ev,
148
+ :black_target => bt,
149
+ :finish_vertex => fv,
150
+ :edge_relaxed => er,
151
+ :edge_not_relaxed => enr }
152
+
153
+ result = romania.astar('Arad', 'Bucharest', h, options)
154
+
155
+ result.should == ["Arad", "Sibiu", "Rimnicu Vilcea", "Pitesti", "Bucharest"]
156
+ # This isn't the greatest test since the exact ordering is not
157
+ # not specified by the algorithm. If someone has a better idea, please fix
158
+ list.should == ["ev Arad",
159
+ "er (Arad=Sibiu '99')",
160
+ "dv Sibiu",
161
+ "er (Arad=Timisoara '138')",
162
+ "dv Timisoara",
163
+ "er (Arad=Zerind '75')",
164
+ "dv Zerind",
165
+ "fv Arad",
166
+ "ev Sibiu",
167
+ "er (Rimnicu Vilcea=Sibiu '80')",
168
+ "dv Rimnicu Vilcea",
169
+ "er (Fagaras=Sibiu '99')",
170
+ "dv Fagaras",
171
+ "er (Oradea=Sibiu '151')",
172
+ "dv Oradea",
173
+ "enr (Arad=Sibiu '99')",
174
+ "fv Sibiu",
175
+ "ev Rimnicu Vilcea",
176
+ "enr (Rimnicu Vilcea=Sibiu '80')",
177
+ "er (Craiova=Rimnicu Vilcea '146')",
178
+ "dv Craiova",
179
+ "er (Pitesti=Rimnicu Vilcea '97')",
180
+ "dv Pitesti",
181
+ "fv Rimnicu Vilcea",
182
+ "ev Fagaras",
183
+ "enr (Fagaras=Sibiu '99')",
184
+ "er (Bucharest=Fagaras '211')",
185
+ "dv Bucharest",
186
+ "fv Fagaras",
187
+ "ev Pitesti",
188
+ "enr (Pitesti=Rimnicu Vilcea '97')",
189
+ "er (Bucharest=Pitesti '101')",
190
+ "enr (Craiova=Pitesti '138')",
191
+ "fv Pitesti",
192
+ "ev Bucharest"]
193
+ end
194
+ end
195
+
196
+ describe "bfs_spanning_forest" do
197
+ it do
198
+ predecessor, roots = @tree.bfs_spanning_forest(1)
199
+ predecessor.should == {2=>1, 3=>1, 4=>1, 5=>2, 6=>2, 7=>6, 24=>23}
200
+ roots.sort.should == [1,23]
201
+ predecessor, roots = @tree.bfs_spanning_forest(3)
202
+ predecessor.should == {7=>6, 24=>23, 2=>1, 4=>1}
203
+ roots.sort.should == [1,3,5,6,23]
204
+ end
205
+ end
206
+
207
+ describe "dfs_spanning_forest" do
208
+ it do
209
+ predecessor, roots = @tree.dfs_spanning_forest(1)
210
+ predecessor.should == {5=>2, 6=>2, 7=>6, 24=>23, 2=>1, 3=>1, 4=>2}
211
+ roots.sort.should == [1,23]
212
+ predecessor, roots = @tree.dfs_spanning_forest(3)
213
+ predecessor.should == {7=>6, 24=>23, 2=>1, 4=>2}
214
+ roots.sort.should == [1,3,5,6,23]
215
+ end
216
+ end
217
+
218
+ describe "tree_from_vertex" do
219
+ it do
220
+ @tree.bfs_tree_from_vertex(1).should == {5=>2, 6=>2, 7=>6, 2=>1, 3=>1, 4=>1}
221
+ @tree.bfs_tree_from_vertex(3).should == {}
222
+ @tree.dfs_tree_from_vertex(1).should == {5=>2, 6=>2, 7=>6, 2=>1, 3=>1, 4=>2}
223
+ @tree.dfs_tree_from_vertex(3).should == {}
224
+ end
225
+ end
226
+
227
+ end