rgl 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d301ca82307bce4dd2de05303de4bc633f92dbf4
4
+ data.tar.gz: a133f96bc69d3baa7a790674fd9d6e08a8b93d83
5
+ SHA512:
6
+ metadata.gz: 88d2fcb68bfc33c482cc11d0c82ac8c143ac9d2fcd1f4c287f3392944fc7ca212dd9f93bed4654a243c4ab9d73038d9c3c34dcd84e1521923756e8833e69963d
7
+ data.tar.gz: ffe9faef0d0e4f77cef5c830a3ef0a86b2fe61bb8ad7e8f62c272c9360d550e24aca23c5aaf392f9f6990cdf1e36e9d631dab7d982ff1c8b89823eecc4c39042
data/ChangeLog CHANGED
@@ -1,3 +1,16 @@
1
+ 2016-05 Release 0.5.2
2
+
3
+ Horst Duchene <monora@gmail.com>
4
+ * Issue #21: Use new method vertex_id instead of object_id to identify vertices in dot export. (fa7592)
5
+ * Integrate Code Climate's test coverage reporting (0ab722)
6
+ * Clarify traversal order of DFS search (see #20). (afa788)
7
+ Chase Gilliam <chase.gilliam@gmail.com>
8
+ * drop 1.9.3 add newer jruby and rubinius (fad333)
9
+ Matías Battocchia <matias@riseup.net>
10
+ * Switched to a different heap implementation. (bd7c13)
11
+ gorn <j@kub.cz>
12
+ * Adding failing test for issue #24 (1f6204)
13
+
1
14
  2015-12 Release 0.5.1
2
15
 
3
16
  Horst Duchene <monora@gmail.com>
@@ -21,7 +34,7 @@ Chase <chase.gilliam@gmail.com>
21
34
  * updated algorithms to 6.1 and added test unit to support newer rubies (fbd874)
22
35
  Louis Rose <louismrose@gmail.com>
23
36
  * Fix #15. Use object IDs rather than labels to identify vertexs in DOT graph to ensure that distinct nodes that share a label are shown. (33206f)
24
- * Issue #15. Fix tests. (4fc455)
37
+ * Issue #15. Fix tests. (4fc455)
25
38
 
26
39
 
27
40
  2014-12 Release 0.5.0
@@ -29,13 +42,13 @@ Horst Duchene <monora@gmail.com>
29
42
  * Changed edge sequence to match example picture (daa88e)
30
43
  * Fixed comment (6a6c93)
31
44
  * Fixed spelling (7ca281)
32
- Horst Duchêne <monora@gmail.com>
33
45
  Chase <chase.gilliam@gmail.com>
34
46
  * updated algorithms to 6.1 and added test unit to support newer rubies (fbd874)
35
47
  Louis Rose <louismrose@gmail.com>
36
- * Fix #15. Use object IDs rather than labels to identify vertexs in DOT graph to ensure that distinct nodes that share a label are shown. (33206f)
37
- * Issue #15. Fix tests. (4fc455)
38
-
48
+ * Fix #15. Use object IDs rather than labels to identify vertexs
49
+ in DOT graph to ensure that distinct nodes that share a label are
50
+ shown. (33206f)
51
+ * Issue #15. Fix tests. (4fc455)
39
52
 
40
53
  2014-12 Release 0.5.0
41
54
 
data/Gemfile CHANGED
@@ -2,6 +2,4 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'rake'
6
- gem 'yard'
7
- gem 'asciidoctor'
5
+ gem "codeclimate-test-reporter", group: :test, require: nil
@@ -0,0 +1,252 @@
1
+ # Ruby Graph Library (RGL) [<img src="https://secure.travis-ci.org/monora/rgl.png?branch=master" alt="Build Status" />](https://travis-ci.org/monora/rgl) [<img src="https://codeclimate.com/github/monora/rgl/badges/coverage.svg" />](https://codeclimate.com/github/monora/rgl/coverage)
2
+
3
+ RGL is a framework for graph data structures and algorithms.
4
+
5
+ The design of the library is much influenced by the Boost Graph Library (BGL)
6
+ which is written in C++. Refer to http://www.boost.org/libs/graph/doc for
7
+ further links and documentation on graph data structures and algorithms and
8
+ the design rationales of BGL.
9
+
10
+ A comprehensive summary of graph terminology can be found in the graph section
11
+ of the *Dictionary of Algorithms and Data Structures* at
12
+ http://www.nist.gov/dads/HTML/graph.html or
13
+ [Wikipedia](https://en.wikipedia.org/wiki/Graph_%28discrete_mathematics%29).
14
+
15
+ ## Documentation
16
+
17
+ * RGL's [API Reference](http://www.rubydoc.info/github/monora/rgl) at
18
+ http://rubydoc.info
19
+
20
+
21
+ ## Design principles
22
+
23
+ This document concentrates on the special issues of the implementation in
24
+ Ruby. The main design goals directly taken from the BGL design are:
25
+
26
+ * An interface for how the structure of a graph can be accessed using a
27
+ generic interface that hides the details of the graph data structure
28
+ implementation. This interface is defined by the module {RGL::Graph},
29
+ which should be included in concrete classes.
30
+
31
+ * A standardized generic interface for traversing graphs
32
+ {RGL::GraphIterator}
33
+
34
+
35
+ RGL provides some general purpose graph classes that conform to this
36
+ interface, but they are not meant to be the **only** graph classes. As in BGL
37
+ I believe that the main contribution of the RGL is the formulation of this
38
+ interface.
39
+
40
+ The BGL graph interface and graph components are generic in the sense of the
41
+ C++ Standard Template Library (STL). In Ruby other techniques are available to
42
+ express the generic character of the algorithms and data structures mainly
43
+ using mixins and iterators. The BGL documentation mentions three means to
44
+ achieve genericity:
45
+
46
+ * Algorithm/Data-Structure Interoperability
47
+ * Extension through Function Objects and Visitors
48
+ * Element Type Parameterization
49
+ * Vertex and Edge Property Multi-Parameterization
50
+
51
+
52
+ The first is easily achieved in RGL using mixins, which of course is not as
53
+ efficient than C++ templates (but much more readable :-). The second one is
54
+ even more easily implemented using standard iterators with blocks or using the
55
+ [stream](http://www.rubydoc.info/github/monora/stream) module. The third one
56
+ is no issue since Ruby is dynamically typed: Each object can be a graph
57
+ vertex. There is no need for a vertex (or even edge type). In the current
58
+ version of RGL properties of vertices are simply attached using hashes. At
59
+ first there seems to be not much need for the graph property machinery.
60
+
61
+ ### Algorithms
62
+
63
+ RGL current contains a core set of algorithm patterns:
64
+
65
+ * Breadth First Search {RGL::BFSIterator}
66
+ * Depth First Search {RGL::DFSIterator}
67
+
68
+
69
+ The algorithm patterns by themselves do not compute any meaningful quantities
70
+ over graphs, they are merely building blocks for constructing graph
71
+ algorithms. The graph algorithms in RGL currently include:
72
+
73
+ * Topological Sort {RGL::TopsortIterator}
74
+ * Connected Components {RGL::Graph#each_connected_component}
75
+ * Strongly Connected Components {RGL::Graph#strongly_connected_components}
76
+ * Transitive Closure {RGL::Graph#transitive_closure}
77
+ * Dijkstras Shortest Path Algorithm {RGL::DijkstraAlgorithm}
78
+ * Bellman Ford Algorithm {RGL::BellmanFordAlgorithm}
79
+
80
+
81
+ ### Data Structures
82
+
83
+ RGL currently provides two graph classes that implement a generalized
84
+ adjacency list and an edge list adaptor.
85
+
86
+ * {RGL::AdjacencyGraph}
87
+ * {RGL::ImplicitGraph}
88
+
89
+
90
+ The AdjacencyGraph class is the general purpose _swiss army knife_ of graph
91
+ classes. It is highly parameterized so that it can be optimized for different
92
+ situations: the graph is directed or undirected, allow or disallow parallel
93
+ edges, efficient access to just the out-edges, fast vertex insertion and
94
+ removal at the cost of extra space overhead, etc.
95
+
96
+ ### Differences to BGL
97
+
98
+ The concepts of IncidenceGraph, AdjacencyGraph and VertexListGraph (see
99
+ http://www.boost.org/libs/graph/doc/IncidenceGraph.html) are here bundled in
100
+ the base graph module. Most methods of IncidenceGraph should be standard in
101
+ the base module Graph. The complexity guarantees can not necessarily provided.
102
+ See http://www.boost.org/libs/graph/doc/graph_concepts.html.
103
+
104
+ ## Installation
105
+
106
+ % gem install rgl
107
+
108
+ or download the latest sources from the git repository
109
+ http://github.com/monora/rgl.
110
+
111
+ ## Running tests
112
+
113
+ Checkout RGL git repository and go to the project directory. First, install
114
+ RGL dependencies with bundler:
115
+
116
+ % bundle install
117
+
118
+ After that you can run the tests:
119
+
120
+ % rake test
121
+
122
+ ## Example irb session with RGL
123
+
124
+ irb> require 'rgl/adjacency'
125
+ irb> dg=RGL::DirectedAdjacencyGraph[1,2 ,2,3 ,2,4, 4,5, 6,4, 1,6]
126
+ # Use DOT to visualize this graph:
127
+ irb> require 'rgl/dot'
128
+ irb> dg.write_to_graphic_file('jpg')
129
+ "graph.jpg"
130
+
131
+ The result:
132
+
133
+ ![Example](https://github.com/monora/rgl/raw/master/images/example.jpg)
134
+
135
+ irb> dg.directed?
136
+ true
137
+ irb> dg.vertices
138
+ [5, 6, 1, 2, 3, 4]
139
+ irb> dg.has_vertex? 4
140
+ true
141
+
142
+ Every object could be a vertex (there is no class Vertex), even the class
143
+ object *Object*:
144
+
145
+ irb> dg.has_vertex? Object
146
+ false
147
+ irb> dg.edges.sort.to_s
148
+ "(1-2)(1-6)(2-3)(2-4)(4-5)(6-4)"
149
+ irb> dg.to_undirected.edges.sort.to_s
150
+ "(1=2)(1=6)(2=3)(2=4)(5=4)(6=4)"
151
+
152
+ Add inverse edge (4-2) to directed graph:
153
+
154
+ irb> dg.add_edge 4,2
155
+
156
+ (4-2) == (2-4) in the undirected graph:
157
+
158
+ irb> dg.to_undirected.edges.sort.to_s
159
+ "(1=2)(1=6)(2=3)(2=4)(5=4)(6=4)"
160
+
161
+ (4-2) != (2-4) in directed graphs:
162
+
163
+ irb> dg.edges.sort.to_s
164
+ "(1-2)(1-6)(2-3)(2-4)(4-2)(4-5)(6-4)"
165
+ irb> dg.remove_edge 4,2
166
+ true
167
+
168
+ *Topological sort* is implemented as an iterator:
169
+
170
+ require 'rgl/topsort'
171
+ irb> dg.topsort_iterator.to_a
172
+ [1, 2, 3, 6, 4, 5]
173
+
174
+ A more elaborated example showing *implicit graphs*:
175
+
176
+ require 'rgl/implicit'
177
+ def module_graph
178
+ RGL::ImplicitGraph.new { |g|
179
+ g.vertex_iterator { |b|
180
+ ObjectSpace.each_object(Module, &b)
181
+ }
182
+ g.adjacent_iterator { |x, b|
183
+ x.ancestors.each { |y|
184
+ b.call(y) unless x == y || y == Kernel || y == Object
185
+ }
186
+ }
187
+ g.directed = true
188
+ }
189
+ end
190
+
191
+ This function creates a directed graph, with vertices being all loaded
192
+ modules:
193
+
194
+ g = module_graph
195
+
196
+ We only want to see the ancestors of {RGL::AdjacencyGraph}:
197
+
198
+ require 'rgl/traversal'
199
+ tree = g.bfs_search_tree_from(RGL::AdjacencyGraph)
200
+
201
+ Now we want to visualize this component of g with DOT. We therefore create a
202
+ subgraph of the original graph, using a filtered graph:
203
+
204
+ g = g.vertices_filtered_by {|v| tree.has_vertex? v}
205
+ g.write_to_graphic_file('jpg')
206
+
207
+ creates the following graph image with DOT:
208
+
209
+ ![Module graph](https://github.com/monora/rgl/raw/master/images/module_graph.jpg)
210
+
211
+ This graph shows all loaded RGL modules:
212
+
213
+ ![RGL Modules](https://github.com/monora/rgl/raw/master/images/rgl_modules.png)
214
+
215
+ Look for more in
216
+ [examples](https://github.com/monora/rgl/tree/master/examples) directory.
217
+
218
+ I collect some links to stuff around RGL at http://del.icio.us/monora/rgl.
219
+
220
+ ## Credits
221
+
222
+ Many thanks to Robert Feldt which also worked on a graph library
223
+ (http://rockit.sf.net/subprojects/graphr) who pointed me to BGL and many other
224
+ graph resources.
225
+
226
+ Robert kindly allowed to integrate his work on graphr, which I did not yet
227
+ succeed. Especially his work to output graphs for
228
+ [GraphViz](http://www.research.att.com/sw/tools/graphviz/download.html) is
229
+ much more elaborated than the minimal support in dot.rb.
230
+
231
+ Jeremy Siek one of the authors of the nice book [The Boost Graph
232
+ Library](http://www.boost.org/libs/graph/doc) kindly allowed to use the BGL
233
+ documentation as a *cheap* reference for RGL. He and Robert also gave feedback
234
+ and many ideas for RGL.
235
+
236
+ Dave Thomas for [RDoc](http://rdoc.sourceforge.net) which generated what you
237
+ read and matz for Ruby. Dave included in the latest version of RDoc (alpha9)
238
+ the module dot/dot.rb which I use instead of Roberts module to visualize
239
+ graphs (see rgl/dot.rb).
240
+
241
+ Jeremy Bopp, John Carter, Sascha Doerdelmann, Shawn Garbett, Andreas Schörk
242
+ and Kirill Lashuk for contributing additions, test cases and bugfixes.
243
+
244
+ Kirill Lashuk who started to take over further development in November 2012.
245
+
246
+ See also http://github.com/monora/rgl/contributors.
247
+
248
+ ## Copying
249
+
250
+ RGL is Copyright (c) 2002,2004,2005,2008,2013,2015 by Horst Duchene. It is
251
+ free software, and may be redistributed under the terms specified in the
252
+ README file of the Ruby distribution.
data/Rakefile CHANGED
@@ -6,12 +6,12 @@ require 'bundler/setup'
6
6
  require 'rubygems/package_task'
7
7
 
8
8
  require 'rake/testtask'
9
+ require 'rake/clean'
9
10
  require 'yard'
10
11
 
11
12
  $:.unshift File.join(File.dirname(__FILE__), 'lib')
12
13
  require 'rgl/base' # require base module to get RGL_VERSION
13
14
 
14
- SUMMARY = "Ruby Graph Library"
15
15
  SOURCES = FileList['lib/**/*.rb']
16
16
 
17
17
  # The default task is run if rake is given no explicit arguments.
@@ -26,20 +26,6 @@ Rake::TestTask.new do |t|
26
26
  t.verbose = true
27
27
  end
28
28
 
29
- begin
30
- require 'rcov/rcovtask'
31
-
32
- desc "Calculate code coverage with rcov"
33
- Rcov::RcovTask.new(:rcov) do |t|
34
- t.libs << 'test'
35
- t.pattern = 'test/*_test.rb'
36
- t.verbose = true
37
- t.rcov_opts += ['--exclude', 'test/,gems/']
38
- end
39
- rescue LoadError
40
- nil # rcov is available only on Ruby 1.8
41
- end
42
-
43
29
  # Git tagging
44
30
 
45
31
  desc "Commit all changes as a new version commit. Tag the commit with v<version> tag"
@@ -6,7 +6,7 @@
6
6
 
7
7
  require 'rgl/enumerable_ext'
8
8
 
9
- RGL_VERSION = "0.5.1"
9
+ RGL_VERSION = "0.5.2"
10
10
 
11
11
  module RGL
12
12
  class NotDirectedError < RuntimeError; end
@@ -77,6 +77,9 @@ module RGL
77
77
  "(#{source}-#{target})"
78
78
  end
79
79
 
80
+ # Since Ruby 2.0 #inspect no longer calls #to_s. So we alias it to to_s (fixes #22)
81
+ alias inspect to_s
82
+
80
83
  # Returns the array [source,target].
81
84
  #
82
85
  def to_a
@@ -2,8 +2,7 @@ require 'rgl/dijkstra_visitor'
2
2
  require 'rgl/edge_properties_map'
3
3
  require 'rgl/path_builder'
4
4
 
5
- require 'delegate'
6
- require 'algorithms'
5
+ require 'lazy_priority_queue'
7
6
 
8
7
  module RGL
9
8
 
@@ -2,8 +2,7 @@ require 'rgl/dijkstra_visitor'
2
2
  require 'rgl/edge_properties_map'
3
3
  require 'rgl/path_builder'
4
4
 
5
- require 'delegate'
6
- require 'algorithms'
5
+ require 'lazy_priority_queue'
7
6
 
8
7
  module RGL
9
8
 
@@ -55,7 +54,7 @@ module RGL
55
54
  def init(source)
56
55
  @visitor.set_source(source)
57
56
 
58
- @queue = Queue.new
57
+ @queue = MinPriorityQueue.new
59
58
  @queue.push(source, 0)
60
59
  end
61
60
 
@@ -82,8 +81,6 @@ module RGL
82
81
  new_v_distance = @distance_combinator.call(@visitor.distance_map[u], @edge_weights_map.edge_property(u, v))
83
82
 
84
83
  if new_v_distance < @visitor.distance_map[v]
85
- old_v_distance = @visitor.distance_map[v]
86
-
87
84
  @visitor.distance_map[v] = new_v_distance
88
85
  @visitor.parents_map[v] = u
89
86
 
@@ -91,7 +88,7 @@ module RGL
91
88
  @visitor.color_map[v] = :GRAY
92
89
  @queue.push(v, new_v_distance)
93
90
  elsif @visitor.color_map[v] == :GRAY
94
- @queue.decrease_key(v, old_v_distance, new_v_distance)
91
+ @queue.decrease_key(v, new_v_distance)
95
92
  end
96
93
 
97
94
  @visitor.handle_edge_relaxed(u, v)
@@ -104,29 +101,6 @@ module RGL
104
101
  edge_weights_map.is_a?(EdgePropertiesMap) ? edge_weights_map : NonNegativeEdgePropertiesMap.new(edge_weights_map, @graph.directed?)
105
102
  end
106
103
 
107
- class Queue < SimpleDelegator # :nodoc:
108
-
109
- def initialize
110
- @heap = Containers::Heap.new { |a, b| a.distance < b.distance }
111
- super(@heap)
112
- end
113
-
114
- def push(vertex, distance)
115
- @heap.push(vertex_key(vertex, distance), vertex)
116
- end
117
-
118
- def decrease_key(vertex, old_distance, new_distance)
119
- @heap.change_key(vertex_key(vertex, old_distance), vertex_key(vertex, new_distance))
120
- end
121
-
122
- def vertex_key(vertex, distance)
123
- VertexKey.new(vertex, distance)
124
- end
125
-
126
- VertexKey = Struct.new(:vertex, :distance)
127
-
128
- end
129
-
130
104
  end # class DijkstraAlgorithm
131
105
 
132
106
  module Graph
@@ -17,6 +17,10 @@ module RGL
17
17
  v.to_s
18
18
  end
19
19
 
20
+ def vertex_id(v)
21
+ v
22
+ end
23
+
20
24
  # Return a RGL::DOT::Digraph for directed graphs or a DOT::Graph for an
21
25
  # undirected Graph. _params_ can contain any graph property specified in
22
26
  # rdot.rb.
@@ -29,7 +33,7 @@ module RGL
29
33
 
30
34
  each_vertex do |v|
31
35
  graph << DOT::Node.new(
32
- 'name' => v.object_id,
36
+ 'name' => vertex_id(v),
33
37
  'fontsize' => fontsize,
34
38
  'label' => vertex_label(v)
35
39
  )
@@ -37,8 +41,8 @@ module RGL
37
41
 
38
42
  each_edge do |u, v|
39
43
  graph << edge_class.new(
40
- 'from' => u.object_id,
41
- 'to' => v.object_id,
44
+ 'from' => vertex_id(u),
45
+ 'to' => vertex_id(v),
42
46
  'fontsize' => fontsize
43
47
  )
44
48
  end
@@ -169,6 +169,10 @@ module RGL
169
169
  # it is called on each _finish_vertex_ event. See
170
170
  # strongly_connected_components for an example usage.
171
171
  #
172
+ # Note that this traversal does not garantee, that roots are at the top of
173
+ # each spanning subtree induced by the DFS search on a directed graph (see
174
+ # also the discussion in issue #20[https://github.com/monora/rgl/issues/20]).
175
+ #
172
176
  def depth_first_search(vis = DFSVisitor.new(self), &b)
173
177
  each_vertex do |u|
174
178
  unless vis.finished_vertex?(u)
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+
3
+ require 'rgl/dijkstra'
4
+ require 'rgl/adjacency'
5
+
6
+ include RGL
7
+
8
+ class TestDijkstraIssue24 < Test::Unit::TestCase
9
+
10
+ def setup
11
+ @graph = RGL::AdjacencyGraph[2,53, 2,3, 3,8, 3,28, 3,39, 29,58, 8,35, 12,39, 10,29, 62,15, 15,32, 32,58, 58,44, 44,53]
12
+
13
+ end
14
+
15
+ def test_shortest_path_search
16
+ assert_equal([53, 44, 58, 32, 15, 62], shortest_path(53, 62))
17
+ end
18
+
19
+ def shortest_path(v,w)
20
+ @graph.dijkstra_shortest_path(Hash.new(1), v, w)
21
+ end
22
+
23
+ end
@@ -10,25 +10,29 @@ class TestDot < Test::Unit::TestCase
10
10
  end
11
11
 
12
12
  def test_to_dot_digraph
13
- graph = RGL::DirectedAdjacencyGraph[1, 2]
13
+ graph = RGL::DirectedAdjacencyGraph["a", "b"]
14
14
  dot = graph.to_dot_graph.to_s
15
15
 
16
- first_vertex_id = 1.object_id
17
- second_vertex_id = 2.object_id
16
+ first_vertex_id = "a"
17
+ second_vertex_id = "b"
18
18
 
19
19
  assert_match(dot, /\{[^}]*\}/) # {...}
20
20
  assert_match(dot, /#{first_vertex_id}\s*\[/) # node 1
21
- assert_match(dot, /label\s*=\s*1/) # node 1 label
21
+ assert_match(dot, /label\s*=\s*a/) # node 1 label
22
22
  assert_match(dot, /#{second_vertex_id}\s*\[/) # node 2
23
- assert_match(dot, /label\s*=\s*2/) # node 2 label
23
+ assert_match(dot, /label\s*=\s*b/) # node 2 label
24
24
  assert_match(dot, /#{first_vertex_id}\s*->\s*#{second_vertex_id}/) # edge
25
25
  end
26
26
 
27
27
  def test_to_dot_graph
28
- graph = RGL::AdjacencyGraph[1, 2]
28
+ graph = RGL::AdjacencyGraph["a", "b"]
29
29
  def graph.vertex_label(v)
30
30
  "label-"+v.to_s
31
31
  end
32
+
33
+ def graph.vertex_id(v)
34
+ "id-"+v.to_s
35
+ end
32
36
  dot = graph.write_to_graphic_file
33
37
  end
34
38
  end
@@ -63,6 +63,11 @@ class TestGraph < Test::Unit::TestCase
63
63
  assert_equal edges, @dg1.edges
64
64
  end
65
65
 
66
+ # Test for issue #22
67
+ def test_edges_to_s
68
+ assert_equal @dg1.edges.sort.to_s, "[(1-2), (1-6), (2-3), (2-4), (4-5), (6-4)]"
69
+ end
70
+
66
71
  def test_not_implemented
67
72
  graph = NotImplementedGraph.new
68
73
  assert_raise(NotImplementedError) { graph.each_vertex }
@@ -1,3 +1,6 @@
1
+ require "codeclimate-test-reporter"
2
+ CodeClimate::TestReporter.start
3
+
1
4
  require 'rubygems'
2
5
  require 'test/unit'
3
6
 
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rgl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
5
- prerelease:
4
+ version: 0.5.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Horst Duchene
@@ -10,12 +9,11 @@ authors:
10
9
  autorequire: rgl/base
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2015-07-25 00:00:00.000000000 Z
12
+ date: 2016-05-09 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: stream
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
18
  - - ~>
21
19
  - !ruby/object:Gem::Version
@@ -23,73 +21,64 @@ dependencies:
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
25
  - - ~>
29
26
  - !ruby/object:Gem::Version
30
27
  version: 0.5.0
31
28
  - !ruby/object:Gem::Dependency
32
- name: algorithms
29
+ name: lazy_priority_queue
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
32
  - - ~>
37
33
  - !ruby/object:Gem::Version
38
- version: 0.6.1
34
+ version: 0.1.0
39
35
  type: :runtime
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
39
  - - ~>
45
40
  - !ruby/object:Gem::Version
46
- version: 0.6.1
41
+ version: 0.1.0
47
42
  - !ruby/object:Gem::Dependency
48
43
  name: rake
49
44
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
45
  requirements:
52
- - - ! '>='
46
+ - - '>='
53
47
  - !ruby/object:Gem::Version
54
48
  version: '0'
55
49
  type: :development
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
52
  requirements:
60
- - - ! '>='
53
+ - - '>='
61
54
  - !ruby/object:Gem::Version
62
55
  version: '0'
63
56
  - !ruby/object:Gem::Dependency
64
57
  name: yard
65
58
  requirement: !ruby/object:Gem::Requirement
66
- none: false
67
59
  requirements:
68
- - - ! '>='
60
+ - - '>='
69
61
  - !ruby/object:Gem::Version
70
62
  version: '0'
71
63
  type: :development
72
64
  prerelease: false
73
65
  version_requirements: !ruby/object:Gem::Requirement
74
- none: false
75
66
  requirements:
76
- - - ! '>='
67
+ - - '>='
77
68
  - !ruby/object:Gem::Version
78
69
  version: '0'
79
70
  - !ruby/object:Gem::Dependency
80
71
  name: test-unit
81
72
  requirement: !ruby/object:Gem::Requirement
82
- none: false
83
73
  requirements:
84
- - - ! '>='
74
+ - - '>='
85
75
  - !ruby/object:Gem::Version
86
76
  version: '0'
87
77
  type: :development
88
78
  prerelease: false
89
79
  version_requirements: !ruby/object:Gem::Requirement
90
- none: false
91
80
  requirements:
92
- - - ! '>='
81
+ - - '>='
93
82
  - !ruby/object:Gem::Version
94
83
  version: '0'
95
84
  description: RGL is a framework for graph data structures and algorithms
@@ -97,7 +86,7 @@ email: monora@gmail.com
97
86
  executables: []
98
87
  extensions: []
99
88
  extra_rdoc_files:
100
- - README.rdoc
89
+ - README.md
101
90
  files:
102
91
  - lib/rgl/dijkstra.rb
103
92
  - lib/rgl/edmonds_karp.rb
@@ -126,9 +115,6 @@ files:
126
115
  - lib/rgl/graph_wrapper.rb
127
116
  - lib/rgl/bipartite.rb
128
117
  - ChangeLog
129
- - examples/images/module_graph.jpg
130
- - examples/images/example.jpg
131
- - examples/images/rgl_modules.png
132
118
  - examples/insel_der_tausend_gefahren.rb
133
119
  - examples/rdep-rgl.rb
134
120
  - examples/north2.rb
@@ -203,7 +189,6 @@ files:
203
189
  - examples/north/g.10.2.graphml
204
190
  - examples/examples.rb
205
191
  - Gemfile
206
- - README.rdoc
207
192
  - Rakefile
208
193
  - rakelib/dep_graph.rake
209
194
  - test/dijkstra_test.rb
@@ -222,43 +207,38 @@ files:
222
207
  - test/bellman_ford_test.rb
223
208
  - test/rdot_test.rb
224
209
  - test/cycles_test.rb
210
+ - test/dijkstra_issue24_test.rb
225
211
  - test/test_helper.rb
226
212
  - test/transitivity_test.rb
227
213
  - test/bipartite_test.rb
214
+ - README.md
228
215
  homepage: https://github.com/monora/rgl
229
216
  licenses: []
217
+ metadata: {}
230
218
  post_install_message:
231
219
  rdoc_options:
232
220
  - --title
233
221
  - RGL - Ruby Graph Library
234
222
  - --main
235
- - README.rdoc
223
+ - README.md
236
224
  - --line-numbers
237
225
  require_paths:
238
226
  - lib
239
227
  required_ruby_version: !ruby/object:Gem::Requirement
240
- none: false
241
228
  requirements:
242
- - - ! '>='
229
+ - - '>='
243
230
  - !ruby/object:Gem::Version
244
231
  version: '0'
245
- segments:
246
- - 0
247
- hash: 900116365
248
232
  required_rubygems_version: !ruby/object:Gem::Requirement
249
- none: false
250
233
  requirements:
251
- - - ! '>='
234
+ - - '>='
252
235
  - !ruby/object:Gem::Version
253
236
  version: '0'
254
- segments:
255
- - 0
256
- hash: 900116365
257
237
  requirements: []
258
238
  rubyforge_project:
259
- rubygems_version: 1.8.23
239
+ rubygems_version: 2.0.14
260
240
  signing_key:
261
- specification_version: 3
241
+ specification_version: 4
262
242
  summary: Ruby Graph Library
263
243
  test_files: []
264
244
  has_rdoc: true
@@ -1,248 +0,0 @@
1
- = Ruby Graph Library (RGL) {<img src="https://secure.travis-ci.org/monora/rgl.png?branch=master" alt="Build Status" />}[https://travis-ci.org/monora/rgl]
2
-
3
- RGL is a framework for graph data structures and algorithms.
4
-
5
- The design of the library is much influenced by the Boost Graph Library (BGL)
6
- which is written in C++ heavily using its template mechanism. Refer to
7
- http://www.boost.org/libs/graph/doc for further links and documentation on graph
8
- data structures and algorithms and the design rationales of BGL.
9
-
10
- A comprehensive summary of graph terminology can be found in the the graph
11
- section of the <em>Dictionary of Algorithms and Data Structures</em> at
12
- http://www.nist.gov/dads/HTML/graph.html.
13
-
14
- == Design principles
15
-
16
- This document concentrates on the special issues of the implementation in
17
- Ruby. The main design goals directly taken from the BGL design are:
18
-
19
- * An interface for how the structure of a graph can be accessed using a generic
20
- interface that hides the details of the graph data structure
21
- implementation. This interface is defined by the module {Graph}, which should be
22
- included in concrete classes.
23
-
24
- * A standardized generic interface for traversing graphs {RGL::GraphIterator}
25
-
26
- RGL provides some general purpose graph classes that conform to this interface,
27
- but they are not meant to be the *only* graph classes. As in BGL I believe that
28
- the main contribution of the RGL is the formulation of this interface.
29
-
30
- The BGL graph interface and graph components are generic in the sense of the C++
31
- Standard Template Library (STL). In Ruby other techniques are available to
32
- express the generic character of the algorithms and data structures mainly using
33
- mixins and iterators. The BGL documentation mentions three means to achieve
34
- genericity:
35
-
36
- * Algorithm/Data-Structure Interoperability
37
- * Extension through Function Objects and Visitors
38
- * Element Type Parameterization
39
- * Vertex and Edge Property Multi-Parameterization
40
-
41
- The first is easily achieved in RGL using mixins, which of course is not as
42
- efficient than C++ templates (but much more readable :-). The second one is even
43
- more easily implemented using standard iterators with blocks or using the
44
- {http://www.rubydoc.info/github/monora/stream stream module}. The third one is
45
- no issue since Ruby is dynamically typed: Each object can be a graph vertex.
46
- There is no need for a vertex (or even edge type). In the current version of RGL
47
- properties of vertices are simply attached using hashes. At first there seems to
48
- be not much need for the graph property machinery.
49
-
50
- === Algorithms
51
-
52
- RGL current contains a core set of algorithm patterns:
53
-
54
- * Breadth First Search {RGL::BFSIterator}
55
- * Depth First Search {RGL::DFSIterator}
56
-
57
- The algorithm patterns by themselves do not compute any meaningful quantities
58
- over graphs, they are merely building blocks for constructing graph
59
- algorithms. The graph algorithms in RGL currently include:
60
-
61
- * Topological Sort {RGL::TopsortIterator}
62
- * Connected Components {RGL::Graph#each_connected_component}
63
- * Strongly Connected Components {RGL::Graph#strongly_connected_components}
64
- * Transitive Closure {RGL::Graph#transitive_closure}
65
- * Dijkstras Shortest Path Algorithm {RGL::DijkstraAlgorithm}
66
- * Bellman Ford Algorithm {RGL::BellmanFordAlgorithm}
67
-
68
- === Data Structures
69
-
70
- RGL currently provides two graph classes that implement a generalized adjacency
71
- list and an edge list adaptor.
72
-
73
- * {RGL::AdjacencyGraph}
74
- * {RGL::ImplicitGraph}
75
-
76
- The AdjacencyGraph class is the general purpose _swiss army knife_ of graph
77
- classes. It is highly parameterized so that it can be optimized for different
78
- situations: the graph is directed or undirected, allow or disallow parallel
79
- edges, efficient access to just the out-edges, fast vertex insertion and removal
80
- at the cost of extra space overhead, etc.
81
-
82
- === Differences to BGL
83
-
84
- The concepts of IncidenceGraph, AdjacencyGraph and VertexListGraph (see
85
- http://www.boost.org/libs/graph/doc/IncidenceGraph.html) are here bundled in the
86
- base graph module. Most methods of IncidenceGraph should be standard in the base
87
- module Graph. The complexity guarantees can not necessarily provided. See
88
- http://www.boost.org/libs/graph/doc/graph_concepts.html.
89
-
90
- == Installation
91
-
92
- % gem install rgl
93
-
94
- or download the latest sources from the git repository http://github.com/monora/rgl.
95
-
96
- == Running tests
97
-
98
- Checkout RGL git repository and go to the project directory. First, install RGL
99
- dependencies with bundler:
100
-
101
- % bundle install
102
-
103
- After that you can run the tests:
104
-
105
- % rake test
106
-
107
- To see tests coverage run rcov[http://github.com/relevance/rcov] rake task:
108
-
109
- % rake rcov
110
-
111
- This command will generate tests coverage report in coverage/ directory.
112
-
113
- <em>Node: rcov is not compatible with Ruby >= 1.9, so this rake task is
114
- available only on Ruby 1.8.</em>
115
-
116
- == Example irb session with RGL
117
-
118
-
119
- irb> require 'rgl/adjacency'
120
- irb> dg=RGL::DirectedAdjacencyGraph[1,2 ,2,3 ,2,4, 4,5, 6,4, 1,6]
121
- # Use DOT to visualize this graph:
122
- irb> require 'rgl/dot'
123
- irb> dg.write_to_graphic_file('jpg')
124
- "graph.jpg"
125
-
126
- The result:
127
-
128
- link:images/example.jpg
129
-
130
- irb> dg.directed?
131
- true
132
- irb> dg.vertices
133
- [5, 6, 1, 2, 3, 4]
134
- irb> dg.has_vertex? 4
135
- true
136
-
137
- Every object could be a vertex (there is no class Vertex), even the class
138
- object _Object_:
139
-
140
- irb> dg.has_vertex? Object
141
- false
142
- irb> dg.edges.sort.to_s
143
- "(1-2)(1-6)(2-3)(2-4)(4-5)(6-4)"
144
- irb> dg.to_undirected.edges.sort.to_s
145
- "(1=2)(1=6)(2=3)(2=4)(5=4)(6=4)"
146
-
147
- Add inverse edge (4-2) to directed graph:
148
-
149
- irb> dg.add_edge 4,2
150
-
151
- (4-2) == (2-4) in the undirected graph:
152
-
153
- irb> dg.to_undirected.edges.sort.to_s
154
- "(1=2)(1=6)(2=3)(2=4)(5=4)(6=4)"
155
-
156
- (4-2) != (2-4) in directed graphs:
157
-
158
- irb> dg.edges.sort.to_s
159
- "(1-2)(1-6)(2-3)(2-4)(4-2)(4-5)(6-4)"
160
- irb> dg.remove_edge 4,2
161
- true
162
-
163
- <em>Topological sort</em> is implemented as an iterator:
164
-
165
- require 'rgl/topsort'
166
- irb> dg.topsort_iterator.to_a
167
- [1, 2, 3, 6, 4, 5]
168
-
169
- A more elaborated example showing <em>implicit graphs</em>:
170
-
171
- require 'rgl/implicit'
172
- def module_graph
173
- RGL::ImplicitGraph.new { |g|
174
- g.vertex_iterator { |b|
175
- ObjectSpace.each_object(Module, &b)
176
- }
177
- g.adjacent_iterator { |x, b|
178
- x.ancestors.each { |y|
179
- b.call(y) unless x == y || y == Kernel || y == Object
180
- }
181
- }
182
- g.directed = true
183
- }
184
- end
185
-
186
- This function creates a directed graph, with vertices being all loaded modules:
187
-
188
- g = module_graph
189
-
190
- We only want to see the ancestors of {RGL::AdjacencyGraph}:
191
-
192
- require 'rgl/traversal'
193
- tree = g.bfs_search_tree_from(RGL::AdjacencyGraph)
194
-
195
- Now we want to visualize this component of g with DOT. We therefore create a
196
- subgraph of the original graph, using a filtered graph:
197
-
198
- g = g.vertices_filtered_by {|v| tree.has_vertex? v}
199
- g.write_to_graphic_file('jpg')
200
-
201
- creates the following graph image with DOT:
202
-
203
- link:images/module_graph.jpg
204
-
205
- This graph shows all loaded RGL modules:
206
-
207
- link:images/rgl_modules.png
208
-
209
- Look for more in _examples_ directory (i.e. {file:examples/examples.rb}).
210
-
211
- == My del.icio.us links concerning RGL
212
-
213
- I collect some links to stuff around RGL at http://del.icio.us/monora/rgl.
214
-
215
- == Credits
216
-
217
- Many thanks to Robert Feldt which also worked on a graph library
218
- (http://rockit.sf.net/subprojects/graphr) who pointed me to BGL and many other
219
- graph resources.
220
-
221
- Robert kindly allowed to integrate his work on graphr, which I did not yet
222
- succeed. Especially his work to output graphs for
223
- GraphViz[http://www.research.att.com/sw/tools/graphviz/download.html] is much
224
- more elaborated than the minimal support in dot.rb.
225
-
226
- Jeremy Siek one of the authors of the nice book "The Boost Graph Library (BGL)"
227
- (http://www.boost.org/libs/graph/doc) kindly allowed to use the
228
- BGL documentation as a _cheap_ reference for RGL. He and Robert also gave
229
- feedback and many ideas for RGL.
230
-
231
- Dave Thomas for RDoc[http://rdoc.sourceforge.net] which generated what you read
232
- and matz for Ruby. Dave included in the latest version of RDoc (alpha9) the
233
- module dot/dot.rb which I use instead of Roberts module to visualize graphs
234
- (see rgl/dot.rb).
235
-
236
- Jeremy Bopp, John Carter, Sascha Doerdelmann, Shawn Garbett, Andreas Schörk
237
- and Kirill Lashuk for contributing additions, test cases and bugfixes.
238
-
239
- Kirill Lashuk who started to take over further development in November 2012.
240
-
241
- See also http://github.com/monora/rgl/contributors.
242
-
243
- == Copying
244
-
245
- RGL is Copyright (c) 2002,2004,2005,2008,2013,2015 by Horst Duchene. It is free software,
246
- and may be redistributed under the terms specified in the README file of the
247
- Ruby distribution.
248
-
Binary file