networkx 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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