rgl 0.5.1 → 0.5.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ChangeLog +72 -16
- data/Gemfile +4 -3
- data/README.md +267 -0
- data/Rakefile +15 -30
- data/examples/examples.rb +11 -9
- data/examples/unix.dot +53 -0
- data/lib/rgl/adjacency.rb +2 -2
- data/lib/rgl/base.rb +4 -3
- data/lib/rgl/bellman_ford.rb +1 -2
- data/lib/rgl/bipartite.rb +2 -2
- data/lib/rgl/dijkstra.rb +3 -29
- data/lib/rgl/dot.rb +33 -14
- data/lib/rgl/edmonds_karp.rb +4 -4
- data/lib/rgl/graph_iterator.rb +4 -0
- data/lib/rgl/graphxml.rb +2 -2
- data/lib/rgl/path.rb +17 -0
- data/lib/rgl/rdot.rb +1 -1
- data/lib/rgl/traversal.rb +8 -1
- data/test/components_test.rb +2 -2
- data/test/dijkstra_issue24_test.rb +23 -0
- data/test/dot_test.rb +54 -14
- data/test/graph_test.rb +5 -0
- data/test/graph_xml_test.rb +1 -7
- data/test/path_test.rb +52 -0
- data/test/test_helper.rb +3 -0
- data/test/traversal_test.rb +26 -0
- metadata +131 -150
- data/README.rdoc +0 -248
- data/examples/images/example.jpg +0 -0
- data/examples/images/module_graph.jpg +0 -0
- data/examples/images/rgl_modules.png +0 -0
- data/lib/rgl/enumerable_ext.rb +0 -16
data/README.rdoc
DELETED
@@ -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
|
-
|
data/examples/images/example.jpg
DELETED
Binary file
|
Binary file
|
Binary file
|
data/lib/rgl/enumerable_ext.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
module Enumerable
|
2
|
-
|
3
|
-
# Fixnum()
|
4
|
-
#
|
5
|
-
# Return the number of elements of the Enumerable. Same as _size_ but not all
|
6
|
-
# Enumerables implement size.
|
7
|
-
#--
|
8
|
-
# Should we call the methods _size_?
|
9
|
-
#
|
10
|
-
def length
|
11
|
-
inject(0) do |sum, v|
|
12
|
-
sum + 1
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|