gratr19 0.4.4

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 (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,371 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # Priority Queue tests
4
+
5
+ $:.unshift '../ext/priority_queue/CPriorityQueue'
6
+ $:.unshift '../lib/'
7
+
8
+ require 'test/unit'
9
+
10
+ require 'priority_queue/ruby_priority_queue'
11
+ require 'priority_queue/poor_priority_queue'
12
+ begin
13
+ require 'priority_queue/CPriorityQueue'
14
+ rescue LoadError
15
+ require 'CPriorityQueue'
16
+ end
17
+
18
+
19
+ module PriorityQueueTest
20
+ # Check that the order is maintained
21
+ def teardown
22
+ last = @q.min_priority
23
+ while priority = @q.delete_min_return_priority
24
+ assert_operator(last, :<=, priority)
25
+ last = priority
26
+ end
27
+ end
28
+
29
+ def test_length
30
+ 20.times do | i |
31
+ assert_equal(i, @q.length)
32
+ @q[i] = i
33
+ end
34
+ 10.times do | i |
35
+ assert_equal(20-i, @q.length)
36
+ @q.delete_min
37
+ end
38
+ 10.times do | i |
39
+ assert_equal(10+i, @q.length)
40
+ @q[i] = i
41
+ end
42
+ @q.delete(5)
43
+ assert_equal(19, @q.length)
44
+ end
45
+
46
+ def test_merge
47
+ @q1 = @q.class.new
48
+ @q2 = @q.class.new
49
+
50
+ 20.times do | i |
51
+ @q1[i] = i
52
+ @q2[i+20] = i+20
53
+ end
54
+ end
55
+
56
+ # Assure that delete min works
57
+ def test_delete_min
58
+ assert_equal(nil, @q.delete_min, "Empty queue should pop nil")
59
+ @q["n1"] = 0
60
+ assert_equal(["n1", 0], @q.delete_min)
61
+ @q["n1"] = 0
62
+ @q["n2"] = -1
63
+ assert_equal(["n2", -1], @q.delete_min)
64
+ end
65
+
66
+ def test_delete_min_return_key
67
+ assert_equal(nil, @q.delete_min_return_key, "Empty queue should pop nil")
68
+ @q["n1"] = 0
69
+ assert_equal("n1", @q.delete_min_return_key)
70
+ @q["n1"] = 0
71
+ @q["n2"] = -1
72
+ assert_equal("n2", @q.delete_min_return_key)
73
+ end
74
+
75
+ def test_delete_min_return_priority
76
+ assert_equal(nil, @q.delete_min_return_priority, "Empty queue should pop nil")
77
+ @q["n1"] = 0
78
+ assert_equal(0, @q.delete_min_return_priority)
79
+ @q["n1"] = 0
80
+ @q["n2"] = -1
81
+ assert_equal(-1, @q.delete_min_return_priority)
82
+ end
83
+
84
+ def test_has_key?
85
+ assert(!@q.has_key?(1))
86
+ @q[1] = 1
87
+ assert(@q.has_key?(1))
88
+ end
89
+
90
+ def test_empty?
91
+ assert_equal(true, @q.empty?, "Empty queue should return true on empty?")
92
+ @q["node1"] = 10
93
+ assert_equal(false, @q.empty?, "Filled queue should return false on empty?")
94
+ end
95
+
96
+ def test_push
97
+ 20.times do | i |
98
+ @q.push i, i+10
99
+ end
100
+
101
+ 20.times do | i |
102
+ @q.push i, i
103
+ end
104
+
105
+ 20.times do | i |
106
+ assert_equal([i, i], @q.delete_min)
107
+ end
108
+
109
+ assert_equal(nil, @q.delete_min)
110
+ end
111
+
112
+ def test_push_pop
113
+ 20.times do | i |
114
+ @q.push i, i
115
+ end
116
+
117
+ 20.times do | i |
118
+ assert_equal([i, i], @q.delete_min)
119
+ end
120
+
121
+ assert_equal(nil, @q.delete_min)
122
+ end
123
+
124
+ def test_push_decrease_pop
125
+ 50.times do | i |
126
+ @q.push i, i
127
+ end
128
+
129
+ 10.times do | i |
130
+ assert_equal([i, i], @q.delete_min)
131
+ end
132
+
133
+ 10.times do | i |
134
+ @q[i+10] = i
135
+ end
136
+
137
+ 10.times do | i |
138
+ assert_equal([i+10, i], @q.delete_min)
139
+ end
140
+
141
+ 30.times do | i |
142
+ assert_equal([i+20, i+20], @q.delete_min)
143
+ end
144
+
145
+ assert_equal(nil, @q.delete_min)
146
+ end
147
+
148
+ def test_min_key
149
+ assert_equal(nil, @q.min_key)
150
+ @q["node1"] = 0
151
+ assert_equal("node1", @q.min_key)
152
+ @q["node2"] = 1
153
+ assert_equal("node1", @q.min_key)
154
+ @q["node3"] = -1
155
+ assert_equal("node3", @q.min_key)
156
+ end
157
+
158
+ def test_min_priority
159
+ assert_equal(nil, @q.min_priority)
160
+ @q["node1"] = 0
161
+ assert_equal(0, @q.min_priority)
162
+ @q["node2"] = 1
163
+ assert_equal(0, @q.min_priority)
164
+ @q["node3"] = -1
165
+ assert_equal(-1, @q.min_priority)
166
+ end
167
+
168
+ def test_access
169
+ assert_equal(0, @q["node1"] = 0)
170
+ assert_equal(["node1", 0], @q.min)
171
+ assert_equal(1, @q["node2"] = 1)
172
+ assert_equal(1, @q["node2"])
173
+ assert_equal("node1", @q.min_key)
174
+ assert_equal(2, @q["node3"] = 2)
175
+ assert_equal(2, @q["node3"])
176
+ assert_equal("node1", @q.min_key)
177
+ assert_equal(-1, @q["node3"] = -1)
178
+ assert_equal(-1, @q["node3"])
179
+ assert_equal("node3", @q.min_key)
180
+ end
181
+
182
+ def test_min
183
+ assert_equal(nil, @q.min)
184
+ @q["node1"] = 10
185
+ assert_equal(["node1", 10], @q.min)
186
+ @q["node2"] = 5
187
+ assert_equal(["node2", 5], @q.min)
188
+ end
189
+
190
+ def test_decrease_priority
191
+
192
+ 20.times do | i |
193
+ @q.push i, i / 20.0
194
+ end
195
+
196
+ assert_equal([0, 0], @q.delete_min)
197
+
198
+ @q[10] = -1
199
+ @q[11] = -0.5
200
+
201
+ [10, 11, (1..9).to_a, (12..19).to_a, nil].flatten.each do | shall |
202
+ key, priority = *@q.delete_min
203
+ assert_equal(shall, key)
204
+ end
205
+ end
206
+
207
+ def test_increase_priority
208
+ 20.times do | i |
209
+ @q[i] = i
210
+ end
211
+ @q[10] = 5
212
+ assert_equal([0,0], @q.delete_min)
213
+ assert_equal(10, @q[10] = 10)
214
+ assert_equal(20, @q[11] = 20)
215
+ assert_equal([1,1], @q.delete_min)
216
+ end
217
+
218
+ def test_delete
219
+ @q[1] = 1
220
+ @q[2] = 2
221
+ @q[3] = 3
222
+ assert_equal(1, @q[1])
223
+ assert_equal([1,1], @q.min)
224
+ assert_equal([1,1], @q.delete(1))
225
+ assert_equal(nil, @q[1])
226
+ assert_equal([2,2], @q.min)
227
+ assert_equal(nil, @q.delete(1))
228
+ end
229
+
230
+ def test_example_1
231
+ assert_equal(0, @q["node1"] = 0)
232
+ assert_equal(1, @q["node2"] = 1)
233
+ assert_equal("node1", @q.min_key)
234
+ assert_equal(0, @q[@q.min_key])
235
+ assert_equal(0, @q.min_priority)
236
+
237
+ @q["node2"] = -1
238
+ assert_equal(["node2", -1], @q.delete_min)
239
+ assert_equal(nil, @q["node2"])
240
+ @q["node3"] = 1
241
+
242
+ assert_equal(["node3", 1], @q.delete("node3"))
243
+ assert_equal(nil, @q.delete("node2"))
244
+ end
245
+
246
+ def test_dup
247
+ ('a'..'z').each do | n |
248
+ @q[n] = n[0]
249
+ end
250
+ qq = @q.dup
251
+ until @q.empty?
252
+ assert_equal(@q.delete_min, qq.delete_min)
253
+ end
254
+ end
255
+
256
+ def test_each
257
+ ('a'..'z').each do | n |
258
+ @q[n] = n[0]
259
+ end
260
+ queue = ('a'..'z').inject([]) { | r, n | r << [n, n[0]] }
261
+ assert_equal(queue.sort, @q.to_a.sort)
262
+ end
263
+
264
+ extend self
265
+ end
266
+
267
+ class CPriorityQueueTest < Test::Unit::TestCase
268
+ include PriorityQueueTest
269
+
270
+ def setup
271
+ @q = CPriorityQueue.new
272
+ end
273
+
274
+ def test_to_dot
275
+ 5.times do | i |
276
+ @q.push "N#{i}", i
277
+ end
278
+ @q.delete_min
279
+ assert_equal(
280
+ ['digraph fibonacci_heap {',
281
+ ' NODE [label="N1 (1)",shape=box];',
282
+ ' NODE [label="N3 (3)",shape=box];',
283
+ ' NODE [label="N4 (4)",shape=box];',
284
+ ' NODE -> NODE;',
285
+ ' NODE -> NODE;',
286
+ ' NODE [label="N2 (2)",shape=box];',
287
+ ' NODE -> NODE;',
288
+ '}',''].join("\n"), @q.to_dot.gsub(/NODE[0-9]*/, 'NODE'))
289
+ end
290
+
291
+ end
292
+
293
+ class PoorPriorityQueueTest < Test::Unit::TestCase
294
+ include PriorityQueueTest
295
+
296
+ def setup
297
+ @q = PoorPriorityQueue.new
298
+ end
299
+
300
+ end
301
+
302
+ class RubyPriorityQueueTest < Test::Unit::TestCase
303
+ include PriorityQueueTest
304
+
305
+ def setup
306
+ @q = RubyPriorityQueue.new
307
+ end
308
+
309
+ def test_private_link_nodes
310
+ q = RubyPriorityQueue.new
311
+ q[0] = 0
312
+ q[1] = 1
313
+ tc = self
314
+ q.instance_eval do
315
+ n0 = @nodes[0]
316
+ n1 = @nodes[1]
317
+ n0.right = n0.left = n0
318
+ n1.right = n1.left = n1
319
+ tc.assert_equal(n0, link_nodes(n0, n1))
320
+ tc.assert_equal(n0.child, n1)
321
+ tc.assert_equal(n1.child, nil)
322
+ tc.assert_equal(n0.left, n0)
323
+ tc.assert_equal(n1.left, n1)
324
+ tc.assert_equal(n0.right, n0)
325
+ tc.assert_equal(n1.right, n1)
326
+ end
327
+ q = RubyPriorityQueue.new
328
+ q[0] = 0
329
+ q[1] = 1
330
+ q.instance_eval do
331
+ n0 = @nodes[0]
332
+ n1 = @nodes[1]
333
+ n0.right = n0.left = n0
334
+ n1.right = n1.left = n1
335
+ tc.assert_equal(n0, link_nodes(n1, n0))
336
+ tc.assert_equal(n0.child, n1)
337
+ tc.assert_equal(n1.child, nil)
338
+ tc.assert_equal(n0.left, n0)
339
+ tc.assert_equal(n1.left, n1)
340
+ tc.assert_equal(n0.right, n0)
341
+ tc.assert_equal(n1.right, n1)
342
+ end
343
+ end
344
+
345
+
346
+ def test_private_delete_first
347
+ q = RubyPriorityQueue.new
348
+ q[0] = 0
349
+ q[1] = 1
350
+ q[2] = 2
351
+ tc = self
352
+ q.instance_eval do
353
+ 2.times do
354
+ r = @rootlist
355
+ tc.assert_equal(r, delete_first)
356
+ tc.assert_equal(r.right, r)
357
+ tc.assert_equal(r.left, r)
358
+ tc.assert_not_equal(r, @rootlist.left)
359
+ tc.assert_not_equal(r, @rootlist.right)
360
+ end
361
+ r = @rootlist
362
+ tc.assert_equal(r, delete_first)
363
+ tc.assert_equal(r.right, r)
364
+ tc.assert_equal(r.left, r)
365
+ tc.assert_equal(nil, @rootlist)
366
+
367
+ tc.assert_equal(nil, delete_first)
368
+ end
369
+ end
370
+ end
371
+
@@ -0,0 +1,53 @@
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
+ require 'test/unit'
29
+ require 'gratr/import'
30
+
31
+ class TestBiconnected < Test::Unit::TestCase # :nodoc:
32
+ def test_tarjan
33
+ tarjan = UndirectedGraph[ 1, 2,
34
+ 1, 5,
35
+ 1, 6,
36
+ 1, 7,
37
+ 2, 3,
38
+ 2, 4,
39
+ 3, 4,
40
+ 2, 5,
41
+ 5, 6,
42
+ 7, 8,
43
+ 7, 9,
44
+ 8, 9 ]
45
+ graphs, articulations = tarjan.biconnected
46
+ assert_equal [1,2,7], articulations.sort
47
+ assert_equal 4, graphs.size
48
+ assert_equal [1,7], graphs.find {|g| g.size == 2}.vertices.sort
49
+ assert_equal [1,2,5,6], graphs.find {|g| g.size == 4}.vertices.sort
50
+ assert_equal [2,3,4], graphs.find {|g| g.size == 3 && g.vertex?(2)}.vertices.sort
51
+ assert_equal [7,8,9], graphs.find {|g| g.size == 3 && g.vertex?(7)}.vertices.sort
52
+ end
53
+ end
@@ -0,0 +1,53 @@
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 TestChinesePostman < Test::Unit::TestCase # :nodoc:
33
+
34
+ def setup
35
+ @simple=Digraph[ 0,1, 0,2, 1,2, 1,3, 2,3, 3,0 ]
36
+ @weight = Proc.new {|e| 1}
37
+ end
38
+
39
+ def test_closed_simple_tour
40
+ tour = @simple.closed_chinese_postman_tour(0, @weight)
41
+ assert_equal 11, tour.size
42
+ assert_equal 0, tour[0]
43
+ assert_equal 0, tour[10]
44
+ edges = Set.new
45
+ 0.upto(9) do |n|
46
+ edges << Arc[tour[n],tour[n+1]]
47
+ assert(@simple.edge?(tour[n],tour[n+1]), "Arc(#{tour[n]},#{tour[n+1]}) from tour not in graph")
48
+ end
49
+ assert_equal @simple.edges.size, edges.size, "Not all arcs traversed!"
50
+ end
51
+
52
+
53
+ end