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.
Files changed (72) hide show
  1. data/ChangeLog +19 -10
  2. data/Gemfile +3 -0
  3. data/{README → README.rdoc} +70 -98
  4. data/Rakefile +44 -150
  5. data/examples/canvas.rb +63 -64
  6. data/examples/examples.rb +42 -42
  7. data/examples/graph.dot +46 -0
  8. data/examples/images/example.jpg +0 -0
  9. data/examples/images/module_graph.jpg +0 -0
  10. data/examples/images/rgl_modules.png +0 -0
  11. data/examples/{insel-der-tausend-gefahren.rb → insel_der_tausend_gefahren.rb} +18 -19
  12. data/examples/north.rb +2 -2
  13. data/examples/north2.rb +11 -11
  14. data/examples/rdep-rgl.rb +218 -222
  15. data/lib/rgl/adjacency.rb +78 -74
  16. data/lib/rgl/base.rb +160 -78
  17. data/lib/rgl/bellman_ford.rb +115 -0
  18. data/lib/rgl/bidirectional.rb +17 -10
  19. data/lib/rgl/bipartite.rb +87 -0
  20. data/lib/rgl/condensation.rb +13 -4
  21. data/lib/rgl/connected_components.rb +38 -30
  22. data/lib/rgl/dijkstra.rb +158 -0
  23. data/lib/rgl/dijkstra_visitor.rb +42 -0
  24. data/lib/rgl/dot.rb +40 -32
  25. data/lib/rgl/edge_properties_map.rb +55 -0
  26. data/lib/rgl/edmonds_karp.rb +136 -0
  27. data/lib/rgl/enumerable_ext.rb +4 -1
  28. data/lib/rgl/graph_iterator.rb +15 -0
  29. data/lib/rgl/graph_visitor.rb +138 -0
  30. data/lib/rgl/graph_wrapper.rb +15 -0
  31. data/lib/rgl/graphxml.rb +20 -10
  32. data/lib/rgl/implicit.rb +68 -66
  33. data/lib/rgl/mutable.rb +37 -31
  34. data/lib/rgl/path_builder.rb +40 -0
  35. data/lib/rgl/prim.rb +52 -0
  36. data/lib/rgl/rdot.rb +411 -374
  37. data/lib/rgl/topsort.rb +23 -16
  38. data/lib/rgl/transitivity.rb +29 -27
  39. data/lib/rgl/traversal.rb +67 -205
  40. data/rakelib/dep_graph.rake +4 -3
  41. data/test/bellman_ford_test.rb +187 -0
  42. data/test/bipartite_test.rb +47 -0
  43. data/test/components_test.rb +80 -0
  44. data/test/cycles_test.rb +60 -0
  45. data/test/dijkstra_test.rb +148 -0
  46. data/test/directed_graph_test.rb +118 -0
  47. data/test/dot_test.rb +26 -0
  48. data/test/edge_properties_map_test.rb +63 -0
  49. data/test/edge_test.rb +35 -0
  50. data/test/edmonds_karp_test.rb +105 -0
  51. data/{tests/TestGraph.rb → test/graph_test.rb} +6 -6
  52. data/test/graph_xml_test.rb +57 -0
  53. data/test/implicit_test.rb +53 -0
  54. data/test/prim_test.rb +98 -0
  55. data/{tests/TestRdot.rb → test/rdot_test.rb} +309 -308
  56. data/{tests → test}/test_helper.rb +4 -1
  57. data/{tests/TestTransitivity.rb → test/transitivity_test.rb} +43 -43
  58. data/test/traversal_test.rb +221 -0
  59. data/test/undirected_graph_test.rb +103 -0
  60. metadata +226 -145
  61. data/examples/example.jpg +0 -0
  62. data/examples/module_graph.jpg +0 -0
  63. data/install.rb +0 -49
  64. data/tests/TestComponents.rb +0 -65
  65. data/tests/TestCycles.rb +0 -61
  66. data/tests/TestDirectedGraph.rb +0 -125
  67. data/tests/TestDot.rb +0 -18
  68. data/tests/TestEdge.rb +0 -34
  69. data/tests/TestGraphXML.rb +0 -57
  70. data/tests/TestImplicit.rb +0 -52
  71. data/tests/TestTraversal.rb +0 -220
  72. data/tests/TestUnDirectedGraph.rb +0 -102
@@ -1,7 +1,7 @@
1
1
  # From c.l.r SNIP IT: bond TkCanvas with RubyGraphLibrary
2
2
  # author: Phlip (see also
3
- # http://www.rubygarden.org/ruby?RubyAlgorithmPackage/TkCanvasSample)
4
- #
3
+ # http://www.rubygarden.org/ruby?RubyAlgorithmPackage/TkCanvasSample)
4
+ #
5
5
  # put a GraphViz graph into a TkCanvas, and make nodes
6
6
  # selectable. Illustrates a bug in GraphViz
7
7
 
@@ -19,83 +19,82 @@ puts 'Displaying ' + filename
19
19
  # ruby canvas.rb north/g.14.9.graphml &
20
20
 
21
21
  File.open(filename) { |file|
22
- graph = DirectedAdjacencyGraph.from_graphxml(file)
22
+ graph = DirectedAdjacencyGraph.from_graphxml(file)
23
23
  graph.write_to_graphic_file('gif', filename)
24
24
  graph.write_to_graphic_file('plain', filename)
25
- root = TkRoot.new{title "Ex1"}
26
-
27
- canvas = TkCanvas.new(root) {
28
- width 400
29
- height 600
25
+ root = TkRoot.new { title "Ex1" }
26
+
27
+ canvas = TkCanvas.new(root) {
28
+ width 400
29
+ height 600
30
30
  }
31
31
  canvas.pack()
32
32
  ovals = []
33
33
 
34
34
  TkcImage.new(canvas, 0, 0) {
35
- anchor 'nw'
36
-
37
- image TkPhotoImage.new() {
38
- file filename + '.gif'
39
- }
35
+ anchor 'nw'
36
+
37
+ image TkPhotoImage.new() {
38
+ file filename + '.gif'
39
+ }
40
40
  }
41
41
 
42
42
  # read the 'plain' file, and for each node put an invisible
43
43
  # oval over its image
44
-
45
- File.open(filename + '.plain') { |f|
46
- graphLine = f.readline()
47
- graphStats = graphLine.split()
48
- graphHeight = graphStats[3].to_f()
49
- nodeLine = f.readline()
50
- fields = nodeLine.split()
51
-
52
- while fields[0] == 'node'
53
- namer = fields[1]
54
-
55
- # the following crud is because GraphViz has no system to
56
- # emit a "plain" format in pixels that exactly match the
57
- # locations of objects in dot's raster output
58
-
59
- # furtherless, the current GraphViz seems to be centering
60
- # the raster output but not the 'plain' output. Hence on
61
- # g.10.8.graphml the X fudge factor must be 45. >sigh<
62
-
63
- # YMMV, based on your system's opinion of the size of an inch
64
-
65
- exx = fields[2].to_f * 96 - 20 # 45
66
- why = (graphHeight - fields[3].to_f()) * 96 - 20
67
- widt = fields[4].to_f() * 90
68
- hite = fields[5].to_f() * 90
69
-
70
- ov = TkcOval.new(canvas, exx, why,
71
- exx + widt, why + hite) {
72
- state 'hidden'
73
- width 4
74
- outline 'green'
75
- tags namer
76
- }
77
- ovals.push(ov)
78
- nodeLine = f.readline()
79
- fields = nodeLine.split()
80
- end
44
+
45
+ File.open(filename + '.plain') { |f|
46
+ graphLine = f.readline()
47
+ graphStats = graphLine.split()
48
+ graphHeight = graphStats[3].to_f()
49
+ nodeLine = f.readline()
50
+ fields = nodeLine.split()
51
+
52
+ while fields[0] == 'node'
53
+ namer = fields[1]
54
+
55
+ # the following crud is because GraphViz has no system to
56
+ # emit a "plain" format in pixels that exactly match the
57
+ # locations of objects in dot's raster output
58
+
59
+ # furtherless, the current GraphViz seems to be centering
60
+ # the raster output but not the 'plain' output. Hence on
61
+ # g.10.8.graphml the X fudge factor must be 45. >sigh<
62
+
63
+ # YMMV, based on your system's opinion of the size of an inch
64
+
65
+ exx = fields[2].to_f * 96 - 20 # 45
66
+ why = (graphHeight - fields[3].to_f) * 96 - 20
67
+ widt = fields[4].to_f() * 90
68
+ hite = fields[5].to_f() * 90
69
+
70
+ ov = TkcOval.new(canvas, exx, why, exx + widt, why + hite) {
71
+ state 'hidden'
72
+ width 4
73
+ outline 'green'
74
+ tags namer
75
+ }
76
+ ovals.push(ov)
77
+ nodeLine = f.readline()
78
+ fields = nodeLine.split()
79
+ end
81
80
  }
82
81
  lastOval = ovals[0]
83
82
 
84
83
  # at click time, search for an oval in range and display it
85
-
86
- canvas.bind('Button-1') do |event|
87
- x,y = canvas.canvasx(event.x), canvas.canvasy(event.y)
88
-
89
- ovals.each { |r|
90
- x1,y1,x2,y2 = r.coords()
91
-
92
- if x >= x1 and x <= x2 and y >= y1 and y <= y2 then
93
- lastOval.configure('state' => 'hidden')
94
- lastOval = r
95
- lastOval.configure('state' => 'normal')
96
- break
97
- end
98
- }
84
+
85
+ canvas.bind('Button-1') do |event|
86
+ x, y = canvas.canvasx(event.x), canvas.canvasy(event.y)
87
+
88
+ ovals.each { |r|
89
+ x1, y1, x2, y2 = r.coords()
90
+
91
+ if x >= x1 and x <= x2 and y >= y1 and y <= y2
92
+ lastOval.configure('state' => 'hidden')
93
+ lastOval = r
94
+ lastOval.configure('state' => 'normal')
95
+ break
96
+ end
97
+ }
99
98
  end
100
99
 
101
100
  Tk.mainloop
@@ -4,12 +4,12 @@ require 'rgl/adjacency'
4
4
  require 'rgl/implicit'
5
5
 
6
6
  # partite 8, 5
7
- def partite(n,m)
7
+ def partite(n, m)
8
8
  result = RGL::DirectedAdjacencyGraph.new
9
9
  1.upto(n) { |i|
10
- 1.upto(m) { |j|
11
- result.add_edge('a'+i.to_s,'b'+j.to_s)
12
- }
10
+ 1.upto(m) { |j|
11
+ result.add_edge('a' + i.to_s, 'b' + j.to_s)
12
+ }
13
13
  }
14
14
  result
15
15
  end
@@ -18,8 +18,8 @@ end
18
18
  def modulo (n, m)
19
19
  result = RGL::AdjacencyGraph.new
20
20
  1.upto(n) { |x|
21
- 1.upto(n) {|y|
22
- result.add_edge x,y if x != y && x%m == y%m }
21
+ 1.upto(n) { |y|
22
+ result.add_edge x, y if x != y && x % m == y % m }
23
23
  }
24
24
  result
25
25
  end
@@ -27,9 +27,9 @@ end
27
27
  # Cyclic graph with _n_ vertices
28
28
  def cycle (n)
29
29
  RGL::ImplicitGraph.new { |g|
30
- g.vertex_iterator { |b| 0.upto(n-1,&b) }
31
- g.adjacent_iterator { |x, b| b.call((x+1)%n) }
32
- g.directed = true
30
+ g.vertex_iterator { |b| 0.upto(n - 1, &b) }
31
+ g.adjacent_iterator { |x, b| b.call((x + 1) % n) }
32
+ g.directed = true
33
33
  }
34
34
  end
35
35
 
@@ -37,40 +37,40 @@ end
37
37
  def complete (n)
38
38
  set = n.integer? ? (1..n) : n
39
39
  RGL::ImplicitGraph.new { |g|
40
- g.vertex_iterator { |b| set.each(&b) }
41
- g.adjacent_iterator { |x, b|
42
- set.each { |y| b.call(y) unless x == y }
43
- }
40
+ g.vertex_iterator { |b| set.each(&b) }
41
+ g.adjacent_iterator { |x, b|
42
+ set.each { |y| b.call(y) unless x == y }
43
+ }
44
44
  }
45
45
  end
46
46
 
47
47
  # Directed graph of ruby modules. Edges are defined by the method _ancestors_
48
48
  def module_graph
49
49
  RGL::ImplicitGraph.new { |g|
50
- g.vertex_iterator { |b|
51
- ObjectSpace.each_object(Module, &b)
52
- }
53
- g.adjacent_iterator { |x, b|
54
- x.ancestors.each { |y|
55
- b.call(y) unless x == y || y == Kernel || y == Object
56
- }
57
- }
58
- g.directed = true
50
+ g.vertex_iterator { |b|
51
+ ObjectSpace.each_object(Module, &b)
52
+ }
53
+ g.adjacent_iterator { |x, b|
54
+ x.ancestors.each { |y|
55
+ b.call(y) unless x == y || y == Kernel || y == Object
56
+ }
57
+ }
58
+ g.directed = true
59
59
  }
60
60
  end
61
61
 
62
62
  # Shows graph of divisors of all integers from 2 to _n_.
63
63
  def divisors(n)
64
64
  RGL::ImplicitGraph.new { |g|
65
- g.vertex_iterator { |b| 2.upto(n,&b) }
66
- g.adjacent_iterator { |x, b|
67
- n.downto(x+1) { |y| b.call(y) if y % x == 0 }
68
- }
69
- g.directed = true
65
+ g.vertex_iterator { |b| 2.upto(n, &b) }
66
+ g.adjacent_iterator { |x, b|
67
+ n.downto(x + 1) { |y| b.call(y) if y % x == 0 }
68
+ }
69
+ g.directed = true
70
70
  }
71
71
  end
72
72
 
73
- def bfs_example(g=cycle(5), start=g.detect {|x| true})
73
+ def bfs_example(g = cycle(5), start = g.detect { |x| true })
74
74
  require 'rgl/traversal'
75
75
 
76
76
  g.bfs_search_tree_from(start)
@@ -81,15 +81,15 @@ def graph_from_dotfile (file)
81
81
  g = RGL::AdjacencyGraph.new
82
82
  pattern = /\s*([^\"]+)[\"\s]*--[\"\s]*([^\"\[\;]+)/ # ugly but works
83
83
  IO.foreach(file) { |line|
84
- case line
85
- when /^digraph/
86
- g = RGL::DirectedAdjacencyGraph.new
87
- pattern = /\s*([^\"]+)[\"\s]*->[\"\s]*([^\"\[\;]+)/
88
- when pattern
89
- g.add_edge $1,$2
90
- else
91
- nil
92
- end
84
+ case line
85
+ when /^digraph/
86
+ g = RGL::DirectedAdjacencyGraph.new
87
+ pattern = /\s*([^\"]+)[\"\s]*->[\"\s]*([^\"\[\;]+)/
88
+ when pattern
89
+ g.add_edge $1, $2
90
+ else
91
+ nil
92
+ end
93
93
  }
94
94
  g
95
95
  end
@@ -99,15 +99,15 @@ end
99
99
  if $0 == __FILE__
100
100
  require 'rgl/dot'
101
101
 
102
- dg = RGL::DirectedAdjacencyGraph[1,2 ,2,3 ,2,4, 4,5, 6,4, 1,6]
102
+ dg = RGL::DirectedAdjacencyGraph[1,2, 2,3, 2,4, 4,5, 6,4, 1,6]
103
103
  dg.dotty
104
104
  dg.write_to_graphic_file
105
- bfs_example(dg,1).dotty
106
- bfs_example(graph_from_dotfile('dot/unix.dot'), 'Interdata').dotty({'label'=>'Interdata Nachfolger', 'fontsize' => 12})
105
+ bfs_example(dg, 1).dotty
106
+ bfs_example(graph_from_dotfile('dot/unix.dot'), 'Interdata').dotty({ 'label' => 'Interdata Nachfolger', 'fontsize' => 12 })
107
107
 
108
108
  g = module_graph
109
- tree = bfs_example(module_graph,RGL::AdjacencyGraph)
110
- g = g.vertices_filtered_by {|v| tree.has_vertex? v}
109
+ tree = bfs_example(module_graph, RGL::AdjacencyGraph)
110
+ g = g.vertices_filtered_by { |v| tree.has_vertex? v }
111
111
  g.write_to_graphic_file
112
112
  g.dotty
113
113
  end
@@ -0,0 +1,46 @@
1
+ subgraph RGL__AdjacencyGraph {
2
+ 0 [
3
+ fontsize = 8,
4
+ label = 0
5
+ ]
6
+
7
+ 1 [
8
+ fontsize = 8,
9
+ label = 1
10
+ ]
11
+
12
+ 2 [
13
+ fontsize = 8,
14
+ label = 2
15
+ ]
16
+
17
+ 3 [
18
+ fontsize = 8,
19
+ label = 3
20
+ ]
21
+
22
+ 4 [
23
+ fontsize = 8,
24
+ label = 4
25
+ ]
26
+
27
+ 0 -- 1 [
28
+ fontsize = 8
29
+ ]
30
+
31
+ 0 -- 4 [
32
+ fontsize = 8
33
+ ]
34
+
35
+ 1 -- 2 [
36
+ fontsize = 8
37
+ ]
38
+
39
+ 2 -- 3 [
40
+ fontsize = 8
41
+ ]
42
+
43
+ 3 -- 4 [
44
+ fontsize = 8
45
+ ]
46
+ }
@@ -1,7 +1,6 @@
1
1
  # Die Insel der 1000 Gefahren
2
2
  # http://www.amazon.de/1000-Gefahren-Die-Insel/dp/3473520225/ref=pd_sim_b?ie=UTF8&qid=1203279845&sr=8-3
3
3
 
4
- require 'rubygems' rescue nil
5
4
  require 'rgl/adjacency'
6
5
  require 'rgl/implicit'
7
6
  require 'rgl/dot'
@@ -18,16 +17,16 @@ g = RGL::DirectedAdjacencyGraph[
18
17
 
19
18
  11, 15,
20
19
  11, 16,
21
-
20
+
22
21
  12, 17,
23
- 12, 18,
22
+ 12, 18,
24
23
 
25
- 13, 19,
24
+ 13, 19,
26
25
  13, 20,
27
26
 
28
27
  14, 21,
29
28
  14, 22,
30
-
29
+
31
30
  15, 23,
32
31
  15, 24,
33
32
 
@@ -38,12 +37,12 @@ g = RGL::DirectedAdjacencyGraph[
38
37
  17, 28,
39
38
 
40
39
  18, 29,
41
- 18, 30,
40
+ 18, 30,
42
41
 
43
42
  18, 31,
44
43
  18, 32,
45
44
 
46
- 19, 31,
45
+ 19, 31,
47
46
  19, 32,
48
47
 
49
48
  20, 33,
@@ -58,7 +57,7 @@ g = RGL::DirectedAdjacencyGraph[
58
57
  23, 39,
59
58
  23, 40,
60
59
 
61
- 24, 41,
60
+ 24, 41,
62
61
  24, 42,
63
62
 
64
63
  25, 43,
@@ -71,29 +70,29 @@ g = RGL::DirectedAdjacencyGraph[
71
70
  27, 48,
72
71
 
73
72
  28, 49,
74
- 28, 50,
73
+ 28, 50,
75
74
 
76
75
  29, 51,
77
- 29, 52,
76
+ 29, 52,
78
77
 
79
78
  30, 53,
80
79
  30, 54,
81
-
80
+
82
81
  31, 55,
83
- 31, 56,
84
-
82
+ 31, 56,
83
+
85
84
  32, 57,
86
85
  32, 58,
87
86
 
88
87
  33, 59,
89
88
  33, 60,
90
-
89
+
91
90
  34, 61,
92
91
  34, 62,
93
92
 
94
93
  35, 63,
95
94
  35, 64,
96
- #
95
+
97
96
  36, 65,
98
97
  36, 66,
99
98
 
@@ -135,9 +134,9 @@ g = RGL::DirectedAdjacencyGraph[
135
134
  53, 91,
136
135
 
137
136
  55, 93,
138
- 55, 94,
137
+ 55, 94,
138
+
139
139
 
140
-
141
140
  57, 92,
142
141
 
143
142
 
@@ -155,7 +154,7 @@ g = RGL::DirectedAdjacencyGraph[
155
154
  61, 103,
156
155
 
157
156
  62, 104,
158
- 62, 105,
157
+ 62, 105,
159
158
 
160
159
  64, 88,
161
160
 
@@ -168,7 +167,7 @@ g = RGL::DirectedAdjacencyGraph[
168
167
  67, 109,
169
168
 
170
169
  75, 9,
171
-
170
+
172
171
  78, 26,
173
172
 
174
173
  86, 30,