rgl 0.5.9 → 0.5.10
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.
- checksums.yaml +4 -4
- data/ChangeLog +2 -2
- data/README.md +11 -11
- data/examples/canvas.rb +1 -1
- data/examples/graph.dot +971 -0
- data/examples/insel_der_tausend_gefahren.rb +1 -1
- data/examples/north/g.10.0.graphml +1 -1
- data/examples/north/g.10.1.graphml +1 -1
- data/examples/north/g.10.11.graphml +1 -1
- data/examples/north/g.10.12.graphml +1 -1
- data/examples/north/g.10.13.graphml +1 -1
- data/examples/north/g.10.14.graphml +1 -1
- data/examples/north/g.10.15.graphml +1 -1
- data/examples/north/g.10.16.graphml +1 -1
- data/examples/north/g.10.17.graphml +1 -1
- data/examples/north/g.10.19.graphml +1 -1
- data/examples/north/g.10.2.graphml +1 -1
- data/examples/north/g.10.20.graphml +1 -1
- data/examples/north/g.10.22.graphml +1 -1
- data/examples/north/g.10.24.graphml +1 -1
- data/examples/north/g.10.25.graphml +1 -1
- data/examples/north/g.10.27.graphml +1 -1
- data/examples/north/g.10.28.graphml +1 -1
- data/examples/north/g.10.29.graphml +1 -1
- data/examples/north/g.10.3.graphml +1 -1
- data/examples/north/g.10.30.graphml +1 -1
- data/examples/north/g.10.31.graphml +1 -1
- data/examples/north/g.10.34.graphml +1 -1
- data/examples/north/g.10.37.graphml +1 -1
- data/examples/north/g.10.38.graphml +1 -1
- data/examples/north/g.10.39.graphml +1 -1
- data/examples/north/g.10.4.graphml +1 -1
- data/examples/north/g.10.40.graphml +1 -1
- data/examples/north/g.10.41.graphml +1 -1
- data/examples/north/g.10.42.graphml +1 -1
- data/examples/north/g.10.45.graphml +1 -1
- data/examples/north/g.10.46.graphml +1 -1
- data/examples/north/g.10.5.graphml +1 -1
- data/examples/north/g.10.50.graphml +1 -1
- data/examples/north/g.10.56.graphml +1 -1
- data/examples/north/g.10.57.graphml +1 -1
- data/examples/north/g.10.58.graphml +1 -1
- data/examples/north/g.10.6.graphml +1 -1
- data/examples/north/g.10.60.graphml +1 -1
- data/examples/north/g.10.61.graphml +1 -1
- data/examples/north/g.10.62.graphml +1 -1
- data/examples/north/g.10.68.graphml +1 -1
- data/examples/north/g.10.69.graphml +1 -1
- data/examples/north/g.10.7.graphml +1 -1
- data/examples/north/g.10.70.graphml +1 -1
- data/examples/north/g.10.71.graphml +1 -1
- data/examples/north/g.10.72.graphml +1 -1
- data/examples/north/g.10.74.graphml +1 -1
- data/examples/north/g.10.75.graphml +1 -1
- data/examples/north/g.10.78.graphml +1 -1
- data/examples/north/g.10.79.graphml +1 -1
- data/examples/north/g.10.8.graphml +1 -1
- data/examples/north/g.10.80.graphml +1 -1
- data/examples/north/g.10.82.graphml +1 -1
- data/examples/north/g.10.83.graphml +1 -1
- data/examples/north/g.10.85.graphml +1 -1
- data/examples/north/g.10.86.graphml +1 -1
- data/examples/north/g.10.88.graphml +1 -1
- data/examples/north/g.10.89.graphml +1 -1
- data/examples/north/g.10.9.graphml +1 -1
- data/examples/north/g.10.90.graphml +1 -1
- data/examples/north/g.10.91.graphml +1 -1
- data/examples/north/g.10.92.graphml +1 -1
- data/examples/north/g.10.93.graphml +1 -1
- data/examples/north/g.10.94.graphml +1 -1
- data/examples/north/g.12.8.graphml +1 -1
- data/examples/north/g.14.9.graphml +1 -1
- data/examples/north.rb +1 -1
- data/examples/rdep-rgl.rb +3 -3
- data/lib/rgl/adjacency.rb +43 -51
- data/lib/rgl/base.rb +71 -60
- data/lib/rgl/bellman_ford.rb +4 -3
- data/lib/rgl/bidirectional.rb +2 -2
- data/lib/rgl/bipartite.rb +1 -1
- data/lib/rgl/condensation.rb +3 -3
- data/lib/rgl/connected_components.rb +6 -6
- data/lib/rgl/dot.rb +5 -7
- data/lib/rgl/edmonds_karp.rb +7 -2
- data/lib/rgl/graph_iterator.rb +4 -2
- data/lib/rgl/graph_visitor.rb +16 -14
- data/lib/rgl/graph_wrapper.rb +3 -2
- data/lib/rgl/graphxml.rb +4 -4
- data/lib/rgl/implicit.rb +35 -35
- data/lib/rgl/mutable.rb +7 -7
- data/lib/rgl/path_builder.rb +3 -2
- data/lib/rgl/prim.rb +3 -1
- data/lib/rgl/rdot.rb +7 -7
- data/lib/rgl/topsort.rb +8 -7
- data/lib/rgl/transitivity.rb +6 -6
- data/lib/rgl/traversal.rb +47 -47
- data/test/traversal_test.rb +1 -1
- metadata +4 -3
@@ -1,6 +1,6 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
2
|
<!-- This file was written by the internal XML-Handler of Y-Files.-->
|
3
|
-
<!DOCTYPE graphml SYSTEM "
|
3
|
+
<!DOCTYPE graphml SYSTEM "https://www.graphdrawing.org/dtds/graphml.dtd">
|
4
4
|
<graphml>
|
5
5
|
<graph id="G">
|
6
6
|
<node id="n0"/>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
2
|
<!-- This file was written by the internal XML-Handler of Y-Files.-->
|
3
|
-
<!DOCTYPE graphml SYSTEM "
|
3
|
+
<!DOCTYPE graphml SYSTEM "https://www.graphdrawing.org/dtds/graphml.dtd">
|
4
4
|
<graphml>
|
5
5
|
<graph id="G">
|
6
6
|
<node id="n0"/>
|
data/examples/north.rb
CHANGED
data/examples/rdep-rgl.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
#
|
2
2
|
# Simple extensions of Hal Fultons tool to show dependencies between ruby
|
3
|
-
# source files (see
|
3
|
+
# source files (see https://hypermetrics.com/rubyhacker/code/rdep/). The basic
|
4
4
|
# extensions can be found at the end of the function find_files.
|
5
5
|
#
|
6
|
-
# Source: [
|
6
|
+
# Source: [https://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/rgl/rgl/examples/rdep-rgl.rb]
|
7
7
|
#
|
8
8
|
# Additionaly rdep-rgl.rb generates a graphics file named
|
9
9
|
# File.basename(ARGV[0]) + ".png".
|
10
10
|
#
|
11
|
-
# Requires RGL (
|
11
|
+
# Requires RGL (https://rgl.sourceforge.net) and Graphviz
|
12
12
|
# (www.research.att.com/sw/tools/graphviz/download.html).
|
13
13
|
#
|
14
14
|
# ruby rdep-rgl.rb j:/ruby/lib/ruby/site_ruby/1.6/rdoc/rdoc.rb
|
data/lib/rgl/adjacency.rb
CHANGED
@@ -1,30 +1,27 @@
|
|
1
1
|
# adjacency.rb
|
2
2
|
#
|
3
|
-
# $Id$
|
4
|
-
#
|
5
|
-
# The DirectedAdjacencyGraph class implements a generalized adjacency list
|
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.
|
10
|
-
#
|
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.
|
14
|
-
|
15
3
|
require 'rgl/mutable'
|
16
4
|
require 'set'
|
17
5
|
|
18
6
|
module RGL
|
19
7
|
|
8
|
+
# The +DirectedAdjacencyGraph+ class implements a generalized adjacency list
|
9
|
+
# graph structure. An AdjacencyGraph is basically a two-dimensional structure
|
10
|
+
# (ie, a list of lists). Each element of the first dimension represents a
|
11
|
+
# vertex. Each of the vertices contains a one-dimensional structure that is
|
12
|
+
# the list of all adjacent vertices.
|
13
|
+
#
|
14
|
+
# The class for representing the adjacency list of a vertex is, by default, a
|
15
|
+
# +Set+. This can be configured by the client, however, when an AdjacencyGraph
|
16
|
+
# is created.
|
20
17
|
class DirectedAdjacencyGraph
|
21
18
|
|
22
19
|
include MutableGraph
|
23
20
|
|
24
|
-
# Shortcut for creating a DirectedAdjacencyGraph
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
21
|
+
# Shortcut for creating a DirectedAdjacencyGraph
|
22
|
+
# @example
|
23
|
+
# RGL::DirectedAdjacencyGraph[1,2, 2,3, 2,4, 4,5].edges.to_a.to_s =>
|
24
|
+
# "(1-2)(2-3)(2-4)(4-5)"
|
28
25
|
#
|
29
26
|
def self.[](*a)
|
30
27
|
result = new
|
@@ -32,13 +29,13 @@ module RGL
|
|
32
29
|
result
|
33
30
|
end
|
34
31
|
|
35
|
-
#
|
36
|
-
#
|
37
|
-
# set semantics for edges and vertices.
|
32
|
+
# The new empty graph has as its edgelist class the given class. The default
|
33
|
+
# edgelist class is Set, to ensure set semantics for edges and vertices.
|
38
34
|
#
|
39
35
|
# If other graphs are passed as parameters their vertices and edges are
|
40
36
|
# added to the new graph.
|
41
|
-
#
|
37
|
+
# @param [Class] edgelist_class
|
38
|
+
# @param [Array[Graph]] other_graphs
|
42
39
|
def initialize(edgelist_class = Set, *other_graphs)
|
43
40
|
@edgelist_class = edgelist_class
|
44
41
|
@vertices_dict = Hash.new
|
@@ -58,58 +55,53 @@ module RGL
|
|
58
55
|
end
|
59
56
|
|
60
57
|
# Iterator for the keys of the vertices list hash.
|
61
|
-
#
|
58
|
+
# @see Graph#each_vertex
|
62
59
|
def each_vertex(&b)
|
63
60
|
@vertices_dict.each_key(&b)
|
64
61
|
end
|
65
62
|
|
66
|
-
|
63
|
+
# @see Graph#each_adjacent
|
64
|
+
def each_adjacent(v, &b)
|
67
65
|
adjacency_list = (@vertices_dict[v] or raise NoVertexError, "No vertex #{v}.")
|
68
66
|
adjacency_list.each(&b)
|
69
67
|
end
|
70
68
|
|
71
|
-
#
|
69
|
+
# @return true.
|
72
70
|
#
|
73
71
|
def directed?
|
74
72
|
true
|
75
73
|
end
|
76
74
|
|
77
|
-
# Complexity is O(1), because the vertices are kept in a Hash containing
|
75
|
+
# Complexity is O(1), because the vertices are kept in a +Hash+ containing
|
78
76
|
# as values the lists of adjacent vertices of _v_.
|
79
77
|
#
|
78
|
+
# @see Graph#has_vertex
|
80
79
|
def has_vertex?(v)
|
81
80
|
@vertices_dict.has_key?(v)
|
82
81
|
end
|
83
82
|
|
84
83
|
# Complexity is O(1), if a Set is used as adjacency list. Otherwise,
|
85
84
|
# complexity is O(out_degree(v)).
|
86
|
-
#
|
87
|
-
# ---
|
88
|
-
# MutableGraph interface.
|
89
|
-
#
|
85
|
+
# @see Graph#has_edge?
|
90
86
|
def has_edge?(u, v)
|
91
87
|
has_vertex?(u) && @vertices_dict[u].include?(v)
|
92
88
|
end
|
93
89
|
|
94
|
-
#
|
95
|
-
#
|
96
|
-
# If the vertex is already in the graph (using eql?), the method does
|
90
|
+
# If the vertex is already in the graph (using +eql?+), the method does
|
97
91
|
# nothing.
|
98
|
-
#
|
92
|
+
# @see MutableGraph#add_vertex
|
99
93
|
def add_vertex(v)
|
100
94
|
@vertices_dict[v] ||= @edgelist_class.new
|
101
95
|
end
|
102
96
|
|
103
|
-
#
|
104
|
-
#
|
97
|
+
# @see MutableGraph#add_edge.
|
105
98
|
def add_edge(u, v)
|
106
99
|
add_vertex(u) # ensure key
|
107
100
|
add_vertex(v) # ensure key
|
108
101
|
basic_add_edge(u, v)
|
109
102
|
end
|
110
103
|
|
111
|
-
#
|
112
|
-
#
|
104
|
+
# @see MutableGraph#remove_vertex.
|
113
105
|
def remove_vertex(v)
|
114
106
|
@vertices_dict.delete(v)
|
115
107
|
|
@@ -117,16 +109,15 @@ module RGL
|
|
117
109
|
@vertices_dict.each_value { |adjList| adjList.delete(v) }
|
118
110
|
end
|
119
111
|
|
120
|
-
#
|
121
|
-
#
|
112
|
+
# @see MutableGraph::remove_edge.
|
122
113
|
def remove_edge(u, v)
|
123
114
|
@vertices_dict[u].delete(v) unless @vertices_dict[u].nil?
|
124
115
|
end
|
125
116
|
|
126
|
-
# Converts the adjacency list of each vertex to be of type
|
117
|
+
# Converts the adjacency list of each vertex to be of type +klass+. The
|
127
118
|
# class is expected to have a new constructor which accepts an enumerable as
|
128
119
|
# parameter.
|
129
|
-
#
|
120
|
+
# @param [Class] klass
|
130
121
|
def edgelist_class=(klass)
|
131
122
|
@vertices_dict.keys.each do |v|
|
132
123
|
@vertices_dict[v] = klass.new @vertices_dict[v].to_a
|
@@ -141,20 +132,21 @@ module RGL
|
|
141
132
|
|
142
133
|
end # class DirectedAdjacencyGraph
|
143
134
|
|
144
|
-
# AdjacencyGraph is an undirected Graph. The methods
|
145
|
-
#
|
146
|
-
#
|
135
|
+
# AdjacencyGraph is an undirected Graph. The methods
|
136
|
+
# {DirectedAdjacencyGraph#add_edge} and {DirectedAdjacencyGraph#remove_edge}
|
137
|
+
# are reimplemented: if an edge (u,v) is added or removed, then the reverse
|
138
|
+
# edge (v,u) is also added or removed.
|
147
139
|
#
|
148
140
|
class AdjacencyGraph < DirectedAdjacencyGraph
|
149
141
|
|
150
|
-
#
|
142
|
+
# @return false.
|
151
143
|
#
|
152
144
|
def directed?
|
153
145
|
false
|
154
146
|
end
|
155
147
|
|
156
148
|
# Also removes (v,u)
|
157
|
-
#
|
149
|
+
# @see DirectedAdjacencyGraph#remove_edge
|
158
150
|
def remove_edge(u, v)
|
159
151
|
super
|
160
152
|
@vertices_dict[v].delete(u) unless @vertices_dict[v].nil?
|
@@ -172,8 +164,8 @@ module RGL
|
|
172
164
|
module Graph
|
173
165
|
|
174
166
|
# Convert a general graph to an AdjacencyGraph. If the graph is directed,
|
175
|
-
# returns a DirectedAdjacencyGraph; otherwise, returns an AdjacencyGraph.
|
176
|
-
#
|
167
|
+
# returns a {DirectedAdjacencyGraph}; otherwise, returns an {AdjacencyGraph}.
|
168
|
+
# @return {DirectedAdjacencyGraph} or {AdjacencyGraph}
|
177
169
|
def to_adjacency
|
178
170
|
result = (directed? ? DirectedAdjacencyGraph : AdjacencyGraph).new
|
179
171
|
each_vertex { |v| result.add_vertex(v) }
|
@@ -185,7 +177,7 @@ module RGL
|
|
185
177
|
# If (u,v) is an edge of the graph, then (v,u) is an edge of the result.
|
186
178
|
#
|
187
179
|
# If the graph is undirected, the result is self.
|
188
|
-
#
|
180
|
+
# @return [DirectedAdjacencyGraph]
|
189
181
|
def reverse
|
190
182
|
return self unless directed?
|
191
183
|
result = DirectedAdjacencyGraph.new
|
@@ -194,12 +186,12 @@ module RGL
|
|
194
186
|
result
|
195
187
|
end
|
196
188
|
|
197
|
-
# Return a new AdjacencyGraph which has the same set of vertices. If (u,v)
|
189
|
+
# Return a new {AdjacencyGraph} which has the same set of vertices. If (u,v)
|
198
190
|
# is an edge of the graph, then (u,v) and (v,u) (which are the same edges)
|
199
191
|
# are edges of the result.
|
200
192
|
#
|
201
|
-
# If the graph is undirected, the result is self
|
202
|
-
#
|
193
|
+
# If the graph is undirected, the result is +self+.
|
194
|
+
# @return [AdjacencyGraph]
|
203
195
|
def to_undirected
|
204
196
|
return self unless directed?
|
205
197
|
AdjacencyGraph.new(Set, self)
|
data/lib/rgl/base.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
# base.rb
|
2
|
-
#
|
3
|
-
# Module RGL defines the namespace for all modules and classes of the graph
|
4
|
-
# library. The main module is RGL::Graph which defines the abstract behavior of
|
5
|
-
# all graphs in the library.
|
6
2
|
|
7
|
-
|
3
|
+
# version information
|
4
|
+
RGL_VERSION = "0.5.10"
|
5
|
+
|
6
|
+
# Module {RGL} defines the namespace for all modules and classes of the graph
|
7
|
+
# library. The main module is {Graph} which defines the abstract behavior of
|
8
|
+
# all graphs in the library. Other important modules or classes are:
|
9
|
+
#
|
10
|
+
# * Class {AdjacencyGraph} provides a concrete implementation of an undirected graph.
|
11
|
+
# * Module {Edge} defines edges of a graph.
|
12
|
+
# * {GraphIterator} and {GraphVisitor} provide support for iterating and searching.
|
13
|
+
# * {DOT} helps to visualize graphs.
|
8
14
|
|
9
15
|
module RGL
|
10
16
|
class NotDirectedError < RuntimeError; end
|
@@ -17,16 +23,16 @@ module RGL
|
|
17
23
|
|
18
24
|
INFINITY = 1.0 / 0.0 # positive infinity
|
19
25
|
|
20
|
-
# Module Edge includes classes for representing edges of directed and
|
21
|
-
# undirected graphs. There is no need for a
|
26
|
+
# Module {Edge} includes classes for representing edges of directed and
|
27
|
+
# undirected graphs. There is no need for a vertex class, because every ruby
|
22
28
|
# object can be a vertex of a graph.
|
23
29
|
#
|
24
30
|
module Edge
|
25
|
-
#
|
26
|
-
# omit to instantiate edges. They instead use two vertex
|
27
|
-
# representing edges (see each_edge). If a client wants to
|
28
|
-
# explicitly DirectedEdge or UnDirectedEdge instances are
|
29
|
-
# (i.e. Graph#edges).
|
31
|
+
# An {Edge} is simply a directed pair +(source -> target)+. Most library
|
32
|
+
# functions try do omit to instantiate edges. They instead use two vertex
|
33
|
+
# parameters for representing edges (see {Graph#each_edge}). If a client wants to
|
34
|
+
# store edges explicitly {DirectedEdge} or {UnDirectedEdge} instances are
|
35
|
+
# returned (i.e. {Graph#edges}).
|
30
36
|
#
|
31
37
|
class DirectedEdge
|
32
38
|
|
@@ -37,15 +43,14 @@ module RGL
|
|
37
43
|
new(a[0], a[1])
|
38
44
|
end
|
39
45
|
|
40
|
-
# Create a new DirectedEdge with source
|
46
|
+
# Create a new DirectedEdge with source +a+ and target +b+.
|
41
47
|
#
|
42
48
|
def initialize(a, b)
|
43
49
|
@source, @target = a, b
|
44
50
|
end
|
45
51
|
|
46
|
-
# Two directed edges (u,v) and (x,y) are equal iff u == x and v == y. eql
|
47
|
-
# is needed when edges are inserted into a Set
|
48
|
-
#
|
52
|
+
# Two directed edges (u,v) and (x,y) are equal iff u == x and v == y. +eql?+
|
53
|
+
# is needed when edges are inserted into a +Set+. +eql?+ is aliased to +==+.
|
49
54
|
def eql?(edge)
|
50
55
|
(source == edge.source) && (target == edge.target)
|
51
56
|
end
|
@@ -57,20 +62,22 @@ module RGL
|
|
57
62
|
end
|
58
63
|
|
59
64
|
# Returns (v,u) if self == (u,v).
|
60
|
-
#
|
65
|
+
# @return [Edge]
|
61
66
|
def reverse
|
62
67
|
self.class.new(target, source)
|
63
68
|
end
|
64
69
|
|
65
|
-
# Edges can be indexed. edge
|
66
|
-
# all n>0
|
70
|
+
# Edges can be indexed. +edge.at(0) == edge.source+, +edge.at(n) ==
|
71
|
+
# edge.target+ for all +n>0+. Edges can thus be used as a two element array.
|
67
72
|
#
|
68
73
|
def [](index)
|
69
74
|
index.zero? ? source : target
|
70
75
|
end
|
71
76
|
|
72
|
-
#
|
73
|
-
#
|
77
|
+
# Returns string representation of the edge
|
78
|
+
# @example
|
79
|
+
# DirectedEdge[1,2].to_s == "(1-2)"
|
80
|
+
# @return [String]
|
74
81
|
def to_s
|
75
82
|
"(#{source}-#{target})"
|
76
83
|
end
|
@@ -79,7 +86,7 @@ module RGL
|
|
79
86
|
alias inspect to_s
|
80
87
|
|
81
88
|
# Returns the array [source,target].
|
82
|
-
#
|
89
|
+
# @return [Array]
|
83
90
|
def to_a
|
84
91
|
[source, target]
|
85
92
|
end
|
@@ -93,15 +100,18 @@ module RGL
|
|
93
100
|
end # DirectedEdge
|
94
101
|
|
95
102
|
# An undirected edge is simply an undirected pair (source, target) used in
|
96
|
-
# undirected graphs.
|
103
|
+
# undirected graphs.
|
104
|
+
# @example
|
105
|
+
# UnDirectedEdge[u,v] == UnDirectedEdge[v,u]
|
97
106
|
#
|
98
107
|
class UnDirectedEdge < DirectedEdge
|
99
108
|
def eql?(edge)
|
100
109
|
super || ((target == edge.source) && (source == edge.target))
|
101
110
|
end
|
102
111
|
|
103
|
-
#
|
104
|
-
#
|
112
|
+
# @example
|
113
|
+
# UnDirectedEdge[1,2].to_s == "(1=2)"
|
114
|
+
# @return (see DirectedEdge#to_s)
|
105
115
|
def to_s
|
106
116
|
"(#{source}=#{target})"
|
107
117
|
end
|
@@ -110,18 +120,18 @@ module RGL
|
|
110
120
|
|
111
121
|
end # Edge
|
112
122
|
|
113
|
-
# In
|
114
|
-
#
|
115
|
-
# distinguish between the IncidenceGraph, EdgeListGraph and
|
116
|
-
# concepts, which would complicate the interface too much.
|
117
|
-
# defined in BGL to differentiate between efficient access
|
118
|
-
# vertices.
|
123
|
+
# In _BGL_ terminology the module Graph defines the graph concept (see {Graph
|
124
|
+
# Concepts}[https://www.boost.org/libs/graph/doc/graph_concepts.html]). We
|
125
|
+
# however do not distinguish between the IncidenceGraph, EdgeListGraph and
|
126
|
+
# VertexListGraph concepts, which would complicate the interface too much.
|
127
|
+
# These concepts are defined in BGL to differentiate between efficient access
|
128
|
+
# to edges and vertices.
|
119
129
|
#
|
120
130
|
# The RGL Graph concept contains only a few requirements that are common to
|
121
131
|
# all the graph concepts. These include, especially, the iterators defining
|
122
|
-
# the sets of vertices and edges (see each_vertex and each_adjacent). Most
|
132
|
+
# the sets of vertices and edges (see {#each_vertex} and {#each_adjacent}). Most
|
123
133
|
# other functions are derived from these fundamental iterators, i.e.
|
124
|
-
# num_vertices or num_edges.
|
134
|
+
# {#each_edge}, {#num_vertices} or {#num_edges}.
|
125
135
|
#
|
126
136
|
# Each graph is an enumerable of vertices.
|
127
137
|
#
|
@@ -129,30 +139,30 @@ module RGL
|
|
129
139
|
|
130
140
|
include Enumerable
|
131
141
|
include Edge
|
132
|
-
# The each_vertex iterator defines the set of vertices
|
133
|
-
# defined by concrete graph classes. It defines the BGL
|
134
|
-
# concept.
|
142
|
+
# The +each_vertex+ iterator defines the set of vertices of the graph. This
|
143
|
+
# method must be defined by concrete graph classes. It defines the BGL
|
144
|
+
# VertexListGraph concept.
|
135
145
|
#
|
136
146
|
def each_vertex() # :yields: v
|
137
147
|
raise NotImplementedError
|
138
148
|
end
|
139
149
|
|
140
|
-
# The each_adjacent iterator defines the out edges of vertex
|
150
|
+
# The +each_adjacent+ iterator defines the out edges of vertex +v+. This
|
141
151
|
# method must be defined by concrete graph classes. Its defines the BGL
|
142
152
|
# IncidenceGraph concept.
|
153
|
+
# @param v a vertex of the graph
|
143
154
|
#
|
144
155
|
def each_adjacent(v) # :yields: v
|
145
156
|
raise NotImplementedError
|
146
157
|
end
|
147
158
|
|
148
|
-
# The each_edge iterator should provide efficient access to all edges of the
|
149
|
-
# graph. Its defines the EdgeListGraph concept.
|
159
|
+
# The +each_edge+ iterator should provide efficient access to all edges of the
|
160
|
+
# graph. Its defines the BGL EdgeListGraph concept.
|
150
161
|
#
|
151
|
-
# This method must
|
152
|
-
# can be implemented using each_vertex and each_adjacent. However for
|
153
|
-
# undirected
|
162
|
+
# This method must *not* be defined by concrete graph classes, because it
|
163
|
+
# can be implemented using {#each_vertex} and {#each_adjacent}. However for
|
164
|
+
# undirected graphs the function is inefficient because we must not yield
|
154
165
|
# (v,u) if we already visited edge (u,v).
|
155
|
-
#
|
156
166
|
def each_edge(&block)
|
157
167
|
if directed?
|
158
168
|
each_vertex do |u|
|
@@ -170,15 +180,14 @@ module RGL
|
|
170
180
|
end
|
171
181
|
|
172
182
|
# Is the graph directed? The default returns false.
|
173
|
-
#
|
174
183
|
def directed?
|
175
184
|
false
|
176
185
|
end
|
177
186
|
|
178
|
-
# Returns true if
|
187
|
+
# Returns true if +v+ is a vertex of the graph. Same as #include? inherited
|
179
188
|
# from Enumerable. Complexity is O(num_vertices) by default. Concrete graph
|
180
189
|
# may be better here (see AdjacencyGraph).
|
181
|
-
#
|
190
|
+
# @param (see #each_adjacent)
|
182
191
|
def has_vertex?(v)
|
183
192
|
include?(v) # inherited from enumerable
|
184
193
|
end
|
@@ -189,20 +198,20 @@ module RGL
|
|
189
198
|
num_vertices.zero?
|
190
199
|
end
|
191
200
|
|
192
|
-
#
|
193
|
-
#
|
201
|
+
# Synonym for #to_a inherited by Enumerable.
|
202
|
+
# @return [Array] of vertices
|
194
203
|
def vertices
|
195
204
|
to_a
|
196
205
|
end
|
197
206
|
|
198
|
-
#
|
207
|
+
# @return [Class] the class for edges: {Edge::DirectedEdge} or {Edge::UnDirectedEdge}.
|
199
208
|
#
|
200
209
|
def edge_class
|
201
210
|
directed? ? DirectedEdge : UnDirectedEdge
|
202
211
|
end
|
203
212
|
|
204
|
-
#
|
205
|
-
#
|
213
|
+
# @return [Array] of edges (DirectedEdge or UnDirectedEdge) of the graph
|
214
|
+
# It uses {#each_edge} to compute the edges
|
206
215
|
def edges
|
207
216
|
result = []
|
208
217
|
c = edge_class
|
@@ -210,8 +219,8 @@ module RGL
|
|
210
219
|
result
|
211
220
|
end
|
212
221
|
|
213
|
-
#
|
214
|
-
#
|
222
|
+
# @return [Array] of vertices adjacent to vertex +v+.
|
223
|
+
# @param (see #each_adjacent)
|
215
224
|
def adjacent_vertices(v)
|
216
225
|
r = []
|
217
226
|
each_adjacent(v) { |u| r << u }
|
@@ -219,15 +228,16 @@ module RGL
|
|
219
228
|
end
|
220
229
|
|
221
230
|
# Returns the number of out-edges (for directed graphs) or the number of
|
222
|
-
# incident edges (for undirected graphs) of vertex
|
223
|
-
#
|
231
|
+
# incident edges (for undirected graphs) of vertex +v+.
|
232
|
+
# @return [int]
|
233
|
+
# @param (see #each_adjacent)
|
224
234
|
def out_degree(v)
|
225
235
|
r = 0
|
226
236
|
each_adjacent(v) { |u| r += 1 }
|
227
237
|
r
|
228
238
|
end
|
229
239
|
|
230
|
-
#
|
240
|
+
# @return [int] the number of vertices
|
231
241
|
#
|
232
242
|
def size # Why not in Enumerable?
|
233
243
|
inject(0) { |n, v| n + 1 }
|
@@ -235,7 +245,7 @@ module RGL
|
|
235
245
|
|
236
246
|
alias num_vertices size
|
237
247
|
|
238
|
-
#
|
248
|
+
# @return [int] the number of edges
|
239
249
|
#
|
240
250
|
def num_edges
|
241
251
|
r = 0
|
@@ -244,13 +254,14 @@ module RGL
|
|
244
254
|
end
|
245
255
|
|
246
256
|
# Utility method to show a string representation of the edges of the graph.
|
247
|
-
#
|
257
|
+
# @return [String]
|
248
258
|
def to_s
|
249
259
|
edges.collect {|e| e.to_s}.sort.join
|
250
260
|
end
|
251
261
|
|
252
|
-
# Two graphs are equal iff they have equal directed? property as well as
|
253
|
-
#
|
262
|
+
# Two graphs are equal iff they have equal directed? property as well as
|
263
|
+
# vertices and edges sets.
|
264
|
+
# @param [Graph] other
|
254
265
|
def eql?(other)
|
255
266
|
equal?(other) || eql_graph?(other)
|
256
267
|
end
|
data/lib/rgl/bellman_ford.rb
CHANGED
@@ -39,9 +39,10 @@ module RGL
|
|
39
39
|
|
40
40
|
# Finds the shortest path form the _source_ to every other vertex of the graph.
|
41
41
|
#
|
42
|
-
# Returns the shortest paths map that contains the shortest path (if it
|
43
|
-
# graph.
|
42
|
+
# Returns the shortest paths map that contains the shortest path (if it
|
43
|
+
# exists) from the source to any vertex of the graph.
|
44
44
|
#
|
45
|
+
# @return [Hash[Object,Array]]
|
45
46
|
def shortest_paths(source)
|
46
47
|
init(source)
|
47
48
|
relax_edges
|
@@ -102,7 +103,7 @@ module RGL
|
|
102
103
|
#
|
103
104
|
# Raises ArgumentError or the graph has negative-weight cycles. This behavior can be overridden my a custom handler
|
104
105
|
# for visitor's _edge_not_minimized_ event.
|
105
|
-
#
|
106
|
+
# @return [Hash[Object,Array]]
|
106
107
|
def bellman_ford_shortest_paths(edge_weights_map, source, visitor = BellmanFordVisitor.new(self))
|
107
108
|
BellmanFordAlgorithm.new(self, edge_weights_map, visitor).shortest_paths(source)
|
108
109
|
end
|
data/lib/rgl/bidirectional.rb
CHANGED
@@ -28,7 +28,7 @@ module RGL
|
|
28
28
|
|
29
29
|
# Returns the number of in-edges (for directed graphs) or the number of
|
30
30
|
# incident edges (for undirected graphs) of vertex _v_.
|
31
|
-
#
|
31
|
+
# @return [int]
|
32
32
|
def in_degree(v)
|
33
33
|
r = 0
|
34
34
|
each_in_neighbor(v) { |u| r += 1 }
|
@@ -37,7 +37,7 @@ module RGL
|
|
37
37
|
|
38
38
|
# Returns the number of in-edges plus out-edges (for directed graphs) or the
|
39
39
|
# number of incident edges (for undirected graphs) of vertex _v_.
|
40
|
-
#
|
40
|
+
# @return [int]
|
41
41
|
def degree(v)
|
42
42
|
in_degree(v) + out_degree(v)
|
43
43
|
end
|
data/lib/rgl/bipartite.rb
CHANGED
@@ -10,7 +10,7 @@ module RGL
|
|
10
10
|
#
|
11
11
|
# Returns an array of two disjoint vertices sets (represented as arrays) if the graph is bipartite. Otherwise,
|
12
12
|
# returns nil.
|
13
|
-
#
|
13
|
+
# @return [Array]
|
14
14
|
def bipartite_sets
|
15
15
|
raise NotUndirectedError.new('bipartite sets can only be found for an undirected graph') if directed?
|
16
16
|
|
data/lib/rgl/condensation.rb
CHANGED
@@ -6,14 +6,14 @@ module RGL
|
|
6
6
|
|
7
7
|
module Graph
|
8
8
|
|
9
|
-
# Returns an
|
9
|
+
# Returns an {ImplicitGraph} where the strongly connected components of
|
10
10
|
# this graph are condensed into single nodes represented by Set instances
|
11
11
|
# containing the members of each strongly connected component. Edges
|
12
12
|
# between the different strongly connected components are preserved while
|
13
13
|
# edges within strongly connected components are omitted.
|
14
14
|
#
|
15
|
-
# Raises
|
16
|
-
#
|
15
|
+
# Raises {NotDirectedError} if run on an undirected graph.
|
16
|
+
# @return ImplicitGraph
|
17
17
|
def condensation_graph
|
18
18
|
raise NotDirectedError,
|
19
19
|
"condensation_graph only supported for directed graphs" unless directed?
|
@@ -38,7 +38,7 @@ module RGL
|
|
38
38
|
yield comp unless comp.empty?
|
39
39
|
end
|
40
40
|
|
41
|
-
# This GraphVisitor is used by strongly_connected_components to compute
|
41
|
+
# This {GraphVisitor} is used by {#strongly_connected_components} to compute
|
42
42
|
# the strongly connected components of a directed graph.
|
43
43
|
#
|
44
44
|
class TarjanSccVisitor < DFSVisitor
|
@@ -103,7 +103,7 @@ module RGL
|
|
103
103
|
# This is Tarjan's algorithm for strongly connected components, from his
|
104
104
|
# paper "Depth first search and linear graph algorithms". It calculates
|
105
105
|
# the components in a single application of DFS. We implement the
|
106
|
-
# algorithm with the help of the DFSVisitor TarjanSccVisitor.
|
106
|
+
# algorithm with the help of the {DFSVisitor} {TarjanSccVisitor}.
|
107
107
|
#
|
108
108
|
# === Definition
|
109
109
|
#
|
@@ -128,10 +128,10 @@ module RGL
|
|
128
128
|
# bibsource = "Parallel/Multi.bib, Misc/Reverse.eng.bib",
|
129
129
|
# }
|
130
130
|
#
|
131
|
-
# The output of the algorithm is recorded in a TarjanSccVisitor _vis_.
|
132
|
-
# vis.comp_map will contain numbers giving the component ID assigned to
|
133
|
-
# each vertex. The number of components is vis.num_comp
|
134
|
-
#
|
131
|
+
# The output of the algorithm is recorded in a {TarjanSccVisitor} _vis_.
|
132
|
+
# +vis.comp_map+ will contain numbers giving the component ID assigned to
|
133
|
+
# each vertex. The number of components is +vis.num_comp+.
|
134
|
+
# @return [TarjanSccVisitor]
|
135
135
|
def strongly_connected_components
|
136
136
|
raise NotDirectedError,
|
137
137
|
"strong_components only works for directed graphs." unless directed?
|