networkx 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +18 -11
- data/CONTRIBUTING.md +2 -2
- data/Guardfile +1 -1
- data/ISSUE_TEMPLATE.md +15 -0
- data/PULL_REQUEST_TEMPLATE.md +12 -0
- data/README.md +4 -4
- data/RELEASE_POLICY.md +20 -0
- data/lib/networkx.rb +37 -1
- data/lib/networkx/auxillary_functions/cliques.rb +65 -0
- data/lib/networkx/auxillary_functions/cycles.rb +104 -0
- data/lib/networkx/auxillary_functions/dag.rb +54 -0
- data/lib/networkx/auxillary_functions/eccentricity.rb +36 -0
- data/lib/networkx/auxillary_functions/mis.rb +23 -0
- data/lib/networkx/auxillary_functions/mst.rb +35 -0
- data/lib/networkx/auxillary_functions/union_find.rb +24 -0
- data/lib/networkx/auxillary_functions/vitality.rb +13 -0
- data/lib/networkx/auxillary_functions/wiener.rb +13 -0
- data/lib/networkx/converters/to_csv.rb +47 -0
- data/lib/networkx/converters/to_json.rb +39 -0
- data/lib/networkx/digraph.rb +228 -0
- data/lib/networkx/flow/capacityscaling.rb +255 -0
- data/lib/networkx/flow/edmondskarp.rb +113 -0
- data/lib/networkx/flow/preflowpush.rb +252 -0
- data/lib/networkx/flow/shortestaugmentingpath.rb +157 -0
- data/lib/networkx/flow/utils.rb +160 -0
- data/lib/networkx/graph.rb +341 -0
- data/lib/networkx/link_analysis/hits.rb +59 -0
- data/lib/networkx/link_analysis/pagerank.rb +47 -0
- data/lib/networkx/multidigraph.rb +240 -0
- data/lib/networkx/multigraph.rb +171 -0
- data/lib/networkx/operators/all.rb +61 -0
- data/lib/networkx/operators/binary.rb +244 -0
- data/lib/networkx/operators/product.rb +204 -0
- data/lib/networkx/operators/unary.rb +17 -0
- data/lib/networkx/shortest_path/astar.rb +71 -0
- data/lib/networkx/shortest_path/dense.rb +31 -0
- data/lib/networkx/shortest_path/unweighted.rb +139 -0
- data/lib/networkx/shortest_path/weighted.rb +408 -0
- data/lib/networkx/to_matrix.rb +52 -0
- data/lib/networkx/traversals/bfs.rb +58 -0
- data/lib/networkx/traversals/dfs.rb +79 -0
- data/lib/networkx/traversals/edge_dfs.rb +90 -0
- data/lib/networkx/version.rb +1 -1
- data/networkx.gemspec +4 -1
- metadata +70 -4
@@ -0,0 +1,52 @@
|
|
1
|
+
module NetworkX
|
2
|
+
# TODO: Reduce condition branches and method length
|
3
|
+
def self.to_matrix(graph, val, multigraph_weight='sum')
|
4
|
+
is_undirected = !graph.directed?
|
5
|
+
is_multigraph = graph.multigraph?
|
6
|
+
nodelen = graph.nodes.length
|
7
|
+
|
8
|
+
m = NMatrix.new(nodelen, val)
|
9
|
+
index = {}
|
10
|
+
inv_index = {}
|
11
|
+
ind = 0
|
12
|
+
|
13
|
+
graph.nodes.each do |u, _|
|
14
|
+
index[u] = ind
|
15
|
+
inv_index[ind] = u
|
16
|
+
ind += 1
|
17
|
+
end
|
18
|
+
|
19
|
+
if is_multigraph
|
20
|
+
graph.adj.each do |u, edge_hash|
|
21
|
+
edge_hash.each do |v, keys|
|
22
|
+
all_weights = []
|
23
|
+
keys.each do |_key, attrs|
|
24
|
+
all_weights << attrs[:weight]
|
25
|
+
end
|
26
|
+
|
27
|
+
edge_attr = 0
|
28
|
+
|
29
|
+
case multigraph_weight
|
30
|
+
when 'sum'
|
31
|
+
edge_attr = all_weights.inject(0, :+)
|
32
|
+
when 'max'
|
33
|
+
edge_attr = all_weights.max
|
34
|
+
when 'min'
|
35
|
+
edge_attr = all_weights.min
|
36
|
+
end
|
37
|
+
|
38
|
+
m[index[u], index[v]] = edge_attr
|
39
|
+
m[index[v], index[u]] = edge_attr || 1 if is_undirected
|
40
|
+
end
|
41
|
+
end
|
42
|
+
else
|
43
|
+
graph.adj.each do |u, edge_hash|
|
44
|
+
edge_hash.each do |v, attrs|
|
45
|
+
m[index[u], index[v]] = (attrs[:weight] || 1)
|
46
|
+
m[index[v], index[u]] = (attrs[:weight] || 1) if is_undirected
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
[m, inv_index]
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module NetworkX
|
2
|
+
# TODO: Reduce method length
|
3
|
+
|
4
|
+
# Returns edges of the graph travelled in breadth first fashion
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# NetworkX.bfs_edges(graph, source)
|
8
|
+
#
|
9
|
+
# @param graph [Graph, DiGraph, MultiGraph, MultiDiGraph] a graph
|
10
|
+
# @param source [Object] node to start bfs from
|
11
|
+
def self.bfs_edges(graph, source)
|
12
|
+
raise KeyError, "There exists no node names #{source} in the given graph." unless graph.node?(source)
|
13
|
+
bfs_edges = []
|
14
|
+
visited = [source]
|
15
|
+
queue = Queue.new.push([source, graph.neighbours(source)])
|
16
|
+
until queue.empty?
|
17
|
+
parent, children = queue.pop
|
18
|
+
children.each_key do |child|
|
19
|
+
next if visited.include?(child)
|
20
|
+
bfs_edges << [parent, child]
|
21
|
+
visited << child
|
22
|
+
queue.push([child, graph.neighbours(child)])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
bfs_edges
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns parent successor pair of the graph travelled in breadth first fashion
|
29
|
+
#
|
30
|
+
# @example
|
31
|
+
# NetworkX.bfs_successors(graph, source)
|
32
|
+
#
|
33
|
+
# @param graph [Graph, DiGraph, MultiGraph, MultiDiGraph] a graph
|
34
|
+
# @param source [Object] node to start bfs from
|
35
|
+
def self.bfs_successors(graph, source)
|
36
|
+
bfs_edges = bfs_edges(graph, source)
|
37
|
+
successors = {}
|
38
|
+
bfs_edges.each do |u, v|
|
39
|
+
successors[u] = [] if successors[u].nil?
|
40
|
+
successors[u] << v
|
41
|
+
end
|
42
|
+
successors
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns predecessor child pair of the graph travelled in breadth first fashion
|
46
|
+
#
|
47
|
+
# @example
|
48
|
+
# NetworkX.bfs_predecessors(graph, source)
|
49
|
+
#
|
50
|
+
# @param graph [Graph, DiGraph, MultiGraph, MultiDiGraph] a graph
|
51
|
+
# @param source [Object] node to start bfs from
|
52
|
+
def self.bfs_predecessors(graph, source)
|
53
|
+
bfs_edges = bfs_edges(graph, source)
|
54
|
+
predecessors = {}
|
55
|
+
bfs_edges.each { |u, v| predecessors[v] = u }
|
56
|
+
predecessors
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module NetworkX
|
2
|
+
# TODO: Reduce method complexity and method length
|
3
|
+
|
4
|
+
# Returns edges of the graph travelled in depth first fashion
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# NetworkX.dfs_edges(graph, source)
|
8
|
+
#
|
9
|
+
# @param graph [Graph, DiGraph, MultiGraph, MultiDiGraph] a graph
|
10
|
+
# @param source [Object] node to start dfs from
|
11
|
+
# @param depth_limit [Integer, nil] the depth limit of dfs
|
12
|
+
def self.dfs_edges(graph, source, depth_limit=nil)
|
13
|
+
raise KeyError, "There exists no node names #{source} in the given graph." unless graph.node?(source)
|
14
|
+
depth_limit = graph.nodes.length if depth_limit.nil?
|
15
|
+
dfs_edges = []
|
16
|
+
visited = [source]
|
17
|
+
stack = [[-1, source, depth_limit, graph.neighbours(source)]]
|
18
|
+
until stack.empty?
|
19
|
+
earlier_node, parent, depth_now, children = stack.pop
|
20
|
+
dfs_edges << [earlier_node, parent]
|
21
|
+
children.each_key do |child|
|
22
|
+
unless visited.include?(child)
|
23
|
+
visited << child
|
24
|
+
stack.push([parent, child, depth_now - 1, graph.neighbours(child)]) if depth_now > 1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
dfs_edges.shift
|
29
|
+
dfs_edges
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns dfs tree of the graph
|
33
|
+
#
|
34
|
+
# @example
|
35
|
+
# NetworkX.dfs_tree(graph, source)
|
36
|
+
#
|
37
|
+
# @param graph [Graph, DiGraph, MultiGraph, MultiDiGraph] a graph
|
38
|
+
# @param source [Object] node to start dfs from
|
39
|
+
# @param depth_limit [Integer, nil] the depth limit of dfs
|
40
|
+
def self.dfs_tree(graph, source, depth_limit=nil)
|
41
|
+
t = NetworkX::DiGraph.new
|
42
|
+
t.add_node(source)
|
43
|
+
t.add_edges_from(dfs_edges(graph, source, depth_limit))
|
44
|
+
t
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns parent successor pair of the graph travelled in depth first fashion
|
48
|
+
#
|
49
|
+
# @example
|
50
|
+
# NetworkX.dfs_successors(graph, source)
|
51
|
+
#
|
52
|
+
# @param graph [Graph, DiGraph, MultiGraph, MultiDiGraph] a graph
|
53
|
+
# @param source [Object] node to start dfs from
|
54
|
+
# @param depth_limit [Integer, nil] the depth limit of dfs
|
55
|
+
def self.dfs_successors(graph, source, depth_limit=nil)
|
56
|
+
dfs_edges = dfs_edges(graph, source, depth_limit)
|
57
|
+
successors = {}
|
58
|
+
dfs_edges.each do |u, v|
|
59
|
+
successors[u] = [] if successors[u].nil?
|
60
|
+
successors[u] << v
|
61
|
+
end
|
62
|
+
successors
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns predecessor child pair of the graph travelled in depth first fashion
|
66
|
+
#
|
67
|
+
# @example
|
68
|
+
# NetworkX.dfs_predecessors(graph, source)
|
69
|
+
#
|
70
|
+
# @param graph [Graph, DiGraph, MultiGraph, MultiDiGraph] a graph
|
71
|
+
# @param source [Object] node to start dfs from
|
72
|
+
# @param depth_limit [Integer, nil] the depth limit of dfs
|
73
|
+
def self.dfs_predecessors(graph, source, depth_limit=nil)
|
74
|
+
dfs_edges = dfs_edges(graph, source, depth_limit)
|
75
|
+
predecessors = {}
|
76
|
+
dfs_edges.each { |u, v| predecessors[v] = u }
|
77
|
+
predecessors
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module NetworkX
|
2
|
+
# TODO: Reduce method complexity and method length
|
3
|
+
|
4
|
+
# Helper function for edge_dfs
|
5
|
+
#
|
6
|
+
# @param graph [Graph, DiGraph, MultiGraph, MultiDiGraph] a graph
|
7
|
+
# @param node [Object] a node in the graph
|
8
|
+
def self.out_edges(graph, node)
|
9
|
+
edges = []
|
10
|
+
visited = {}
|
11
|
+
case graph.class.name
|
12
|
+
when 'NetworkX::Graph', 'NetworkX::DiGraph'
|
13
|
+
graph.adj[node].each do |v, _|
|
14
|
+
if graph.class.name == 'NetworkX::DiGraph' || visited[[v, node]].nil?
|
15
|
+
visited[[node, v]] = true
|
16
|
+
edges << [node, v]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
else
|
20
|
+
graph.adj[node].each do |v, uv_keys|
|
21
|
+
uv_keys.each_key do |k|
|
22
|
+
if graph.class.name == 'NetworkX::MultiDiGraph' || visited[[v, node, k]].nil?
|
23
|
+
visited[[node, v, k]] = true
|
24
|
+
edges << [node, v, k]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
edges
|
30
|
+
end
|
31
|
+
|
32
|
+
# Helper function of edge_dfs
|
33
|
+
def self.edge_id(graph, edge)
|
34
|
+
return edge if graph.directed?
|
35
|
+
return Set.new([edge, (edge[0..1].reverse + edge[2])]) if graph.multigraph?
|
36
|
+
Set.new([edge, edge.reverse])
|
37
|
+
end
|
38
|
+
|
39
|
+
# TODO: Reduce method complexity and method length
|
40
|
+
|
41
|
+
# Performs edge dfs on the graph
|
42
|
+
# Orientation :ignore, directed edges can be
|
43
|
+
# travelled in both fashions
|
44
|
+
# Orientation reverse, directed edges can be travelled
|
45
|
+
# in reverse fashion
|
46
|
+
# Orientation :nil, the graph is not meddled with
|
47
|
+
#
|
48
|
+
# @example
|
49
|
+
# NetworkX.edge_dfs(graph, source, 'ignore')
|
50
|
+
#
|
51
|
+
# @param graph [Graph, DiGraph, MultiGraph, MultiDiGraph] a graph
|
52
|
+
# @param source [Object] node to start dfs from
|
53
|
+
# @param orientation [:ignore, :reverse', nil] the orientation of edges of graph
|
54
|
+
def self.edge_dfs(graph, start, orientation=nil)
|
55
|
+
case orientation
|
56
|
+
when :reverse
|
57
|
+
graph = graph.reverse if graph.class.name == 'NetworkX::DiGraph' || graph.class.name == 'NetworkX::MultiDiGraph'
|
58
|
+
when :ignore
|
59
|
+
graph = graph.to_undirected if graph.class.name == 'NetworkX::DiGraph'
|
60
|
+
graph = graph.to_multigraph if graph.class.name == 'NetworkX::MultiDiGraph'
|
61
|
+
end
|
62
|
+
|
63
|
+
visited_edges = []
|
64
|
+
visited_nodes = []
|
65
|
+
stack = [start]
|
66
|
+
current_edges = {}
|
67
|
+
|
68
|
+
e = Enumerator.new do |yield_var|
|
69
|
+
until stack.empty?
|
70
|
+
current = stack.last
|
71
|
+
unless visited_nodes.include?(current)
|
72
|
+
current_edges[current] = out_edges(graph, current)
|
73
|
+
visited_nodes << current
|
74
|
+
end
|
75
|
+
|
76
|
+
edge = current_edges[current].shift
|
77
|
+
if edge.nil?
|
78
|
+
stack.pop
|
79
|
+
else
|
80
|
+
unless visited_edges.include?(edge_id(graph, edge))
|
81
|
+
visited_edges << edge_id(graph, edge)
|
82
|
+
stack << edge[1]
|
83
|
+
yield_var.yield edge
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
e.take(graph.number_of_edges)
|
89
|
+
end
|
90
|
+
end
|
data/lib/networkx/version.rb
CHANGED
data/networkx.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
lib = File.expand_path('
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
3
|
require 'networkx/version'
|
4
4
|
|
@@ -31,5 +31,8 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_development_dependency 'saharspec'
|
32
32
|
spec.add_development_dependency 'simplecov'
|
33
33
|
spec.add_development_dependency 'yard'
|
34
|
+
spec.add_runtime_dependency 'nmatrix'
|
35
|
+
spec.add_runtime_dependency 'rb_heap'
|
36
|
+
|
34
37
|
spec.add_development_dependency 'guard-rspec' if RUBY_VERSION >= '2.2.5'
|
35
38
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: networkx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Athitya Kumar
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-02-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -164,6 +164,34 @@ dependencies:
|
|
164
164
|
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: nmatrix
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: rb_heap
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :runtime
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
167
195
|
- !ruby/object:Gem::Dependency
|
168
196
|
name: guard-rspec
|
169
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -178,8 +206,9 @@ dependencies:
|
|
178
206
|
- - ">="
|
179
207
|
- !ruby/object:Gem::Version
|
180
208
|
version: '0'
|
181
|
-
description:
|
182
|
-
|
209
|
+
description: ' A Ruby implemenation of the well-known graph library called "networkx".
|
210
|
+
|
211
|
+
'
|
183
212
|
email:
|
184
213
|
- athityakumar@gmail.com
|
185
214
|
executables: []
|
@@ -196,10 +225,47 @@ files:
|
|
196
225
|
- CONTRIBUTING.md
|
197
226
|
- Gemfile
|
198
227
|
- Guardfile
|
228
|
+
- ISSUE_TEMPLATE.md
|
199
229
|
- LICENSE.md
|
230
|
+
- PULL_REQUEST_TEMPLATE.md
|
200
231
|
- README.md
|
232
|
+
- RELEASE_POLICY.md
|
201
233
|
- Rakefile
|
202
234
|
- lib/networkx.rb
|
235
|
+
- lib/networkx/auxillary_functions/cliques.rb
|
236
|
+
- lib/networkx/auxillary_functions/cycles.rb
|
237
|
+
- lib/networkx/auxillary_functions/dag.rb
|
238
|
+
- lib/networkx/auxillary_functions/eccentricity.rb
|
239
|
+
- lib/networkx/auxillary_functions/mis.rb
|
240
|
+
- lib/networkx/auxillary_functions/mst.rb
|
241
|
+
- lib/networkx/auxillary_functions/union_find.rb
|
242
|
+
- lib/networkx/auxillary_functions/vitality.rb
|
243
|
+
- lib/networkx/auxillary_functions/wiener.rb
|
244
|
+
- lib/networkx/converters/to_csv.rb
|
245
|
+
- lib/networkx/converters/to_json.rb
|
246
|
+
- lib/networkx/digraph.rb
|
247
|
+
- lib/networkx/flow/capacityscaling.rb
|
248
|
+
- lib/networkx/flow/edmondskarp.rb
|
249
|
+
- lib/networkx/flow/preflowpush.rb
|
250
|
+
- lib/networkx/flow/shortestaugmentingpath.rb
|
251
|
+
- lib/networkx/flow/utils.rb
|
252
|
+
- lib/networkx/graph.rb
|
253
|
+
- lib/networkx/link_analysis/hits.rb
|
254
|
+
- lib/networkx/link_analysis/pagerank.rb
|
255
|
+
- lib/networkx/multidigraph.rb
|
256
|
+
- lib/networkx/multigraph.rb
|
257
|
+
- lib/networkx/operators/all.rb
|
258
|
+
- lib/networkx/operators/binary.rb
|
259
|
+
- lib/networkx/operators/product.rb
|
260
|
+
- lib/networkx/operators/unary.rb
|
261
|
+
- lib/networkx/shortest_path/astar.rb
|
262
|
+
- lib/networkx/shortest_path/dense.rb
|
263
|
+
- lib/networkx/shortest_path/unweighted.rb
|
264
|
+
- lib/networkx/shortest_path/weighted.rb
|
265
|
+
- lib/networkx/to_matrix.rb
|
266
|
+
- lib/networkx/traversals/bfs.rb
|
267
|
+
- lib/networkx/traversals/dfs.rb
|
268
|
+
- lib/networkx/traversals/edge_dfs.rb
|
203
269
|
- lib/networkx/version.rb
|
204
270
|
- networkx.gemspec
|
205
271
|
homepage: https://github.com/athityakumar/networkx.rb
|