gratr19 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/README +335 -0
  2. data/examples/graph_self.rb +54 -0
  3. data/examples/module_graph.jpg +0 -0
  4. data/examples/module_graph.rb +12 -0
  5. data/examples/self_graph.jpg +0 -0
  6. data/examples/visualize.jpg +0 -0
  7. data/examples/visualize.rb +8 -0
  8. data/install.rb +49 -0
  9. data/lib/gratr.rb +42 -0
  10. data/lib/gratr/adjacency_graph.rb +230 -0
  11. data/lib/gratr/base.rb +34 -0
  12. data/lib/gratr/biconnected.rb +116 -0
  13. data/lib/gratr/chinese_postman.rb +123 -0
  14. data/lib/gratr/common.rb +74 -0
  15. data/lib/gratr/comparability.rb +92 -0
  16. data/lib/gratr/digraph.rb +115 -0
  17. data/lib/gratr/digraph_distance.rb +185 -0
  18. data/lib/gratr/dot.rb +90 -0
  19. data/lib/gratr/edge.rb +145 -0
  20. data/lib/gratr/graph.rb +314 -0
  21. data/lib/gratr/graph_api.rb +82 -0
  22. data/lib/gratr/import.rb +44 -0
  23. data/lib/gratr/labels.rb +103 -0
  24. data/lib/gratr/maximum_flow.rb +107 -0
  25. data/lib/gratr/rdot.rb +332 -0
  26. data/lib/gratr/search.rb +422 -0
  27. data/lib/gratr/strong_components.rb +127 -0
  28. data/lib/gratr/undirected_graph.rb +153 -0
  29. data/lib/gratr/version.rb +6 -0
  30. data/lib/priority-queue/benchmark/dijkstra.rb +171 -0
  31. data/lib/priority-queue/compare_comments.rb +49 -0
  32. data/lib/priority-queue/ext/priority_queue/CPriorityQueue/extconf.rb +2 -0
  33. data/lib/priority-queue/lib/priority_queue.rb +14 -0
  34. data/lib/priority-queue/lib/priority_queue/c_priority_queue.rb +1 -0
  35. data/lib/priority-queue/lib/priority_queue/poor_priority_queue.rb +46 -0
  36. data/lib/priority-queue/lib/priority_queue/ruby_priority_queue.rb +525 -0
  37. data/lib/priority-queue/setup.rb +1551 -0
  38. data/lib/priority-queue/test/priority_queue_test.rb +371 -0
  39. data/tests/TestBiconnected.rb +53 -0
  40. data/tests/TestChinesePostman.rb +53 -0
  41. data/tests/TestComplement.rb +54 -0
  42. data/tests/TestDigraph.rb +333 -0
  43. data/tests/TestDigraphDistance.rb +138 -0
  44. data/tests/TestDot.rb +75 -0
  45. data/tests/TestEdge.rb +171 -0
  46. data/tests/TestInspection.rb +57 -0
  47. data/tests/TestMultiEdge.rb +57 -0
  48. data/tests/TestNeighborhood.rb +64 -0
  49. data/tests/TestProperties.rb +160 -0
  50. data/tests/TestSearch.rb +277 -0
  51. data/tests/TestStrongComponents.rb +85 -0
  52. data/tests/TestTriagulated.rb +137 -0
  53. data/tests/TestUndirectedGraph.rb +219 -0
  54. metadata +152 -0
@@ -0,0 +1,54 @@
1
+ #--
2
+ # Copyright (c) 2006 Shawn Patrick Garbett
3
+ # Copyright (c) 2002,2004,2005 by Horst Duchene
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification,
6
+ # are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice(s),
9
+ # this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ # * Neither the name of the Shawn Garbett nor the names of its contributors
14
+ # may be used to endorse or promote products derived from this software
15
+ # without specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #++
28
+
29
+
30
+ require 'test/unit'
31
+ require 'gratr/import'
32
+
33
+ class TestComplement < Test::Unit::TestCase # :nodoc:
34
+
35
+ def test_square
36
+ x = UndirectedGraph[:a,:b, :b,:c, :c,:d, :d,:a].complement
37
+ assert_equal 2, x.edges.size
38
+ assert x.edges.include?(Edge[:a,:c])
39
+ assert x.edges.include?(Edge[:b,:d])
40
+ end
41
+
42
+ def test_g1
43
+ g1 = UndirectedGraph[ :a,:b, :a,:d, :a,:e, :a,:i, :a,:g, :a,:h,
44
+ :b,:c, :b,:f,
45
+ :c,:d, :c,:h,
46
+ :d,:h, :d,:e,
47
+ :e,:f,
48
+ :f,:g, :f,:h, :f,:i,
49
+ :h,:i ].complement
50
+ assert_equal 19, g1.edges.size
51
+
52
+ end
53
+
54
+ end
@@ -0,0 +1,333 @@
1
+ #--
2
+ # Copyright (c) 2006 Shawn Patrick Garbett
3
+ # Copyright (c) 2002,2004,2005 by Horst Duchene
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #++
24
+
25
+ require 'test/unit'
26
+ require 'gratr/import'
27
+
28
+ class TestDigraph < Test::Unit::TestCase # :nodoc:
29
+
30
+ def setup
31
+ @single = Digraph[1,2, 2,3, 3,4, 1,2, 2,3, 4,4]
32
+ @dups = DirectedPseudoGraph[1,2, 2,3, 3,4, 1,2, 2,3, 4,4]
33
+ @loops = DirectedMultiGraph[1,2, 2,3, 3,4, 4,4, 1,2, 2,3]
34
+ end
35
+
36
+ def test_new
37
+ assert_equal Digraph[1,2, 2,3, 3,4], @single
38
+ assert_equal DirectedPseudoGraph.new([1,2, 2,3, 3,4, 1,2, 2,3]), @dups
39
+ assert_equal DirectedMultiGraph.new([1,2, 2,3, 3,4, 4,4, 1,2, 2,3]), @loops
40
+ assert_raise(ArgumentError) {Digraph.new(:loops)}
41
+ assert_raise(ArgumentError) {Digraph.new(:parallel_edges)}
42
+ assert_raise(ArgumentError) {DirectedMultiGraph.new(:loops)}
43
+ assert_raise(ArgumentError) {DirectedMultiGraph.new(:parallel_edges)}
44
+ assert_raise(ArgumentError) {DirectedPseudoGraph.new(:loops)}
45
+ assert_raise(ArgumentError) {DirectedPseudoGraph.new(:parallel_edges)}
46
+ assert_raise(ArgumentError) {Digraph.new(1)}
47
+ assert_equal @single, Digraph.new(@single)
48
+ assert_equal @dups, DirectedPseudoGraph.new(@dups)
49
+ assert_equal @loops, DirectedMultiGraph.new(@loops)
50
+ assert_equal Digraph[1,2, 2,3, 3,4], Digraph.new(@loops)
51
+ end
52
+
53
+ def test_edges
54
+ assert_equal 3,@single.edges.size
55
+ assert @single.edges.include?(Arc[1,2])
56
+ assert @single.edges.include?(Arc[2,3])
57
+ assert @single.edges.include?(Arc[3,4])
58
+ assert !@single.edges.include?(Arc[4,4])
59
+ assert @single.edges.include?(Arc[1,2])
60
+ assert @single.edges.include?(Arc[2,3])
61
+ assert !@single.edges.include?(Arc[1,3])
62
+ assert @single.edge?(2,3)
63
+ assert !@single.edge?(1,4)
64
+ assert @single.edge?(Arc[1,2])
65
+ assert !@single.add_edge!(5,5).edge?(5,5)
66
+ assert !@single.remove_edge!(5,5).edge?(5,5)
67
+
68
+ assert_equal 5,@dups.edges.size
69
+ assert @dups.edges.include?(MultiArc[1,2])
70
+ assert @dups.edges.include?(MultiArc[2,3])
71
+ assert @dups.edges.include?(MultiArc[3,4])
72
+ assert !@dups.edges.include?(MultiArc[4,4])
73
+ assert @dups.edges.include?(MultiArc[1,2])
74
+ assert @dups.edges.include?(MultiArc[2,3])
75
+ assert !@dups.edges.include?(MultiArc[1,3])
76
+ assert @dups.edge?(2,3)
77
+ assert !@dups.edge?(1,4)
78
+ assert @dups.edge?(MultiArc[1,2])
79
+ assert !@dups.add_edge!(5,5).edge?(5,5)
80
+ assert_raise(ArgumentError) { @dups.remove_edge!(5,5) }
81
+
82
+ assert_equal 5,@dups.edges.size
83
+ assert @loops.edges.include?(MultiArc[1,2])
84
+ assert @loops.edges.include?(MultiArc[2,3])
85
+ assert @loops.edges.include?(MultiArc[3,4])
86
+ assert @loops.edges.include?(MultiArc[4,4])
87
+ assert @loops.edges.include?(MultiArc[1,2])
88
+ assert @loops.edges.include?(MultiArc[2,3])
89
+ assert !@loops.edges.include?(MultiArc[1,3])
90
+ assert @loops.edge?(2,3)
91
+ assert !@loops.edge?(1,4)
92
+ assert @loops.edge?(MultiArc[1,2])
93
+ assert @loops.add_edge!(5,5).edge?(5,5)
94
+ assert_raise(ArgumentError) { @loops.remove_edge!(5,5) }
95
+
96
+ end
97
+
98
+ def test_vertices
99
+ assert_equal [1,2,3,4], @single.vertices.sort
100
+ assert_equal [1,2,3,4,5], @single.add_vertex!(5).sort
101
+ assert_equal [1,2,4,5], @single.remove_vertex!(3).sort
102
+ assert !@single.vertex?(3)
103
+ assert !@single.edge?(2,3)
104
+ assert !@single.edge?(3,4)
105
+ assert @single.add_vertex(:bogus).vertex?(:bogus)
106
+ assert !@single.add_vertex(:bogus).vertex?(nil)
107
+ assert !@single.vertex?(:bogus)
108
+ @single.add_vertex!(:real)
109
+ assert @single.vertex?(:real)
110
+ assert @single.add_edge(:here, :there).edge?(Arc[:here, :there])
111
+ assert !@single.edge?(Arc[:here, :there])
112
+ assert !@single.vertex?(:here)
113
+ assert !@single.vertex?(:there)
114
+ @single.add_edge!(:here, :there)
115
+ assert @single.edge?(Arc[:here, :there])
116
+ assert @single.vertex?(:here)
117
+ assert @single.vertex?(:there)
118
+ end
119
+
120
+ def test_properties
121
+ assert @single.directed?
122
+ assert @single.empty? == false
123
+ assert Digraph.new.empty? == true
124
+ assert_equal 4, @single.size
125
+ assert_equal 4, @dups.size
126
+ assert_equal 4, @loops.size
127
+ assert_equal 4, @single.num_vertices
128
+ assert_equal 4, @dups.num_vertices
129
+ assert_equal 3, @single.num_edges
130
+ assert_equal 5, @dups.num_edges
131
+ assert_equal 6, @loops.num_edges
132
+ assert @single.oriented?
133
+ @single.remove_vertex!(4)
134
+ assert @single.oriented?
135
+ assert !@loops.oriented?
136
+ @loops.remove_vertex!(4)
137
+ assert @loops.oriented?
138
+ end
139
+
140
+ def test_merge
141
+ @dups.merge(@single)
142
+ assert_equal 8, @dups.num_edges
143
+ assert_equal [1,2,3,4], @dups.vertices.sort
144
+ end
145
+
146
+ def test_operators
147
+ result = @single + Arc[3,2]
148
+ assert_equal 4, @single.size
149
+ assert_equal 3, @single.num_edges
150
+ assert_equal 4, result.size
151
+ assert_equal 4, result.num_edges
152
+
153
+ result = @single + 5
154
+ assert_equal 4, @single.size
155
+ assert_equal 3, @single.num_edges
156
+ assert_equal 5, result.size
157
+ assert_equal 3, result.num_edges
158
+
159
+ result = @single - Arc[4,4]
160
+ assert_equal 4, @single.size
161
+ assert_equal 3, @single.num_edges
162
+ assert_equal 4, result.size
163
+ assert_equal 3, result.num_edges
164
+
165
+ e = @loops.edges.detect{|e| e.source == 4 and e.target == 4}
166
+ result = @loops - e
167
+ assert_equal 4, @single.size
168
+ assert_equal 3, @single.num_edges
169
+ assert_equal 4, result.size
170
+ assert_equal 5, result.num_edges
171
+
172
+ result = @single - 4
173
+ assert_equal 4, @single.size
174
+ assert_equal 3, @single.num_edges
175
+ assert_equal 3, result.size
176
+ assert_equal 2, result.num_edges
177
+
178
+ @single << Arc[6,1]
179
+ assert_equal 5, @single.size
180
+ assert_equal 4, @single.num_edges
181
+ assert @single.edge?(6,1)
182
+ end
183
+
184
+ def test_reversal
185
+ reverse = @single.add_vertex!(42).reversal
186
+ assert_equal [1,2,3,4,42], reverse.vertices.sort
187
+ assert reverse.edge?(2,1)
188
+ assert reverse.edge?(3,2)
189
+ assert reverse.edge?(4,3)
190
+ assert !reverse.edge?(4,4)
191
+ assert_equal 3, reverse.num_edges
192
+ reverse = @loops.reversal
193
+ assert reverse.edge?(4,4)
194
+ end
195
+
196
+ def test_complement
197
+ complement = @single.complement
198
+ assert_equal [1,2,3,4], complement.vertices.sort
199
+ assert !complement.edge?(1,1)
200
+ assert complement.edge?(1,3)
201
+ assert complement.edge?(1,4)
202
+ assert complement.edge?(2,1)
203
+ assert complement.edge?(2,4)
204
+ assert complement.edge?(3,1)
205
+ assert complement.edge?(3,2)
206
+ assert complement.edge?(4,1)
207
+ assert complement.edge?(4,2)
208
+ assert complement.edge?(4,3)
209
+ assert 9, complement.num_edges
210
+
211
+ complement = @loops.complement
212
+ assert_equal [1,2,3,4], complement.vertices.sort
213
+ assert complement.edge?(1,1)
214
+ assert complement.edge?(1,3)
215
+ assert complement.edge?(1,4)
216
+ assert complement.edge?(2,1)
217
+ assert complement.edge?(2,2)
218
+ assert complement.edge?(2,4)
219
+ assert complement.edge?(3,1)
220
+ assert complement.edge?(3,2)
221
+ assert complement.edge?(3,3)
222
+ assert complement.edge?(4,1)
223
+ assert complement.edge?(4,2)
224
+ assert complement.edge?(4,3)
225
+ assert 12, complement.num_edges
226
+ end
227
+
228
+ def test_induced_subgraph
229
+ induced = @single.induced_subgraph([1,2])
230
+ assert [1,2], induced.vertices.sort
231
+ assert induced.edge?(1,2)
232
+ assert 1, induced.num_edges
233
+ end
234
+
235
+ def test_include
236
+ assert @single.include?(4)
237
+ assert @dups.include?(4)
238
+ assert !@dups.include?(5)
239
+ assert !@single.include?(5)
240
+ assert @single.include?(Arc[1,2])
241
+ assert @dups.include?(Arc[1,2])
242
+ end
243
+
244
+ def test_adjacent
245
+
246
+ assert @single.adjacent?(2, Arc[1,2])
247
+ assert_equal [2], @single.adjacent(1)
248
+
249
+ assert_equal [Arc[1,2]], @single.adjacent(1, :type=>:edges)
250
+ assert_equal [Arc[1,2]], @single.adjacent(1, :type=>:edges, :direction=> :out)
251
+ assert_equal [Arc[1,2]], @single.adjacent(2, :type=>:edges, :direction=> :in)
252
+ assert_equal [Arc[1,2],Arc[2,3]], @single.adjacent(2, :type=>:edges, :direction=> :all).sort
253
+
254
+ [[{},1], [{:direction => :out},1], [{:direction => :in},2]].each do |h,v|
255
+ adj = @dups.adjacent(v, h.merge(:type=>:edges))
256
+ assert_equal 2, adj.size
257
+ adj.each {|e| assert e.source == 1; assert e.target == 2}
258
+ end
259
+
260
+ adj = @dups.adjacent(2, {:type=>:edges,:direction=>:all})
261
+ assert_equal 4, adj.size
262
+ adj.each do |e|
263
+ assert((e.source==1 and e.target==2) ||
264
+ (e.source==2 and e.target==3))
265
+ end
266
+
267
+ assert_equal [2], @single.adjacent(1, :type=>:vertices)
268
+ assert_equal [2], @single.adjacent(1, :type=>:vertices, :direction=> :out)
269
+ assert_equal [1], @single.adjacent(2, :type=>:vertices, :direction=> :in)
270
+ assert_equal [1,3], @single.adjacent(2, :type=>:vertices, :direction=> :all)
271
+
272
+ assert_equal [3], @single.adjacent(Arc[2,3], :type=>:vertices)
273
+ assert_equal [3], @single.adjacent(Arc[2,3], :type=>:vertices, :direction=> :out)
274
+ assert_equal [2], @single.adjacent(Arc[2,3], :type=>:vertices, :direction=> :in)
275
+ assert_equal [2,3], @single.adjacent(Arc[2,3], :type=>:vertices, :direction=> :all)
276
+
277
+ assert_equal [Arc[3,4]], @single.adjacent(Arc[2,3], :type=>:edges)
278
+ assert_equal [Arc[3,4]], @single.adjacent(Arc[2,3], :type=>:edges, :direction=> :out)
279
+ assert_equal [Arc[1,2]], @single.adjacent(Arc[2,3], :type=>:edges, :direction=> :in)
280
+ assert_equal [Arc[1,2],Arc[3,4]], @single.adjacent(Arc[2,3], :type=>:edges, :direction=> :all).sort
281
+
282
+ assert_equal [MultiArc[3,4]], @dups.adjacent(MultiArc[2,3], :type=>:edges)
283
+ assert_equal [MultiArc[3,4]], @dups.adjacent(MultiArc[2,3], :type=>:edges, :direction=> :out)
284
+ assert_equal [MultiArc[1,2]]*2, @dups.adjacent(MultiArc[2,3], :type=>:edges, :direction=> :in)
285
+ assert_equal ([MultiArc[1,2]]*2+[MultiArc[3,4]]), @dups.adjacent(MultiArc[2,3], :type=>:edges, :direction=> :all).sort
286
+ end
287
+
288
+ def test_neighborhood
289
+ assert_equal [2], @single.neighborhood(1).sort
290
+ assert_equal [1,3], @single.neighborhood(2).sort
291
+ assert_equal [Arc[1,2], Arc[3,4]], @single.neighborhood(Arc[2,3]).sort
292
+ end
293
+
294
+ def test_degree
295
+ assert_equal 0, @single.in_degree(1)
296
+ assert_equal 1, @single.in_degree(2)
297
+ assert_equal 1, @single.in_degree(4)
298
+ assert_equal 3, @loops.degree(4)
299
+ assert_equal 2, @loops.in_degree(4)
300
+ assert_equal 1, @single.out_degree(1)
301
+ assert_equal 1, @single.out_degree(2)
302
+ assert_equal 0, @single.out_degree(4)
303
+ assert_equal 1, @loops.out_degree(4)
304
+ assert_equal 0, @single.add_vertex!(6).out_degree(6)
305
+ assert_equal 0, @single.add_vertex!(7).in_degree(7)
306
+ assert_equal 1, @single.add_edge!(4,2).out_degree(4)
307
+ assert_equal 2, @loops.add_edge!(4,2).out_degree(4)
308
+ assert_equal 2, @single.in_degree(2)
309
+
310
+ assert_equal 0, @single.min_in_degree
311
+ assert_equal 2, @single.max_in_degree
312
+ assert_equal 0, @single.min_out_degree
313
+ assert_equal 1, @single.max_out_degree
314
+
315
+ assert_equal 0, @loops.min_in_degree
316
+ assert_equal 2, @loops.max_in_degree
317
+ assert_equal 1, @loops.min_out_degree
318
+ assert_equal 2, @loops.max_out_degree
319
+ assert_equal 4, @loops.degree(2)
320
+ assert_equal 1, @single.degree(1)
321
+ assert !@loops.regular?
322
+ assert !@single.regular?
323
+ assert !@dups.regular?
324
+ end
325
+
326
+ def test_include
327
+ assert @single.include?(2)
328
+ assert !@single.include?(23)
329
+ assert @single.include?(Arc[1,2])
330
+ assert !@single.include?(Arc[1,4])
331
+ end
332
+
333
+ end
@@ -0,0 +1,138 @@
1
+ #--
2
+ # Copyright (c) 2006 Shawn Patrick Garbett
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without modification,
5
+ # are permitted provided that the following conditions are met:
6
+ #
7
+ # * Redistributions of source code must retain the above copyright notice(s),
8
+ # this list of conditions and the following disclaimer.
9
+ # * Redistributions in binary form must reproduce the above copyright notice,
10
+ # this list of conditions and the following disclaimer in the documentation
11
+ # and/or other materials provided with the distribution.
12
+ # * Neither the name of the Shawn Garbett nor the names of its contributors
13
+ # may be used to endorse or promote products derived from this software
14
+ # without specific prior written permission.
15
+ #
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ #++
27
+
28
+
29
+ require 'test/unit'
30
+ require 'gratr/import'
31
+
32
+ class TestDigraphDistance < Test::Unit::TestCase # :nodoc:
33
+
34
+ def setup
35
+ @d = Digraph[ :a,:b, :a,:e,
36
+ :b,:c, :b,:e,
37
+ :c,:d,
38
+ :d,:c,
39
+ :e,:b, :e,:f,
40
+ :f,:c, :f,:d, :f,:e ]
41
+
42
+ @w = { Arc[:a,:b] => 9,
43
+ Arc[:a,:e] => 3,
44
+ Arc[:b,:c] => 2,
45
+ Arc[:b,:e] => 6,
46
+ Arc[:c,:d] => 1,
47
+ Arc[:d,:c] => 2,
48
+ Arc[:e,:b] => 2,
49
+ Arc[:e,:f] => 1,
50
+ Arc[:f,:c] => 2,
51
+ Arc[:f,:d] => 7,
52
+ Arc[:f,:e] => 2 }
53
+ @a = { :a => 0,
54
+ :b => 5,
55
+ :c => 6,
56
+ :d => 7,
57
+ :e => 3,
58
+ :f => 4 }
59
+ @simple_weight = Proc.new {|e| 1}
60
+ end
61
+
62
+ def test_shortest_path
63
+ x = Digraph[ :s,:u, :s,:w,
64
+ :j,:v,
65
+ :u,:j,
66
+ :v,:y,
67
+ :w,:u, :w,:v, :w,:y, :w,:x,
68
+ :x,:z ]
69
+ assert x.acyclic?
70
+ cost, path = x.shortest_path(:s,@simple_weight)
71
+ assert_equal({:x=>2, :v=>2, :y=>2, :w=>1, :s=>0, :z=>3, :u=>1, :j=> 2}, cost)
72
+ assert_equal({:x=>:w, :v=>:w, :y=>:w, :w=>:s, :z=>:x, :u=>:s, :j=>:u}, path)
73
+ end
74
+
75
+ def test_dijkstra_with_proc
76
+ p = Proc.new {|e| @w[e]}
77
+ distance, path = @d.dijkstras_algorithm(:a,p)
78
+ assert_equal @a, distance
79
+ assert_equal({ :d => :c, :c => :f, :f => :e, :b => :e, :e => :a}, path)
80
+ end
81
+
82
+ def test_dijkstra_with_label
83
+ @w.keys.each {|e| @d[e] = @w[e]}
84
+ assert_equal @a, @d.dijkstras_algorithm(:a)[0]
85
+ end
86
+
87
+ def test_dijkstra_with_bracket_label
88
+ @w.keys.each do |e|
89
+ @d[e] = { :xyz => (@w[e])}
90
+ end
91
+ assert_equal @a, @d.dijkstras_algorithm(:a, :xyz)[0]
92
+ @w.keys.each do |e|
93
+ @d[e] = [@w[e]]
94
+ end
95
+ assert_equal @a, @d.dijkstras_algorithm(:a, 0)[0]
96
+ end
97
+
98
+ def test_floyd_warshall
99
+ simple = Digraph[ 0,1, 0,2, 1,2, 1,3, 2,3, 3,0 ]
100
+
101
+ cost, path, delta = simple.floyd_warshall(@simple_weight)
102
+ # Costs
103
+ assert_equal({0=>3, 1=>1, 2=>1, 3=>2}, cost[0])
104
+ assert_equal({0=>2, 1=>3, 2=>1, 3=>1}, cost[1])
105
+ assert_equal({0=>2, 1=>3, 2=>3, 3=>1}, cost[2])
106
+ assert_equal({0=>1, 1=>2, 2=>2, 3=>3}, cost[3])
107
+
108
+ # Paths
109
+ assert_equal({0=>1, 1=>1, 2=>2, 3=>1}, path[0])
110
+ assert_equal({0=>3, 1=>3, 2=>2, 3=>3}, path[1])
111
+ assert_equal({0=>3, 1=>3, 2=>3, 3=>3}, path[2])
112
+ assert_equal({0=>0, 1=>0, 2=>0, 3=>0}, path[3])
113
+
114
+ # Deltas
115
+ assert_equal 1, delta[0]
116
+ assert_equal 1, delta[1]
117
+ assert_equal -1, delta[2]
118
+ assert_equal -1, delta[3]
119
+ end
120
+
121
+ def test_bellman_ford_moore
122
+ fig24 = Digraph[ [:s,:e] => 8,
123
+ [:s,:d] => 4,
124
+ [:e,:c] => 2,
125
+ [:e,:d] => -5,
126
+ [:c,:b] => -2,
127
+ [:d,:c] => -2,
128
+ [:d,:a] => 4,
129
+ [:a,:c] => 10,
130
+ [:a,:b] => 9,
131
+ [:b,:c] => 5,
132
+ [:b,:a] => -3]
133
+ cost, path = fig24.bellman_ford_moore(:s)
134
+ assert_equal({:e=>8, :d=>3, :c=>1, :b=>-1, :a=>-4, :s=>0}, cost)
135
+ assert_equal({:e=>:s, :d=>:e, :c=>:d, :b=>:c, :a=>:b}, path)
136
+ end
137
+
138
+ end