rgl 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,141 @@
1
+ # Some graph examples
2
+
3
+ require 'rubygems' rescue nil
4
+ require 'rgl/adjacency'
5
+ require 'rgl/implicit'
6
+ require 'rgl/dot'
7
+
8
+ g = RGL::DirectedAdjacencyGraph[
9
+ 8, 9,
10
+ 8, 10,
11
+
12
+ 9, 11,
13
+ 9, 12,
14
+
15
+ 10, 13,
16
+ 10, 14,
17
+
18
+ 11, 15,
19
+ 11, 16,
20
+
21
+ 12, 17,
22
+ 12, 18,
23
+
24
+ 13, 19,
25
+ 13, 20,
26
+
27
+ 14, 21,
28
+ 14, 22,
29
+
30
+ 15, 23,
31
+ 15, 24,
32
+
33
+ 16, 25,
34
+ 16, 26,
35
+
36
+ 17, 27,
37
+ 17, 28,
38
+
39
+ 18, 29,
40
+ 18, 30,
41
+
42
+ 18, 31,
43
+ 18, 32,
44
+
45
+ 19, 31,
46
+ 19, 32,
47
+
48
+ 20, 33,
49
+ 20, 34,
50
+
51
+ 21, 35,
52
+ 21, 36,
53
+
54
+ 22, 37,
55
+ 22, 38,
56
+
57
+ 23, 39,
58
+ 23, 40,
59
+
60
+ 24, 41,
61
+ 24, 42,
62
+
63
+ 25, 43,
64
+ 25, 44,
65
+
66
+ 26, 45,
67
+ 26, 46,
68
+
69
+ 27, 47,
70
+ 27, 48,
71
+
72
+ 28, 49,
73
+ 28, 50,
74
+
75
+ 29, 51,
76
+ 29, 52,
77
+
78
+ 30, 53,
79
+ 30, 54,
80
+
81
+ 31, 55,
82
+ 31, 56,
83
+
84
+ 32, 57,
85
+ 32, 58,
86
+
87
+ 33, 59,
88
+ 33, 60,
89
+
90
+ 34, 61,
91
+ 34, 62,
92
+
93
+ 35, 63,
94
+ 35, 64,
95
+ #
96
+ 36, 65,
97
+ 36, 66,
98
+
99
+ 37, 67,
100
+
101
+ 38, 13,
102
+
103
+ 39, 68,
104
+ 39, 69,
105
+
106
+ 40, 70,
107
+ 40, 71,
108
+
109
+ 42, 72,
110
+ 42, 73,
111
+
112
+ 43, 74,
113
+ 43, 75,
114
+
115
+ 44, 76,
116
+ 44, 77,
117
+
118
+ 46, 78,
119
+ 46, 79,
120
+
121
+ 47, 80,
122
+ 47, 81,
123
+
124
+ 48, 82,
125
+ 48, 83,
126
+
127
+ 50, 84,
128
+ 50, 85,
129
+
130
+ 51, 86,
131
+ 51, 87,
132
+
133
+ 53, 90,
134
+ 53, 91,
135
+
136
+ 55, 93,
137
+ 55, 94
138
+
139
+ ]
140
+ g.dotty
141
+
@@ -1,151 +1,184 @@
1
+ # adjacency.rb
1
2
  #
2
- # $Id: adjacency.rb,v 1.4 2002/11/10 21:21:20 monora Exp $
3
+ # $Id: adjacency.rb,v 1.7 2005/03/30 21:25:34 monora Exp $
3
4
  #
4
5
  # The DirectedAdjacencyGraph class implements a generalized adjacency list
5
- # graph structure. An AdjacencyGraph is basically a two-dimensional structure,
6
- # where each element of the first dimension represents a vertex, and each of
7
- # the vertices contains a one-dimensional structure that is the list of all
8
- # adjacent vertices.
6
+ # graph structure. An AdjacencyGraph is basically a two-dimensional structure
7
+ # (ie, a list of lists). Each element of the first dimension represents a
8
+ # vertex. Each of the vertices contains a one-dimensional structure that is
9
+ # the list of all adjacent vertices.
9
10
  #
10
- # The class for representing the adjacency list of a vertex is by default a
11
- # Set, but can be configured by the client when a AdjacencyGraph is created.
11
+ # The class for representing the adjacency list of a vertex is, by default, a
12
+ # Set. This can be configured by the client, however, when an AdjacencyGraph
13
+ # is created.
12
14
 
13
15
  require 'rgl/mutable'
14
16
  require 'set'
15
17
 
16
18
  module RGL
19
+
17
20
  class DirectedAdjacencyGraph
18
- include MutableGraph
19
-
20
- # Shortcut for creating a DirectedAdjacencyGraph:
21
- #
22
- # RGL::DirectedAdjacencyGraph[1,2, 2,3, 2,4, 4,5].edges.to_a.to_s =>
23
- # "(1-2)(2-3)(2-4)(4-5)"
24
- def self.[](*a)
25
- result = new
26
- 0.step(a.size-1,2) { |i| result.add_edge(a[i],a[i+1])}
27
- result
28
- end
29
-
30
- # Returns a new empty DirectedAdjacencyGraph which has as edgelist class the
31
- # given class. The default edgelist class is Set to ensure set semantics for
32
- # edges and vertices.
33
- def initialize(edgelist_class=Set)
34
- @edgelist_class = edgelist_class
35
- @vertice_dict = Hash.new
36
- end
37
-
38
- # Iterator for the keys of the vertice list hash.
39
- def each_vertex(&b)
40
- @vertice_dict.each_key(&b)
41
- end
42
-
43
- def each_adjacent(v, &b) # :nodoc:
44
- adjacency_list = @vertice_dict[v] or raise NoVertexError, "No vertex #{v}."
45
- adjacency_list.each(&b)
46
- end
47
-
48
- # Returns true.
49
- def directed?; true; end
50
-
51
- # Complexity is O(1), since the vertices are kept in a Hash containing as
52
- # value the list of adjacent vertices of _v_.
53
- def has_vertex?(v); @vertice_dict.has_key?(v); end
54
-
55
- # Complexity is O(1), if a Set is used as adjacency list, otherwise
56
- # O(out_degree(v))
57
- #
58
- # ---
59
- # MutableGraph interface.
60
- def has_edge? (u, v)
61
- has_vertex?(u) and @vertice_dict[u].include? v
62
- end
63
-
64
- # See MutableGraph#add_vertex.
65
- #
66
- # If the vertex is already in (using eql?) the method does nothing.
67
- def add_vertex(v)
68
- @vertice_dict[v] ||= @edgelist_class.new
69
- end
70
-
71
- # See MutableGraph#add_edge.
72
- def add_edge (u,v)
73
- add_vertex(u) # ensure key
74
- add_vertex(v) # ensure key
75
- basic_add_edge(u,v)
76
- end
77
-
78
- # See MutableGraph#remove_vertex.
79
- def remove_vertex(v)
80
- @vertice_dict.delete(v)
81
-
82
- # remove v from all adjacency lists
83
- @vertice_dict.each_value { |adjList| adjList.delete(v) }
84
- end
85
-
86
- # See MutableGraph::remove_edge.
87
- def remove_edge (u,v)
88
- @vertice_dict[u].delete(v) unless @vertice_dict[u].nil?
89
- end
90
-
91
- protected
92
-
93
- def basic_add_edge(u,v)
94
- @vertice_dict[u].add v
95
- end
96
- end # class AdjacencyGraph
97
-
98
- # AdjacencyGraph is an undirected Graph. The methods add_edge and remove_edge
99
- # are reimplemented: If an edge (u,v) is added or removed then the reverse
100
- # edge (v,u) is also added or removed.
101
- class AdjacencyGraph < DirectedAdjacencyGraph
102
- # Always returns false.
103
- def directed?; false; end
104
-
105
- # Also removes (v,u)
106
- def remove_edge (u,v)
107
- super
108
- @vertice_dict[v].delete(u) unless @vertice_dict[v].nil?
109
- end
110
-
111
- protected
112
- def basic_add_edge(u,v)
113
- super
114
- # Insert backwards edge
115
- @vertice_dict[v].add u
116
- end
117
- end
21
+
22
+ include MutableGraph
23
+
24
+ # Shortcut for creating a DirectedAdjacencyGraph:
25
+ #
26
+ # RGL::DirectedAdjacencyGraph[1,2, 2,3, 2,4, 4,5].edges.to_a.to_s =>
27
+ # "(1-2)(2-3)(2-4)(4-5)"
28
+
29
+ def self.[] (*a)
30
+ result = new
31
+ 0.step(a.size-1, 2) { |i| result.add_edge(a[i], a[i+1]) }
32
+ result
33
+ end
34
+
35
+ # Returns a new empty DirectedAdjacencyGraph which has as its edgelist
36
+ # class the given class. The default edgelist class is Set, to ensure
37
+ # set semantics for edges and vertices.
38
+
39
+ def initialize (edgelist_class = Set)
40
+ @edgelist_class = edgelist_class
41
+ @vertice_dict = Hash.new
42
+ end
43
+
44
+ # Iterator for the keys of the vertice list hash.
45
+
46
+ def each_vertex (&b)
47
+ @vertice_dict.each_key(&b)
48
+ end
49
+
50
+ def each_adjacent (v, &b) # :nodoc:
51
+ adjacency_list = @vertice_dict[v] or
52
+ raise NoVertexError, "No vertex #{v}."
53
+ adjacency_list.each(&b)
54
+ end
55
+
56
+ # Returns true.
57
+
58
+ def directed?
59
+ true
60
+ end
61
+
62
+ # Complexity is O(1), because the vertices are kept in a Hash containing
63
+ # as values the lists of adjacent vertices of _v_.
64
+
65
+ def has_vertex? (v)
66
+ @vertice_dict.has_key?(v)
67
+ end
68
+
69
+ # Complexity is O(1), if a Set is used as adjacency list. Otherwise,
70
+ # complexity is O(out_degree(v)).
71
+ #
72
+ # ---
73
+ # MutableGraph interface.
74
+
75
+ def has_edge? (u, v)
76
+ has_vertex?(u) and @vertice_dict[u].include?(v)
77
+ end
78
+
79
+ # See MutableGraph#add_vertex.
80
+ #
81
+ # If the vertex is already in the graph (using eql?), the method does
82
+ # nothing.
83
+
84
+ def add_vertex (v)
85
+ @vertice_dict[v] ||= @edgelist_class.new
86
+ end
87
+
88
+ # See MutableGraph#add_edge.
89
+
90
+ def add_edge (u, v)
91
+ add_vertex(u) # ensure key
92
+ add_vertex(v) # ensure key
93
+ basic_add_edge(u, v)
94
+ end
95
+
96
+ # See MutableGraph#remove_vertex.
97
+
98
+ def remove_vertex (v)
99
+ @vertice_dict.delete(v)
100
+
101
+ # remove v from all adjacency lists
102
+
103
+ @vertice_dict.each_value { |adjList| adjList.delete(v) }
104
+ end
105
+
106
+ # See MutableGraph::remove_edge.
107
+
108
+ def remove_edge (u, v)
109
+ @vertice_dict[u].delete(v) unless @vertice_dict[u].nil?
110
+ end
111
+
112
+ protected
113
+
114
+ def basic_add_edge (u, v)
115
+ @vertice_dict[u].add(v)
116
+ end
117
+
118
+ end # class DirectedAdjacencyGraph
119
+
120
+ # AdjacencyGraph is an undirected Graph. The methods add_edge and
121
+ # remove_edge are reimplemented: If an edge (u,v) is added or removed,
122
+ # then the reverse edge (v,u) is also added or removed.
123
+
124
+ class AdjacencyGraph < DirectedAdjacencyGraph
125
+
126
+ def directed? # Always returns false.
127
+ false
128
+ end
129
+
130
+ # Also removes (v,u)
131
+
132
+ def remove_edge (u, v)
133
+ super
134
+ @vertice_dict[v].delete(u) unless @vertice_dict[v].nil?
135
+ end
136
+
137
+ protected
138
+
139
+ def basic_add_edge (u,v)
140
+ super
141
+ @vertice_dict[v].add(u) # Insert backwards edge
142
+ end
143
+
144
+ end # class AdjacencyGraph
118
145
 
119
146
  module Graph
120
- # Convert a general graph to an AdjacencyGraph. If the graph is directed
121
- # returns a DirectedAdjacencyGraph else a AdjacencyGraph.
122
- def to_adjacency
123
- result = (directed? ? DirectedAdjacencyGraph : AdjacencyGraph).new
124
- each_edge { |u,v| result.add_edge u,v }
125
- result
126
- end
127
-
128
- # Return a new DirectedAdjacencyGraph which has the same set of vertices. If
129
- # (u,v) is an edge of the graph then (v,u) is an edge of the result.
130
- #
131
- # If the graph is undirected the result is self.
132
- def reverse
133
- reurn self unless directed?
134
- result = DirectedAdjacencyGraph.new
135
- each_edge { |u,v| result.add_edge v,u }
136
- result
137
- end
138
-
139
- # Return a new AdjacencyGraph which has the same set of vertices. If (u,v)
140
- # is an edge of the graph (u,v) and (v,u) (which are the same edges) is an
141
- # edge of the result.
142
- #
143
- # If the graph is undirected the result is self.
144
- def to_undirected
145
- return self unless directed?
146
- result = AdjacencyGraph.new
147
- each_edge { |u,v| result.add_edge u,v }
148
- result
149
- end
150
- end
151
- end
147
+
148
+ # Convert a general graph to an AdjacencyGraph. If the graph is directed,
149
+ # returns a DirectedAdjacencyGraph; otherwise, returns an AdjacencyGraph.
150
+
151
+ def to_adjacency
152
+ result = (directed? ? DirectedAdjacencyGraph : AdjacencyGraph).new
153
+ each_edge { |u,v| result.add_edge(u, v) }
154
+ result
155
+ end
156
+
157
+ # Return a new DirectedAdjacencyGraph which has the same set of vertices.
158
+ # If (u,v) is an edge of the graph, then (v,u) is an edge of the result.
159
+ #
160
+ # If the graph is undirected, the result is self.
161
+
162
+ def reverse
163
+ return self unless directed?
164
+ result = DirectedAdjacencyGraph.new
165
+ each_vertex { |v| result.add_vertex v }
166
+ each_edge { |u,v| result.add_edge(v, u) }
167
+ result
168
+ end
169
+
170
+ # Return a new AdjacencyGraph which has the same set of vertices. If (u,v)
171
+ # is an edge of the graph, then (u,v) and (v,u) (which are the same edges)
172
+ # are edges of the result.
173
+ #
174
+ # If the graph is undirected, the result is self.
175
+
176
+ def to_undirected
177
+ return self unless directed?
178
+ result = AdjacencyGraph.new
179
+ each_edge { |u,v| result.add_edge(u, v) }
180
+ result
181
+ end
182
+
183
+ end # module Graph
184
+ end # module RGL