networkx 0.1.0 → 0.1.1
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/.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
|