rgl 0.4.0 → 0.5.0
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.
- data/ChangeLog +19 -10
- data/Gemfile +3 -0
- data/{README → README.rdoc} +70 -98
- data/Rakefile +44 -150
- data/examples/canvas.rb +63 -64
- data/examples/examples.rb +42 -42
- data/examples/graph.dot +46 -0
- data/examples/images/example.jpg +0 -0
- data/examples/images/module_graph.jpg +0 -0
- data/examples/images/rgl_modules.png +0 -0
- data/examples/{insel-der-tausend-gefahren.rb → insel_der_tausend_gefahren.rb} +18 -19
- data/examples/north.rb +2 -2
- data/examples/north2.rb +11 -11
- data/examples/rdep-rgl.rb +218 -222
- data/lib/rgl/adjacency.rb +78 -74
- data/lib/rgl/base.rb +160 -78
- data/lib/rgl/bellman_ford.rb +115 -0
- data/lib/rgl/bidirectional.rb +17 -10
- data/lib/rgl/bipartite.rb +87 -0
- data/lib/rgl/condensation.rb +13 -4
- data/lib/rgl/connected_components.rb +38 -30
- data/lib/rgl/dijkstra.rb +158 -0
- data/lib/rgl/dijkstra_visitor.rb +42 -0
- data/lib/rgl/dot.rb +40 -32
- data/lib/rgl/edge_properties_map.rb +55 -0
- data/lib/rgl/edmonds_karp.rb +136 -0
- data/lib/rgl/enumerable_ext.rb +4 -1
- data/lib/rgl/graph_iterator.rb +15 -0
- data/lib/rgl/graph_visitor.rb +138 -0
- data/lib/rgl/graph_wrapper.rb +15 -0
- data/lib/rgl/graphxml.rb +20 -10
- data/lib/rgl/implicit.rb +68 -66
- data/lib/rgl/mutable.rb +37 -31
- data/lib/rgl/path_builder.rb +40 -0
- data/lib/rgl/prim.rb +52 -0
- data/lib/rgl/rdot.rb +411 -374
- data/lib/rgl/topsort.rb +23 -16
- data/lib/rgl/transitivity.rb +29 -27
- data/lib/rgl/traversal.rb +67 -205
- data/rakelib/dep_graph.rake +4 -3
- data/test/bellman_ford_test.rb +187 -0
- data/test/bipartite_test.rb +47 -0
- data/test/components_test.rb +80 -0
- data/test/cycles_test.rb +60 -0
- data/test/dijkstra_test.rb +148 -0
- data/test/directed_graph_test.rb +118 -0
- data/test/dot_test.rb +26 -0
- data/test/edge_properties_map_test.rb +63 -0
- data/test/edge_test.rb +35 -0
- data/test/edmonds_karp_test.rb +105 -0
- data/{tests/TestGraph.rb → test/graph_test.rb} +6 -6
- data/test/graph_xml_test.rb +57 -0
- data/test/implicit_test.rb +53 -0
- data/test/prim_test.rb +98 -0
- data/{tests/TestRdot.rb → test/rdot_test.rb} +309 -308
- data/{tests → test}/test_helper.rb +4 -1
- data/{tests/TestTransitivity.rb → test/transitivity_test.rb} +43 -43
- data/test/traversal_test.rb +221 -0
- data/test/undirected_graph_test.rb +103 -0
- metadata +226 -145
- data/examples/example.jpg +0 -0
- data/examples/module_graph.jpg +0 -0
- data/install.rb +0 -49
- data/tests/TestComponents.rb +0 -65
- data/tests/TestCycles.rb +0 -61
- data/tests/TestDirectedGraph.rb +0 -125
- data/tests/TestDot.rb +0 -18
- data/tests/TestEdge.rb +0 -34
- data/tests/TestGraphXML.rb +0 -57
- data/tests/TestImplicit.rb +0 -52
- data/tests/TestTraversal.rb +0 -220
- data/tests/TestUnDirectedGraph.rb +0 -102
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'rgl/adjacency'
|
4
|
+
|
5
|
+
include RGL
|
6
|
+
include RGL::Edge
|
7
|
+
|
8
|
+
class TestDirectedGraph < Test::Unit::TestCase
|
9
|
+
def setup
|
10
|
+
@dg = DirectedAdjacencyGraph.new
|
11
|
+
[[1, 2], [2, 3], [3, 2], [2, 4]].each do |(src, target)|
|
12
|
+
@dg.add_edge(src, target)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_empty_graph
|
17
|
+
dg = DirectedAdjacencyGraph.new
|
18
|
+
assert dg.empty?
|
19
|
+
assert dg.directed?
|
20
|
+
assert(!dg.has_edge?(2, 1))
|
21
|
+
assert(!dg.has_vertex?(3))
|
22
|
+
# Non existent vertex result in a Name Error because each_key is
|
23
|
+
# called for nil
|
24
|
+
assert_raises(NoVertexError) { dg.out_degree(3) }
|
25
|
+
assert_equal([], dg.vertices)
|
26
|
+
assert_equal(0, dg.size)
|
27
|
+
assert_equal(0, dg.num_vertices)
|
28
|
+
assert_equal(0, dg.num_edges)
|
29
|
+
assert_equal(DirectedEdge, dg.edge_class)
|
30
|
+
assert([].eql?(dg.edges))
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_add
|
34
|
+
dg = DirectedAdjacencyGraph.new
|
35
|
+
dg.add_edge(1, 2)
|
36
|
+
assert(!dg.empty?)
|
37
|
+
assert(dg.has_edge?(1, 2))
|
38
|
+
assert(!dg.has_edge?(2, 1))
|
39
|
+
assert(dg.has_vertex?(1) && dg.has_vertex?(2))
|
40
|
+
assert(!dg.has_vertex?(3))
|
41
|
+
|
42
|
+
assert_equal([1, 2], dg.vertices.sort)
|
43
|
+
assert([DirectedEdge.new(1, 2)].eql?(dg.edges))
|
44
|
+
assert_equal("(1-2)", dg.edges.join)
|
45
|
+
|
46
|
+
assert_equal([2], dg.adjacent_vertices(1))
|
47
|
+
assert_equal([], dg.adjacent_vertices(2))
|
48
|
+
|
49
|
+
assert_equal(1, dg.out_degree(1))
|
50
|
+
assert_equal(0, dg.out_degree(2))
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_edges
|
54
|
+
assert_equal(4, @dg.edges.length)
|
55
|
+
assert_equal([1, 2, 2, 3], @dg.edges.map { |l| l.source }.sort)
|
56
|
+
assert_equal([2, 2, 3, 4], @dg.edges.map { |l| l.target }.sort)
|
57
|
+
assert_equal("(1-2)(2-3)(2-4)(3-2)", @dg.edges.map { |l| l.to_s }.sort.join)
|
58
|
+
# assert_equal([0,1,2,3], @dg.edges.map {|l| l.info}.sort)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_vertices
|
62
|
+
assert_equal([1, 2, 3, 4], @dg.vertices.sort)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_edges_from_to?
|
66
|
+
assert @dg.has_edge?(1, 2)
|
67
|
+
assert @dg.has_edge?(2, 3)
|
68
|
+
assert @dg.has_edge?(3, 2)
|
69
|
+
assert @dg.has_edge?(2, 4)
|
70
|
+
assert !@dg.has_edge?(2, 1)
|
71
|
+
assert !@dg.has_edge?(3, 1)
|
72
|
+
assert !@dg.has_edge?(4, 1)
|
73
|
+
assert !@dg.has_edge?(4, 2)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_remove_edges
|
77
|
+
@dg.remove_edge 1, 2
|
78
|
+
assert !@dg.has_edge?(1, 2)
|
79
|
+
@dg.remove_edge 1, 2
|
80
|
+
assert !@dg.has_edge?(1, 2)
|
81
|
+
@dg.remove_vertex 3
|
82
|
+
assert !@dg.has_vertex?(3)
|
83
|
+
assert !@dg.has_edge?(2, 3)
|
84
|
+
assert_equal('(2-4)', @dg.edges.join)
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_add_vertices
|
88
|
+
dg = DirectedAdjacencyGraph.new
|
89
|
+
dg.add_vertices 1, 3, 2, 4
|
90
|
+
assert_equal dg.vertices.sort, [1, 2, 3, 4]
|
91
|
+
|
92
|
+
dg.remove_vertices 1, 3
|
93
|
+
assert_equal dg.vertices.sort, [2, 4]
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_creating_from_array
|
97
|
+
dg = DirectedAdjacencyGraph[1, 2, 3, 4]
|
98
|
+
assert_equal([1, 2, 3, 4], dg.vertices.sort)
|
99
|
+
assert_equal('(1-2)(3-4)', dg.edges.join)
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_reverse
|
103
|
+
# Add isolated vertex
|
104
|
+
@dg.add_vertex(42)
|
105
|
+
reverted = @dg.reverse
|
106
|
+
|
107
|
+
@dg.each_edge do |u, v|
|
108
|
+
assert(reverted.has_edge?(v, u))
|
109
|
+
end
|
110
|
+
|
111
|
+
assert(reverted.has_vertex?(42), 'Reverted graph should contain isolated Vertex 42')
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_to_undirected
|
115
|
+
undirected = @dg.to_undirected
|
116
|
+
assert_equal '(1=2)(2=3)(2=4)', undirected.edges.sort.join
|
117
|
+
end
|
118
|
+
end
|
data/test/dot_test.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'rgl/dot'
|
4
|
+
require 'rgl/adjacency'
|
5
|
+
|
6
|
+
class TestDot < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def assert_match(dot, pattern)
|
9
|
+
assert(!(dot =~ pattern).nil?, "#{dot} doesn't match #{pattern}")
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_to_dot_digraph
|
13
|
+
graph = RGL::DirectedAdjacencyGraph[1, 2]
|
14
|
+
dot = graph.to_dot_graph.to_s
|
15
|
+
|
16
|
+
assert_match(dot, /\{[^}]*\}/) # {...}
|
17
|
+
assert_match(dot, /1\s*\[/) # node 1
|
18
|
+
assert_match(dot, /2\s*\[/) # node 2
|
19
|
+
assert_match(dot, /1\s*->\s*2/) # edge
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_to_dot_graph
|
23
|
+
graph = RGL::AdjacencyGraph[1, 2]
|
24
|
+
dot = graph.write_to_graphic_file
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'rgl/edge_properties_map'
|
4
|
+
|
5
|
+
include RGL
|
6
|
+
|
7
|
+
class TestEdgePropertiesMap < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@edge_properties = {
|
11
|
+
[1, 2] => 1,
|
12
|
+
[2, 3] => 3,
|
13
|
+
[1, 3] => 7
|
14
|
+
}
|
15
|
+
|
16
|
+
@edge_properties_lambda = lambda { |edge| @edge_properties[edge] }
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_directed_graph
|
20
|
+
properties_map = EdgePropertiesMap.new(@edge_properties, true)
|
21
|
+
|
22
|
+
assert_equal(1, properties_map.edge_property(1, 2))
|
23
|
+
assert_equal(3, properties_map.edge_property(2, 3))
|
24
|
+
assert_equal(7, properties_map.edge_property(1, 3))
|
25
|
+
|
26
|
+
assert_raise ArgumentError do
|
27
|
+
properties_map.edge_property(2, 1)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_undirected_graph
|
32
|
+
properties_map = EdgePropertiesMap.new(@edge_properties, false)
|
33
|
+
|
34
|
+
assert_equal(1, properties_map.edge_property(1, 2))
|
35
|
+
assert_equal(3, properties_map.edge_property(2, 3))
|
36
|
+
assert_equal(7, properties_map.edge_property(1, 3))
|
37
|
+
|
38
|
+
assert_equal(1, properties_map.edge_property(2, 1))
|
39
|
+
assert_equal(3, properties_map.edge_property(3, 2))
|
40
|
+
assert_equal(7, properties_map.edge_property(3, 1))
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_nil_properties
|
44
|
+
assert_raise ArgumentError do
|
45
|
+
EdgePropertiesMap.new(@edge_properties.merge([1, 4] => nil), false)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_non_negative_properties_map
|
50
|
+
assert_raise ArgumentError do
|
51
|
+
NonNegativeEdgePropertiesMap.new(@edge_properties.merge([1, 4] => -2), false)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_with_lambda
|
56
|
+
properties_map = EdgePropertiesMap.new(@edge_properties_lambda, true)
|
57
|
+
|
58
|
+
assert_equal(1, properties_map.edge_property(1, 2))
|
59
|
+
assert_equal(3, properties_map.edge_property(2, 3))
|
60
|
+
assert_equal(7, properties_map.edge_property(1, 3))
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
data/test/edge_test.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'rgl/base'
|
4
|
+
|
5
|
+
include RGL::Edge
|
6
|
+
|
7
|
+
class TestEdge < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def test_directed_edge
|
10
|
+
assert_raises(ArgumentError) { DirectedEdge.new }
|
11
|
+
e = DirectedEdge.new 1, 2
|
12
|
+
assert_equal(1, e.source)
|
13
|
+
assert_equal(2, e.target)
|
14
|
+
assert_equal([1, 2], e.to_a)
|
15
|
+
assert_equal("(1-2)", e.to_s)
|
16
|
+
assert_equal("(2-1)", e.reverse.to_s)
|
17
|
+
assert_equal([1, 2], [e[0], e[1]])
|
18
|
+
assert(DirectedEdge[1, 2].eql?(DirectedEdge.new(1, 2)))
|
19
|
+
assert(!DirectedEdge[1, 2].eql?(DirectedEdge.new(1, 3)))
|
20
|
+
assert(!DirectedEdge[2, 1].eql?(DirectedEdge.new(1, 2)))
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_undirected_edge
|
24
|
+
assert_raises(ArgumentError) { UnDirectedEdge.new }
|
25
|
+
e = UnDirectedEdge.new 1, 2
|
26
|
+
assert_equal(1, e.source)
|
27
|
+
assert_equal(2, e.target)
|
28
|
+
assert_equal([1, 2], e.to_a)
|
29
|
+
assert_equal("(1=2)", e.to_s)
|
30
|
+
assert(UnDirectedEdge.new(1, 2).eql?(UnDirectedEdge.new(2, 1)))
|
31
|
+
assert(!UnDirectedEdge.new(1, 3).eql?(UnDirectedEdge.new(2, 1)))
|
32
|
+
assert_equal(UnDirectedEdge.new(1, 2).hash, UnDirectedEdge.new(1, 2).hash)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'rgl/edmonds_karp'
|
4
|
+
require 'rgl/adjacency'
|
5
|
+
|
6
|
+
include RGL
|
7
|
+
|
8
|
+
class TestEdmondsKarp < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@capacities_map = {
|
12
|
+
[1, 2] => 3,
|
13
|
+
[1, 4] => 3,
|
14
|
+
[2, 3] => 4,
|
15
|
+
[3, 1] => 3,
|
16
|
+
[3, 4] => 1,
|
17
|
+
[3, 5] => 2,
|
18
|
+
[4, 5] => 2,
|
19
|
+
[4, 6] => 6,
|
20
|
+
[5, 2] => 1,
|
21
|
+
[5, 7] => 1,
|
22
|
+
[6, 7] => 9
|
23
|
+
}
|
24
|
+
|
25
|
+
@graph = DirectedAdjacencyGraph[*@capacities_map.keys.flatten]
|
26
|
+
|
27
|
+
add_reverse_edges(@graph, @capacities_map)
|
28
|
+
|
29
|
+
@expected_flow = {
|
30
|
+
[1, 2] => 2, [2, 1] => -2,
|
31
|
+
[1, 4] => 3, [4, 1] => -3,
|
32
|
+
[2, 3] => 2, [3, 2] => -2,
|
33
|
+
[3, 4] => 1, [4, 3] => -1,
|
34
|
+
[3, 5] => 1, [5, 3] => -1,
|
35
|
+
[4, 5] => 0, [5, 4] => 0,
|
36
|
+
[4, 6] => 4, [6, 4] => -4,
|
37
|
+
[5, 7] => 1, [7, 5] => -1,
|
38
|
+
[6, 7] => 4, [7, 6] => -4,
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_max_flow
|
43
|
+
assert_equal(@expected_flow, maximum_flow(1, 7))
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_max_flow_with_lambda_capacities_map
|
47
|
+
capacities_lambda = lambda { |edge| @capacities_map[edge] }
|
48
|
+
assert_equal(@expected_flow, maximum_flow(1, 7), capacities_lambda)
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_reverse_edges_validation
|
52
|
+
@graph.remove_edge(2, 1)
|
53
|
+
assert_raises(ArgumentError, 'reverse edge for (2, 1) is missing') { maximum_flow(1, 7) }
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_missing_capacities_validation
|
57
|
+
@capacities_map.delete([3, 5])
|
58
|
+
assert_raises(ArgumentError, 'capacity for edge (3, 5) is missing') { maximum_flow(1, 7) }
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_negative_capacities_validation
|
62
|
+
@capacities_map[[5, 2]] = -2
|
63
|
+
assert_raises(ArgumentError, 'capacity of edge (5, 2) is negative') { maximum_flow(1, 7) }
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_zero_reverse_capacities_validation
|
67
|
+
@capacities_map[[7, 5]] = 1
|
68
|
+
assert_raises(ArgumentError, 'either (7, 5) or (5, 7) should have 0 capacity') { maximum_flow(1, 7) }
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_zero_capacities
|
72
|
+
@capacities_map[[1, 5]] = 0
|
73
|
+
@capacities_map[[5, 1]] = 0
|
74
|
+
assert_equal(@expected_flow, maximum_flow(1, 7))
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_equal_source_and_sink
|
78
|
+
assert_raises(ArgumentError, "source and sink can't be equal") { maximum_flow(1, 1) }
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_directed_graph_validation
|
82
|
+
graph = AdjacencyGraph.new
|
83
|
+
graph.add_vertex(1)
|
84
|
+
|
85
|
+
assert_raises(NotDirectedError, 'Edmonds-Karp algorithm can only be applied to a directed graph') { graph.maximum_flow({}, 1, 2) }
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_unreachable_sink
|
89
|
+
assert_equal({}, maximum_flow(1, 8))
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def maximum_flow(source, sink, capacities_map = @capacities_map)
|
95
|
+
@graph.maximum_flow(capacities_map, source, sink)
|
96
|
+
end
|
97
|
+
|
98
|
+
def add_reverse_edges(graph, capacities_map)
|
99
|
+
capacities_map.keys.each do |(u, v)|
|
100
|
+
graph.add_edge(v, u)
|
101
|
+
capacities_map[[v, u]] = 0
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'rgl/adjacency'
|
3
1
|
require 'test_helper'
|
4
2
|
|
3
|
+
require 'rgl/adjacency'
|
4
|
+
|
5
5
|
include RGL
|
6
6
|
|
7
7
|
class TestGraph < Test::Unit::TestCase
|
@@ -11,9 +11,9 @@ class TestGraph < Test::Unit::TestCase
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def setup
|
14
|
-
@dg1
|
15
|
-
@edges = [[1,2],[2,3],[2,4],[4,5],[1,6],[6,4]]
|
16
|
-
@edges.each do |(src,target)|
|
14
|
+
@dg1 = DirectedAdjacencyGraph.new
|
15
|
+
@edges = [[1, 2], [2, 3], [2, 4], [4, 5], [1, 6], [6, 4]]
|
16
|
+
@edges.each do |(src, target)|
|
17
17
|
@dg1.add_edge(src, target)
|
18
18
|
end
|
19
19
|
@loan_vertices = [7, 8, 9]
|
@@ -58,7 +58,7 @@ class TestGraph < Test::Unit::TestCase
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def test_set_edgelist_class
|
61
|
-
edges
|
61
|
+
edges = @dg1.edges
|
62
62
|
@dg1.edgelist_class=Array
|
63
63
|
assert_equal edges, @dg1.edges
|
64
64
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'rgl/graphxml'
|
4
|
+
require 'rgl/adjacency'
|
5
|
+
require 'rgl/topsort'
|
6
|
+
require 'rgl/connected_components'
|
7
|
+
|
8
|
+
include RGL
|
9
|
+
|
10
|
+
class TestGraphXML < Test::Unit::TestCase
|
11
|
+
NORTH_DIR = './examples/north/'
|
12
|
+
|
13
|
+
def setup
|
14
|
+
@stream = File.new(NORTH_DIR + "g.10.0.graphml")
|
15
|
+
end
|
16
|
+
|
17
|
+
def tear_down
|
18
|
+
@stream.close
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_graphxml
|
22
|
+
@dg = DirectedAdjacencyGraph.new.from_graphxml(@stream).edges.sort.join
|
23
|
+
assert_equal("(n0-n1)(n0-n2)(n0-n9)(n3-n4)(n4-n5)(n5-n7)(n8-n0)(n8-n3)(n8-n4)(n8-n5)(n8-n6)", @dg)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_north_graphs
|
27
|
+
name, nnodes, nedges = '', 0, 0
|
28
|
+
IO.foreach(NORTH_DIR + '/Graph.log') {
|
29
|
+
|line|
|
30
|
+
if /name:\s*(.*)\sformat: graphml\s+nodes: (\d+)\s+edges: (\d+)/ =~ line
|
31
|
+
name, nnodes, nedges = $1, $2.to_i, $3.to_i
|
32
|
+
end
|
33
|
+
if name && /directed: (\w+).*acyclic: (\w+).*connected: (\w+).*biconnected: (\w+)\s+/ =~ line
|
34
|
+
directed, acyclic, connected, biconnected = $1, $2, $3, $4
|
35
|
+
File.open(NORTH_DIR + name + '.graphml') {
|
36
|
+
|file|
|
37
|
+
print '.'; $stdout.flush
|
38
|
+
graph = (directed == 'true' ? DirectedAdjacencyGraph : AdjacencyGraph).new.from_graphxml(file)
|
39
|
+
#graph.write_to_graphic_file
|
40
|
+
assert_equal(nnodes, graph.num_vertices)
|
41
|
+
assert_equal(nedges, graph.num_edges)
|
42
|
+
assert_equal(acyclic, graph.acyclic?.to_s)
|
43
|
+
|
44
|
+
num_comp = 0
|
45
|
+
graph.to_undirected.each_connected_component { |x| num_comp += 1 }
|
46
|
+
assert_equal(connected, (num_comp == 1).to_s)
|
47
|
+
|
48
|
+
# if graph.directed?
|
49
|
+
# num_comp = graph.strongly_connected_components.num_comp
|
50
|
+
# #puts num_comp
|
51
|
+
# assert_equal(biconnected, (num_comp == 1).to_s)
|
52
|
+
# end
|
53
|
+
}
|
54
|
+
end
|
55
|
+
}
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'rgl/implicit'
|
4
|
+
require 'rgl/adjacency'
|
5
|
+
|
6
|
+
include RGL
|
7
|
+
|
8
|
+
class TestImplicit < Test::Unit::TestCase
|
9
|
+
def setup
|
10
|
+
@dg = DirectedAdjacencyGraph.new
|
11
|
+
[[1, 2], [2, 3], [2, 4], [4, 5], [1, 6], [6, 4]].each do |(src, target)|
|
12
|
+
@dg.add_edge(src, target)
|
13
|
+
end
|
14
|
+
|
15
|
+
@cycle = ImplicitGraph.new { |g|
|
16
|
+
g.vertex_iterator { |b| 0.upto(4, &b) }
|
17
|
+
g.adjacent_iterator { |x, b| b.call((x+1)%5) }
|
18
|
+
g.directed = true
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_empty
|
23
|
+
empty = ImplicitGraph.new
|
24
|
+
assert(empty.empty?)
|
25
|
+
assert_equal([], empty.edges)
|
26
|
+
assert_equal([], empty.vertices)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_cycle
|
30
|
+
assert(!@cycle.empty?)
|
31
|
+
assert_equal([0, 1, 2, 3, 4], @cycle.vertices.sort)
|
32
|
+
assert_equal("(0-1)(1-2)(2-3)(3-4)(4-0)", @cycle.edges.sort.join)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_vertex_filtered_graph
|
36
|
+
fg = @cycle.vertices_filtered_by { |v| v%2 == 0 }
|
37
|
+
assert_equal([0, 2, 4], fg.vertices.sort)
|
38
|
+
assert_equal("(4-0)", fg.edges.sort.join)
|
39
|
+
assert(fg.directed?)
|
40
|
+
|
41
|
+
fg = @dg.vertices_filtered_by { |v| v%2 == 0 }
|
42
|
+
assert_equal([2, 4, 6], fg.vertices.sort)
|
43
|
+
assert_equal("(2-4)(6-4)", fg.edges.sort.join)
|
44
|
+
assert(fg.directed?)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_edge_filtered_graph
|
48
|
+
fg = @cycle.edges_filtered_by { |u, v| u+v > 3 }
|
49
|
+
assert_equal(@cycle.vertices.sort, fg.vertices.sort)
|
50
|
+
assert_equal("(2-3)(3-4)(4-0)", fg.edges.sort.join)
|
51
|
+
assert(fg.directed?)
|
52
|
+
end
|
53
|
+
end
|