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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +18 -11
  3. data/CONTRIBUTING.md +2 -2
  4. data/Guardfile +1 -1
  5. data/ISSUE_TEMPLATE.md +15 -0
  6. data/PULL_REQUEST_TEMPLATE.md +12 -0
  7. data/README.md +4 -4
  8. data/RELEASE_POLICY.md +20 -0
  9. data/lib/networkx.rb +37 -1
  10. data/lib/networkx/auxillary_functions/cliques.rb +65 -0
  11. data/lib/networkx/auxillary_functions/cycles.rb +104 -0
  12. data/lib/networkx/auxillary_functions/dag.rb +54 -0
  13. data/lib/networkx/auxillary_functions/eccentricity.rb +36 -0
  14. data/lib/networkx/auxillary_functions/mis.rb +23 -0
  15. data/lib/networkx/auxillary_functions/mst.rb +35 -0
  16. data/lib/networkx/auxillary_functions/union_find.rb +24 -0
  17. data/lib/networkx/auxillary_functions/vitality.rb +13 -0
  18. data/lib/networkx/auxillary_functions/wiener.rb +13 -0
  19. data/lib/networkx/converters/to_csv.rb +47 -0
  20. data/lib/networkx/converters/to_json.rb +39 -0
  21. data/lib/networkx/digraph.rb +228 -0
  22. data/lib/networkx/flow/capacityscaling.rb +255 -0
  23. data/lib/networkx/flow/edmondskarp.rb +113 -0
  24. data/lib/networkx/flow/preflowpush.rb +252 -0
  25. data/lib/networkx/flow/shortestaugmentingpath.rb +157 -0
  26. data/lib/networkx/flow/utils.rb +160 -0
  27. data/lib/networkx/graph.rb +341 -0
  28. data/lib/networkx/link_analysis/hits.rb +59 -0
  29. data/lib/networkx/link_analysis/pagerank.rb +47 -0
  30. data/lib/networkx/multidigraph.rb +240 -0
  31. data/lib/networkx/multigraph.rb +171 -0
  32. data/lib/networkx/operators/all.rb +61 -0
  33. data/lib/networkx/operators/binary.rb +244 -0
  34. data/lib/networkx/operators/product.rb +204 -0
  35. data/lib/networkx/operators/unary.rb +17 -0
  36. data/lib/networkx/shortest_path/astar.rb +71 -0
  37. data/lib/networkx/shortest_path/dense.rb +31 -0
  38. data/lib/networkx/shortest_path/unweighted.rb +139 -0
  39. data/lib/networkx/shortest_path/weighted.rb +408 -0
  40. data/lib/networkx/to_matrix.rb +52 -0
  41. data/lib/networkx/traversals/bfs.rb +58 -0
  42. data/lib/networkx/traversals/dfs.rb +79 -0
  43. data/lib/networkx/traversals/edge_dfs.rb +90 -0
  44. data/lib/networkx/version.rb +1 -1
  45. data/networkx.gemspec +4 -1
  46. 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
@@ -1,3 +1,3 @@
1
1
  module NetworkX
2
- VERSION = '0.1.0'.freeze
2
+ VERSION = '0.1.1'.freeze
3
3
  end
@@ -1,4 +1,4 @@
1
- lib = File.expand_path('../lib', __FILE__)
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.0
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: 2017-11-14 00:00:00.000000000 Z
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: |2
182
- A Ruby implemenation of the well-known graph library called "networkx".
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