rgl 0.2.3 → 0.3.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/README CHANGED
@@ -83,7 +83,7 @@ The concepts of IncidenceGraph, AdjacencyGraph and VertexListGraph (see
83
83
  http://www.boost.org/libs/graph/doc/IncidenceGraph.html) are here bundled in the
84
84
  base graph module. Most methods of IncidenceGraph should be standard in the base
85
85
  module Graph. The complexity guarantees can not necessarily provided. See
86
- http://www.boost.org/libs/graph/doc/graph_concepts.html
86
+ http://www.boost.org/libs/graph/doc/graph_concepts.html.
87
87
 
88
88
  == Installation
89
89
 
@@ -102,7 +102,7 @@ or directly with
102
102
 
103
103
  % gem install rgl
104
104
 
105
- Use the correct version number for VERSION (e.g. 0.2.2). You may need root
105
+ Use the correct version number for VERSION (e.g. 0.2.x). You may need root
106
106
  privileges to install.
107
107
 
108
108
  === Running tests
@@ -112,23 +112,27 @@ installation directory and start rake:
112
112
 
113
113
  % gem env
114
114
  Rubygems Environment:
115
- - VERSION: 0.8.3 (0.8.3)
115
+ - VERSION: 0.9.0 (0.9.0)
116
116
  - INSTALLATION DIRECTORY: /usr/lib/ruby/gems/1.8
117
117
  - GEM PATH:
118
118
  - /usr/lib/ruby/gems/1.8
119
119
  - REMOTE SOURCES:
120
120
  - http://gems.rubyforge.org
121
121
 
122
- % cd /usr/lib/ruby/gems/1.8/gems/rgl-0.2.2/
123
- % r40> rake
124
- (in /usr/lib/ruby/gems/1.8/gems/rgl-0.2.2)
125
- ruby1.8 -Ilib:tests -e0 -rtests/TestGraphXML -rtests/TestComponents -rtests/TestDirectedGraph -rtests/TestEdge -rtests/TestImplicit -rtests/TestTransitiveClosure -rtests/TestTraversal -rtests/TestUnDirectedGraph
126
- Loaded suite -e
122
+ % cd /usr/lib/ruby/gems/1.8/gems/rgl-0.3.0/
123
+ % rake
124
+ (in /usr/lib/ruby/gems/1.8/gems/rgl-0.3.0)
125
+ /usr/bin/ruby1.8 -Ilib:tests "/usr/lib/ruby/gems/1.8/gems/rake-0.7.3/lib/rake/rake_test_loader.rb" "tests/TestTransitiveClosure.rb" "tests/TestComponents.rb" "tests/TestCycles.rb" "tests/TestDirectedGraph.rb" "tests/TestEdge.rb" "tests/TestGraph.rb" "tests/TestGraphXML.rb" "tests/TestImplicit.rb" "tests/TestUnDirectedGraph.rb" "tests/TestTraversal.rb" "tests/TestDot.rb" "tests/TestRdot.rb"
126
+ Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.7.3/lib/rake/rake_test_loader
127
127
  Started
128
- ........................................................................................................
129
- Finished in 0.736444 seconds.
128
+ ......................................................................................................................................................
129
+ Finished in 0.750958 seconds.
130
130
 
131
- 40 tests, 421 assertions, 0 failures, 0 errors
131
+ 86 tests, 625 assertions, 0 failures, 0 errors
132
+
133
+ === Code coverage
134
+
135
+ Running rcov[http://eigenclass.org/hiki.rb?rcov] on the test suite generates this[link:coverage/index.html] result.
132
136
 
133
137
  === Normal Installation
134
138
 
@@ -137,7 +141,9 @@ following command:
137
141
 
138
142
  % ruby install.rb
139
143
 
140
- from its distribution directory.
144
+ from its distribution directory. To uninstall it use
145
+
146
+ % ruby install.rb -u
141
147
 
142
148
  == Example irb session with RGL
143
149
 
@@ -185,7 +191,7 @@ Add inverse edge (4-2) to directed graph:
185
191
 
186
192
  <em>Topological sort</em> is realized with as iterator:
187
193
 
188
- require 'graph/topsort'
194
+ require 'rgl/topsort'
189
195
  irb> dg.topsort_iterator.to_a
190
196
  [1, 2, 3, 6, 4, 5]
191
197
 
@@ -227,12 +233,16 @@ produces module_graph.jpg: link:../examples/module_graph.jpg
227
233
  Look for more in the examples directory (i.e.
228
234
  examples.rb[link:files/examples/examples_rb.html]).
229
235
 
236
+ == My del.icio.us links concerning RGL
237
+
238
+ I collect some links to stuff around RGL at http://del.icio.us/monora/rgl. I
239
+ registered RGL at SWiK[http://swik.net/rgl].
240
+
230
241
  == Credits
231
242
 
232
243
  Many thanks to Robert Feldt which also worked on a graph library
233
244
  (http://rockit.sf.net/subprojects/graphr) who pointed me to BGL and many other
234
- graph resources. Manuel Simoni found a subtle bug in a preliminary version
235
- announced at http://rubygarden.com/ruby?RubyAlgorithmPackage/Graph.
245
+ graph resources.
236
246
 
237
247
  Robert kindly allowed to integrate his work on graphr, which I did not yet
238
248
  succeed. Especially his work to output graphs for
@@ -249,15 +259,17 @@ and matz for Ruby. Dave included in the latest version of RDoc (alpha9) the
249
259
  module dot/dot.rb which I use instead of Roberts module to visualize graphs
250
260
  (see rgl/dot.rb).
251
261
 
262
+ Jeremy Bopp, John Carter, Sascha Doerdelmann and Shawn Garbett for contributing
263
+ additions, test cases and bugfixes.
264
+
252
265
  == Copying
253
266
 
254
- RGL is Copyright (c) 2002,2004,2005 by Horst Duchene. It is free software, and may be
255
- redistributed under the terms specified in the README file of the Ruby
256
- distribution.
267
+ RGL is Copyright (c) 2002,2004,2005,2008 by Horst Duchene. It is free software, and may be
268
+ redistributed under the terms specified in the README file of the Ruby distribution.
257
269
 
258
270
  == Support
259
271
 
260
- Please contact me at mailto:monora@users.sourceforge.net with bug reports
272
+ Please contact me at mailto:monora@gmail.com with bug reports
261
273
  suggestions, and other comments. If you send patches, it would help if
262
274
  they were in-line (not attachments) and generated using "diff -u".
263
275
 
data/Rakefile CHANGED
@@ -11,15 +11,16 @@ require 'rake/testtask'
11
11
  require 'rake/rdoctask'
12
12
 
13
13
  # Determine the current version of the software
14
-
15
- if `ruby -Ilib -rrgl/base -e'puts RGL_VERSION'` =~ /\S+$/
16
- PKG_VERSION = $&
14
+ rgl_version =
15
+ if %x(ruby -Ilib -rrgl/base -e'puts RGL_VERSION') =~ /\S+$/
16
+ $&
17
17
  else
18
- PKG_VERSION = "0.0.0"
18
+ "0.0.0"
19
19
  end
20
20
 
21
21
  SUMMARY = "Ruby Graph Library"
22
22
  SOURCES = FileList['lib/**/*.rb']
23
+ CLOBBER.include('TAGS', 'coverage')
23
24
  RDOC_DIR = './rgl'
24
25
 
25
26
  # The default task is run if rake is given no explicit arguments.
@@ -41,9 +42,18 @@ task :test
41
42
  desc "Run all test targets"
42
43
  task :testall => [:test ]
43
44
 
45
+ desc "Do code coverage with rcov"
46
+ task :rcov do
47
+ begin
48
+ sh 'rcov -Ilib:tests --exclude "tests/.*[tT]est.*.rb,usr.local" tests/Test*rb'
49
+ rescue Exception
50
+ nil
51
+ end
52
+ end
53
+
44
54
  # Install rgl using the standard install.rb script.
45
55
 
46
- desc "Install the application"
56
+ desc "Install the library"
47
57
  task :install do
48
58
  ruby "install.rb"
49
59
  end
@@ -52,23 +62,26 @@ end
52
62
 
53
63
  desc "Tag all the CVS files with the latest release number (TAG=x)"
54
64
  task :tag do
55
- rel = "REL_" + PKG_VERSION.gsub(/\./, '_')
65
+ rel = "REL_" + rgl_version.gsub(/\./, '_')
56
66
  rel << ENV['TAG'] if ENV['TAG']
57
67
  puts rel
58
68
  sh %{cvs commit -m 'pre-tag commit'}
59
69
  sh %{cvs tag #{rel}}
60
70
  end
61
71
 
72
+ desc "Accumulate changelog"
73
+ task :changelog do
74
+ sh %{cvs2cl --tags --utc --prune --accum}
75
+ end
76
+
62
77
  # Create a task to build the RDOC documentation tree.
63
78
 
64
79
  rd = Rake::RDocTask.new("rdoc") { |rdoc|
65
80
  rdoc.rdoc_dir = RDOC_DIR
66
- # rdoc.template = 'kilmer'
67
- # rdoc.template = 'css2'
81
+ rdoc.template = 'doc/jamis.rb'
68
82
  rdoc.title = SUMMARY
69
- rdoc.options << '--line-numbers' << '--inline-source' <<
70
- '--main' << 'README'
71
- rdoc.rdoc_files.include(SOURCES, 'README', 'examples/examples.rb')
83
+ rdoc.options << '--line-numbers' << '--inline-source' << '--main' << 'README'
84
+ rdoc.rdoc_files.include(SOURCES, 'README', 'ChangeLog', 'examples/examples.rb', 'rakelib/*.rake')
72
85
  }
73
86
 
74
87
  # ====================================================================
@@ -79,30 +92,27 @@ PKG_FILES = FileList[
79
92
  'install.rb',
80
93
  '[A-Z]*',
81
94
  'tests/**/*.rb',
82
- 'examples/**/*'
95
+ 'examples/**/*',
96
+ 'rakelib/*.rake'
83
97
  ] + SOURCES
84
98
 
85
99
  if ! defined?(Gem)
86
- puts "Package Target requires RubyGEMs"
100
+ puts "Package Target requires RubyGems"
87
101
  else
88
102
  spec = Gem::Specification.new do |s|
89
103
 
90
- #### Basic information.
91
-
92
104
  s.name = 'rgl'
93
- s.version = PKG_VERSION
105
+ s.version = rgl_version
94
106
  s.summary = SUMMARY
95
-
107
+
96
108
  s.description = <<-EOF
97
109
  RGL is a framework for graph data structures and algorithms.
98
110
 
99
111
  The design of the library is much influenced by the Boost Graph Library (BGL)
100
112
  which is written in C++ heavily using its template mechanism.
101
113
 
102
-
103
114
  RGL currently contains a core set of algorithm patterns:
104
115
 
105
-
106
116
  * Breadth First Search
107
117
  * Depth First Search
108
118
 
@@ -114,37 +124,39 @@ else
114
124
  * Connected Components
115
125
  * Strongly Connected Components
116
126
  * Transitive Closure
127
+ * Search cycles (contributed by Shawn Garbett)
117
128
  EOF
118
-
129
+
119
130
  #### Dependencies and requirements.
120
-
131
+
121
132
  s.add_dependency('stream', '>= 0.5')
133
+ s.add_dependency 'rake'
122
134
  s.requirements << "Stream library, v0.5 or later"
123
-
135
+
124
136
  #### Which files are to be included in this gem? Everything! (Except CVS directories.)
125
137
  s.files = PKG_FILES.to_a
126
-
138
+
127
139
  #### Load-time details: library and application (you will need one or both).
128
-
140
+
129
141
  s.require_path = 'lib' # Use these for libraries.
130
142
  s.autorequire = 'rgl/base'
131
-
143
+
132
144
  #### Documentation and testing.
133
-
145
+
134
146
  s.has_rdoc = true
135
147
  s.extra_rdoc_files = ['README']
136
148
  s.rdoc_options <<
137
149
  '--title' << 'RGL - Ruby Graph Library' <<
138
150
  '--main' << 'README' <<
139
151
  '--line-numbers'
140
-
152
+
141
153
  #### Author and project details.
142
154
  s.author = "Horst Duchene"
143
- s.email = "hd.at.clr@hduchene.de"
155
+ s.email = "monora@gmail.com"
144
156
  s.homepage = "http://rgl.rubyforge.org"
145
157
  s.rubyforge_project = "rgl"
146
158
  end
147
-
159
+
148
160
  Rake::GemPackageTask.new(spec) do |pkg|
149
161
  #pkg.need_zip = true
150
162
  pkg.need_tar = true
@@ -197,14 +209,9 @@ task :lines do
197
209
  show_line("TOTAL", total_lines, total_code)
198
210
  end
199
211
 
200
- ARCHIVEDIR = '/mnt/flash'
201
-
202
- task :archive => [:package] do
203
- cp FileList["pkg/*.tgz", "pkg/*.zip", "pkg/*.gem"], ARCHIVEDIR
204
- end
205
-
206
212
  desc "Copy rdoc html to rubyforge"
207
- task :rdoc2rf => [:rdoc] do
213
+ task :rdoc2rf => [:rdoc, :rcov, :changelog] do
214
+ mv 'coverage', RDOC_DIR
208
215
  sh "scp -r #{RDOC_DIR} monora@rubyforge.org:/var/www/gforge-projects/rgl"
209
216
  sh "scp examples/*.jpg monora@rubyforge.org:/var/www/gforge-projects/rgl/examples"
210
217
  end
@@ -1,4 +1,5 @@
1
- # Some graph examples
1
+ # Die Insel der 1000 Gefahren
2
+ # http://www.amazon.de/1000-Gefahren-Die-Insel/dp/3473520225/ref=pd_sim_b?ie=UTF8&qid=1203279845&sr=8-3
2
3
 
3
4
  require 'rubygems' rescue nil
4
5
  require 'rgl/adjacency'
@@ -134,8 +135,56 @@ g = RGL::DirectedAdjacencyGraph[
134
135
  53, 91,
135
136
 
136
137
  55, 93,
137
- 55, 94
138
+ 55, 94,
138
139
 
139
- ]
140
- g.dotty
140
+
141
+ 57, 92,
142
+
143
+
144
+ 58, 97,
145
+ 58, 98,
146
+
147
+ 59, 99,
148
+ 99, 100,
149
+
150
+ 60, 100,
151
+
152
+
153
+ 61, 101,
154
+ 61, 102,
155
+ 61, 103,
156
+
157
+ 62, 104,
158
+ 62, 105,
159
+
160
+ 64, 88,
161
+
162
+ 65, 106,
163
+ 65, 107,
141
164
 
165
+ 66, 9,
166
+
167
+ 67, 108,
168
+ 67, 109,
169
+
170
+ 75, 9,
171
+
172
+ 78, 26,
173
+
174
+ 86, 30,
175
+
176
+ 88, 106,
177
+ 88, 89,
178
+
179
+ 89, 16,
180
+
181
+ 92, 95,
182
+ 92, 96,
183
+
184
+ 93, 37,
185
+
186
+ 96, 9,
187
+
188
+ 105, 9,
189
+ 105, 10]
190
+ g.dotty
@@ -1,6 +1,6 @@
1
1
  # adjacency.rb
2
2
  #
3
- # $Id: adjacency.rb,v 1.7 2005/03/30 21:25:34 monora Exp $
3
+ # $Id: adjacency.rb,v 1.11 2008/03/02 13:45:43 monora Exp $
4
4
  #
5
5
  # The DirectedAdjacencyGraph class implements a generalized adjacency list
6
6
  # graph structure. An AdjacencyGraph is basically a two-dimensional structure
@@ -35,10 +35,24 @@ module RGL
35
35
  # Returns a new empty DirectedAdjacencyGraph which has as its edgelist
36
36
  # class the given class. The default edgelist class is Set, to ensure
37
37
  # set semantics for edges and vertices.
38
-
39
- def initialize (edgelist_class = Set)
38
+ #
39
+ # If other graphs are passed as parameters their vertices and edges are
40
+ # added to the new graph.
41
+ def initialize (edgelist_class = Set, *other_graphs)
40
42
  @edgelist_class = edgelist_class
41
43
  @vertice_dict = Hash.new
44
+ other_graphs.each do |g|
45
+ g.each_vertex {|v| add_vertex v}
46
+ g.each_edge {|v,w| add_edge v,w}
47
+ end
48
+ end
49
+
50
+ # Copy internal vertice_dict
51
+ def initialize_copy(orig)
52
+ @vertice_dict = orig.instance_eval{@vertice_dict}.dup
53
+ @vertice_dict.keys.each do |v|
54
+ @vertice_dict[v] = @vertice_dict[v].dup
55
+ end
42
56
  end
43
57
 
44
58
  # Iterator for the keys of the vertice list hash.
@@ -48,8 +62,8 @@ module RGL
48
62
  end
49
63
 
50
64
  def each_adjacent (v, &b) # :nodoc:
51
- adjacency_list = @vertice_dict[v] or
52
- raise NoVertexError, "No vertex #{v}."
65
+ adjacency_list = (@vertice_dict[v] or
66
+ raise NoVertexError, "No vertex #{v}.")
53
67
  adjacency_list.each(&b)
54
68
  end
55
69
 
@@ -109,6 +123,15 @@ module RGL
109
123
  @vertice_dict[u].delete(v) unless @vertice_dict[u].nil?
110
124
  end
111
125
 
126
+ # Converts the adjacency list of each vertex to be of type _klass_. The
127
+ # class is expected to have a new contructor which accepts an enumerable as
128
+ # parameter.
129
+ def edgelist_class=(klass)
130
+ @vertice_dict.keys.each do |v|
131
+ @vertice_dict[v] = klass.new @vertice_dict[v].to_a
132
+ end
133
+ end
134
+
112
135
  protected
113
136
 
114
137
  def basic_add_edge (u, v)
@@ -175,9 +198,7 @@ module RGL
175
198
 
176
199
  def to_undirected
177
200
  return self unless directed?
178
- result = AdjacencyGraph.new
179
- each_edge { |u,v| result.add_edge(u, v) }
180
- result
201
+ AdjacencyGraph.new(Set, self)
181
202
  end
182
203
 
183
204
  end # module Graph
@@ -3,52 +3,9 @@
3
3
  # Module RGL defines the namespace for all modules and classes of the graph
4
4
  # library. The main module is RGL::Graph which defines the abstract behavior of
5
5
  # all graphs in the library.
6
+ require 'rgl/enumerable_ext'
6
7
 
7
- RGL_VERSION = "0.2.3"
8
-
9
- unless Enumerable.instance_methods(true).grep(/inject/)
10
- module Enumerable
11
- def inject(*argv)
12
- argc = argv.size
13
-
14
- if argc == 0
15
- first = true
16
- result = nil
17
-
18
- each { |e|
19
- if first
20
- first = false
21
- result = e
22
- else
23
- result = yield(result, e)
24
- end
25
- }
26
- elsif argc == 1
27
- result = argv[0]
28
-
29
- each { |e| result = yield(result, e) }
30
- else
31
- raise ArgumentError, "wrong # of arguments(#{argc} for 1)"
32
- end
33
-
34
- result
35
- end
36
- end
37
- end
38
-
39
- module Enumerable
40
- # Fixnum()
41
- #
42
- # Return the number of elements of the Enumerable. Same as _size_ but not all
43
- # Enumerables implement size.
44
- #--
45
- # Should we call the methods _size_?
46
- def length
47
- inject(0) do |sum,v|
48
- sum + 1
49
- end
50
- end
51
- end
8
+ RGL_VERSION = "0.3.0"
52
9
 
53
10
  module RGL
54
11
  class NotDirectedError < RuntimeError; end
@@ -61,11 +18,11 @@ module RGL
61
18
  # undirected graphs. There is no need for a Vertex class, because every ruby
62
19
  # object can be a vertex of a graph.
63
20
  module Edge
64
- # Simply a directed pair (source -> target). Must library functions try do
21
+ # Simply a directed pair (source -> target). Most library functions try do
65
22
  # omit to instantiate edges. They instead use two vertex parameters for
66
23
  # representing edges (see each_edge). If a client wants to store edges
67
- # explicitly DirecteEdge or UnDirectedEdge instances are return
68
- # (i.e. Graph#edges).
24
+ # explicitly DirecteEdge or UnDirectedEdge instances are returned
25
+ # (i.e. Graph#edges).
69
26
  class DirectedEdge
70
27
  attr_accessor :source, :target
71
28
 
@@ -122,47 +79,47 @@ module RGL
122
79
  # UnDirectedEdge[1,2].to_s == "(1=2)"
123
80
  def to_s; "(#{source}=#{target})"; end
124
81
  end
82
+
125
83
  end # Edge
126
84
 
127
- # In BGL terminology the module Graph defines the concept graph (see
128
- # http://www.boost.org/libs/graph/doc/graph_concepts.html). We though do not
129
- # distinguish between IncidenceGraph, EdgeListGraph and VertexListGraph concept, which would
130
- # complicate the interface two much. These concepts are defined in BGL to
131
- # differentiate between efficient access to edges and vertices.
85
+ # In BGL terminology the module Graph defines the graph concept (see
86
+ # http://www.boost.org/libs/graph/doc/graph_concepts.html). We however do not
87
+ # distinguish between the IncidenceGraph, EdgeListGraph and VertexListGraph
88
+ # concepts, which would complicate the interface too much. These concepts are
89
+ # defined in BGL to differentiate between efficient access to edges and
90
+ # vertices.
132
91
  #
133
- # The RGL Graph concept contains only few requirements that are common to all
134
- # the graph concepts. These include especially the iterators defining the set of
135
- # vertices and edges (see each_vertex and each_adjacent). Most other functions
136
- # are derived from these fundamental iterators, i.e. num_vertices() or
137
- # num_edges().
92
+ # The RGL Graph concept contains only a few requirements that are common to
93
+ # all the graph concepts. These include, especially, the iterators defining
94
+ # the sets of vertices and edges (see each_vertex and each_adjacent). Most
95
+ # other functions are derived from these fundamental iterators, i.e.
96
+ # num_vertices or num_edges.
138
97
  #
139
98
  # Each graph is an enumerable of vertices.
140
99
  module Graph
141
100
  include Enumerable
142
101
  include Edge
143
102
 
144
- # The each_vertex iterator defines the set of vertices. This method must be
145
- # defined be concrete graph classes. It defines the BGL VertexListGraph
103
+ # The each_vertex iterator defines the set of vertices. This method must be
104
+ # defined by concrete graph classes. It defines the BGL VertexListGraph
146
105
  # concept.
147
- def each_vertex
106
+ def each_vertex () # :yields: v
148
107
  raise NotImplementedError
149
- yield v # for RDoc
150
108
  end
151
109
 
152
110
  # The each_adjacent iterator defines the out edges of vertex _v_. This
153
- # method must be defined be concrete graph classes. Its defines the BGL
111
+ # method must be defined by concrete graph classes. Its defines the BGL
154
112
  # IncidenceGraph concept.
155
- def each_adjacent (v)
113
+ def each_adjacent (v) # :yields: v
156
114
  raise NotImplementedError
157
- yield u # for RDoc
158
115
  end
159
116
 
160
117
  # The each_edge iterator should provide efficient access to all edges of the
161
118
  # graph. Its defines the EdgeListGraph concept.
162
119
  #
163
- # This method must _not_ be defined be concrete graph classes, because it
120
+ # This method must _not_ be defined by concrete graph classes, because it
164
121
  # can be implemented using each_vertex and each_adjacent. However for
165
- # undirected graph the function is inefficient because we must may not yield
122
+ # undirected graph the function is inefficient because we must not yield
166
123
  # (v,u) if we already visited edge (u,v).
167
124
  def each_edge (&block)
168
125
  if directed?
@@ -173,26 +130,26 @@ module RGL
173
130
  each_edge_aux(&block) # concrete graphs should to this better
174
131
  end
175
132
  end
176
-
133
+
177
134
  # Vertices get enumerated. A graph is thus an enumerable of vertices.
178
135
  # ---
179
136
  # === Testing
180
137
  def each(&block); each_vertex(&block); end
181
-
138
+
182
139
  # Is the graph directed? The default returns false.
183
140
  def directed?; false; end
184
141
 
185
- # Returns true if _v_ is a vertex of the graph. Same as include? inherited
186
- # from enumerable. Complexity is O(num_vertices) by default. Concrete graph
187
- # may bee better here (see AdjacencyGraph).
142
+ # Returns true if _v_ is a vertex of the graph. Same as #include? inherited
143
+ # from Enumerable. Complexity is O(num_vertices) by default. Concrete graph
144
+ # may be better here (see AdjacencyGraph).
188
145
  def has_vertex?(v); include?(v); end # inherited from enumerable
189
146
 
190
- # Returns true if the graph has no vertex, i.e. num_vertices == 0.
147
+ # Returns true if the graph has no vertices, i.e. num_vertices == 0.
191
148
  # ---
192
149
  # === accessing vertices and edges
193
150
  def empty?; num_vertices.zero?; end
194
151
 
195
- # Return the array of vertices. Synonym for to_a inherited by enumerable.
152
+ # Return the array of vertices. Synonym for #to_a inherited by Enumerable.
196
153
  def vertices; to_a; end
197
154
 
198
155
  # Returns the class for edges: DirectedEdge or UnDirectedEdge.
@@ -214,8 +171,8 @@ module RGL
214
171
  r
215
172
  end
216
173
 
217
- # Returns the number of out-edges (for directed graphs) or the number of incident
218
- # edges (for undirected graphs) of vertex _v_.
174
+ # Returns the number of out-edges (for directed graphs) or the number of
175
+ # incident edges (for undirected graphs) of vertex _v_.
219
176
  def out_degree (v)
220
177
  r = 0
221
178
  each_adjacent(v) { |u| r += 1}
@@ -225,11 +182,8 @@ module RGL
225
182
  # Returns the number of vertices.
226
183
  def size() # Why not in Enumerable?
227
184
  inject(0) { |n, v| n + 1 }
228
- #r = 0; each_vertex {|v| r +=1}; r
229
185
  end
230
-
231
- # Synonym for size.
232
- def num_vertices; size; end
186
+ alias :num_vertices :size
233
187
 
234
188
  # Returns the number of edges.
235
189
  def num_edges; r = 0; each_edge {|u,v| r +=1}; r; end
@@ -239,8 +193,23 @@ module RGL
239
193
  edges.sort.to_s
240
194
  end
241
195
 
196
+ # Equality is defined to be same set of edges and directed?
197
+ def eql?(g)
198
+ equal?(g) or
199
+ begin
200
+ g.is_a?(Graph) and directed? == g.directed? and
201
+ g.inject(0) { |n, v| has_vertex?(v) or return false; n+1} ==
202
+ num_vertices and begin
203
+ ng = 0
204
+ g.each_edge {|u,v| has_edge? u,v or return false; ng += 1}
205
+ ng == num_edges
206
+ end
207
+ end
208
+ end
209
+ alias == eql?
210
+
242
211
  private
243
-
212
+
244
213
  def each_edge_aux
245
214
  # needed in each_edge
246
215
  visited = Hash.new
@@ -256,40 +225,5 @@ module RGL
256
225
  end
257
226
  end # module Graph
258
227
 
259
- # BGL defines the concept BidirectionalGraph as follows:
260
- #
261
- # The BidirectionalGraph concept refines IncidenceGraph and adds the
262
- # requirement for efficient access to the in-edges of each vertex. This
263
- # concept is separated from IncidenceGraph because, for directed graphs,
264
- # efficient access to in-edges typically requires more storage space,
265
- # and many algorithms do not require access to in-edges. For undirected
266
- # graphs, this is not an issue; because the in_edges() and out_edges()
267
- # functions are the same, they both return the edges incident to the vertex.
268
- module BidirectionalGraph
269
- include Graph
270
-
271
- # Iterator providing access to the in-edges (for directed graphs) or incident
272
- # edges (for undirected graphs) of vertex _v_. For both directed and
273
- # undirected graphs, the target of an out-edge is required to be vertex _v_
274
- # and the source is required to be a vertex that is adjacent to _v_.
275
- def each_in_neighbor (v)
276
- raise NotImplementedError
277
- yield u
278
- end
279
-
280
- # Returns the number of in-edges (for directed graphs) or the number of
281
- # incident edges (for undirected graphs) of vertex _v_.
282
- def in_degree (v)
283
- r = 0;
284
- each_in_neighbor(v) { |u| r += 1}
285
- r
286
- end
287
-
288
- # Returns the number of in-edges plus out-edges (for directed graphs) or the
289
- # number of incident edges (for undirected graphs) of vertex _v_.
290
- def degree (v)
291
- in_degree(v) + out_degree(v)
292
- end
293
- end
294
228
  end # module RGL
295
229