rgl 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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,