gratr19 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README +335 -0
- data/examples/graph_self.rb +54 -0
- data/examples/module_graph.jpg +0 -0
- data/examples/module_graph.rb +12 -0
- data/examples/self_graph.jpg +0 -0
- data/examples/visualize.jpg +0 -0
- data/examples/visualize.rb +8 -0
- data/install.rb +49 -0
- data/lib/gratr.rb +42 -0
- data/lib/gratr/adjacency_graph.rb +230 -0
- data/lib/gratr/base.rb +34 -0
- data/lib/gratr/biconnected.rb +116 -0
- data/lib/gratr/chinese_postman.rb +123 -0
- data/lib/gratr/common.rb +74 -0
- data/lib/gratr/comparability.rb +92 -0
- data/lib/gratr/digraph.rb +115 -0
- data/lib/gratr/digraph_distance.rb +185 -0
- data/lib/gratr/dot.rb +90 -0
- data/lib/gratr/edge.rb +145 -0
- data/lib/gratr/graph.rb +314 -0
- data/lib/gratr/graph_api.rb +82 -0
- data/lib/gratr/import.rb +44 -0
- data/lib/gratr/labels.rb +103 -0
- data/lib/gratr/maximum_flow.rb +107 -0
- data/lib/gratr/rdot.rb +332 -0
- data/lib/gratr/search.rb +422 -0
- data/lib/gratr/strong_components.rb +127 -0
- data/lib/gratr/undirected_graph.rb +153 -0
- data/lib/gratr/version.rb +6 -0
- data/lib/priority-queue/benchmark/dijkstra.rb +171 -0
- data/lib/priority-queue/compare_comments.rb +49 -0
- data/lib/priority-queue/ext/priority_queue/CPriorityQueue/extconf.rb +2 -0
- data/lib/priority-queue/lib/priority_queue.rb +14 -0
- data/lib/priority-queue/lib/priority_queue/c_priority_queue.rb +1 -0
- data/lib/priority-queue/lib/priority_queue/poor_priority_queue.rb +46 -0
- data/lib/priority-queue/lib/priority_queue/ruby_priority_queue.rb +525 -0
- data/lib/priority-queue/setup.rb +1551 -0
- data/lib/priority-queue/test/priority_queue_test.rb +371 -0
- data/tests/TestBiconnected.rb +53 -0
- data/tests/TestChinesePostman.rb +53 -0
- data/tests/TestComplement.rb +54 -0
- data/tests/TestDigraph.rb +333 -0
- data/tests/TestDigraphDistance.rb +138 -0
- data/tests/TestDot.rb +75 -0
- data/tests/TestEdge.rb +171 -0
- data/tests/TestInspection.rb +57 -0
- data/tests/TestMultiEdge.rb +57 -0
- data/tests/TestNeighborhood.rb +64 -0
- data/tests/TestProperties.rb +160 -0
- data/tests/TestSearch.rb +277 -0
- data/tests/TestStrongComponents.rb +85 -0
- data/tests/TestTriagulated.rb +137 -0
- data/tests/TestUndirectedGraph.rb +219 -0
- 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
|