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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3f43ce74dd6bd8fbe91d6b5f29f3b7af355881e9
4
- data.tar.gz: 0275c9f6161b6bcf973af9f18a989969ce757bd0
3
+ metadata.gz: 805b70cf94db86eb3c9e144fe644e6f94f4e664a
4
+ data.tar.gz: 71f71c73039b7b666763268ce87c3780bd9853fb
5
5
  SHA512:
6
- metadata.gz: 17623a41e26fceebed54169c423dbe95a3ee59456a3cc4d3d888e74b70d8e2a58b7329d1565026babdc5196ae37b19422432eaa6e74cce03bbcef21c883c5312
7
- data.tar.gz: 8727b100efab027667eb7c8f3aa13bb3396b56e28a21437b3e21eda904bb99e7ebc9fc35a31451e3661f909faba8c6e57a14c2be1c832100526c1dcfedda4c1e
6
+ metadata.gz: 0f19f6aba21c6c12c7ce027e3067dc00e071235661e8f63287f92dc27ed3e332751cbb3526484e8095520e8d1fd29dfd7672f9fd93b55169372043ed6aa220d0
7
+ data.tar.gz: fe7846c3da4f617441bdb86720861074cb98da48c849b8f3507c867b7dbfee2909d4eb336bc79c904be407b887c8653ef46036d89021e31cdb37ffa7f93b1786
@@ -8,7 +8,7 @@ AllCops:
8
8
  - 'benchmarks/*'
9
9
  - 'profile/*'
10
10
  DisplayCopNames: true
11
- TargetRubyVersion: 2.1
11
+ TargetRubyVersion: 2.2
12
12
 
13
13
  # Preferred codebase style ---------------------------------------------
14
14
 
@@ -52,9 +52,6 @@ Style/EmptyElse:
52
52
  Style/EmptyMethod:
53
53
  EnforcedStyle: compact
54
54
 
55
- Style/FileName:
56
- Enabled: false
57
-
58
55
  Style/FormatString:
59
56
  EnforcedStyle: percent
60
57
 
@@ -73,33 +70,43 @@ Style/Documentation:
73
70
  ### Metrics ------------------------------------------------------------
74
71
 
75
72
  Metrics/AbcSize:
76
- Max: 20
73
+ Enabled: true
77
74
 
78
75
  Metrics/BlockLength:
79
- Exclude:
80
- - 'spec/**/*'
76
+ Enabled: true
81
77
 
82
78
  Metrics/ClassLength:
83
79
  Max: 200
84
80
 
85
81
  Metrics/CyclomaticComplexity:
86
- Max: 7
82
+ Enabled: true
83
+
84
+ Metrics/PerceivedComplexity:
85
+ Enabled: true
86
+
87
+ Metrics/BlockNesting:
88
+ Enabled: true
87
89
 
88
90
  Metrics/LineLength:
89
91
  Max: 120
90
92
 
91
93
  Metrics/MethodLength:
92
- Max: 15
94
+ Enabled: true
93
95
 
94
96
  Metrics/ModuleLength:
95
- Max: 200
97
+ Enabled: true
96
98
 
97
99
  Style/MultilineBlockChain:
98
- Enabled: false
100
+ Enabled: true
99
101
 
100
102
  Metrics/ParameterLists:
101
103
  Max: 10
102
104
 
105
+ ### Naming -------------------------------------------------------------
106
+
107
+ Naming/VariableNumber:
108
+ EnforcedStyle: snake_case
109
+
103
110
  ### RSpec --------------------------------------------------------------
104
111
 
105
112
  RSpec/MessageSpies:
@@ -14,8 +14,8 @@ Please proceed with a Pull Request only after you're assigned. It'd be sad if yo
14
14
  1. Clone this repository and install all the required gem dependencies.
15
15
 
16
16
  ```sh
17
- git clone https://github.com/athityakumar/daru-io.git
18
- cd daru-io
17
+ git clone https://github.com/athityakumar/networkx.rb.git
18
+ cd networkx.rb
19
19
  gem install bundler
20
20
  bundle install
21
21
  ```
data/Guardfile CHANGED
@@ -1,7 +1,7 @@
1
1
  guard :rspec, cmd: 'rspec' do
2
2
  watch(%r{^spec/.+_spec\.rb$})
3
3
  watch(%r{^lib/networkx/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
- watch('spec/spec_helper.rb') { 'spec' }
4
+ watch('spec/spec_helper.rb') { 'spec' }
5
5
  end
6
6
 
7
7
  # TODO: Run Rubocop in the background
@@ -0,0 +1,15 @@
1
+ ### Description
2
+
3
+ Thanks for opening this issue. Add a brief description of what this issue is, and how to recreate it. Do tag the relevant issue(s) and PR(s) below. If required, add the stack trace of the error.
4
+
5
+ - Relevant Issues : (optional)
6
+ - Relevant PRs : (optional)
7
+ - Type of issue :
8
+ - User mode :
9
+ - [ ] Installation
10
+ - [ ] Feature request
11
+ - [ ] Bug in existing feature
12
+ - Developer mode :
13
+ - [ ] Code quality
14
+ - [ ] Tests
15
+ - [ ] Documentation
@@ -0,0 +1,12 @@
1
+ ### Description
2
+
3
+ Thanks for contributing this Pull Request. Add a brief description of what this Pull Request does. Do tag the relevant issue(s) and PR(s) below. If required, add some screenshot(s) to support your changes.
4
+
5
+ - Relevant Issues : (required)
6
+ - Relevant PRs : (optional)
7
+ - Type of change :
8
+ - [ ] New feature
9
+ - [ ] Bug fix for existing feature
10
+ - [ ] Code quality improvement
11
+ - [ ] Addition or Improvement of tests
12
+ - [ ] Addition or Improvement of documentation
data/README.md CHANGED
@@ -13,6 +13,8 @@
13
13
 
14
14
  ### Installing
15
15
 
16
+ [(Back to top)](#list-of-contents)
17
+
16
18
  - Clone the repository with `git clone git@github.com:athityakumar/networkx.rb.git`
17
19
  - Navigate to networkx with `cd networkx.rb`
18
20
  - Install dependencies with `gem install bundler && bundle install`
@@ -30,6 +32,8 @@ g.add_edge('start', 'stop')
30
32
 
31
33
  ### Roadmap
32
34
 
35
+ [(Back to top)](#list-of-contents)
36
+
33
37
  Quite easily, any networkx user would be able to understand the number of details that have been implemented in the Python library. As a humble start towards the release of v0.1.0, the following could be the goals to achieve :
34
38
 
35
39
  - `Node` : This class should be capable of handling different types of nodes (not just `String` / `Integer`). A possible complex use-case could be XML nodes.
@@ -40,10 +44,6 @@ Quite easily, any networkx user would be able to understand the number of detail
40
44
 
41
45
  - `DirectedGraph` : Inherits from `Graph` class. Uses directions between `Edge`s.
42
46
 
43
- [(Back to top)](#list-of-contents)
44
-
45
- After months of extensive searching, we realised there was not a single repository that could guide a newbie to machine learning and natural language processing in Ruby. Thus, after a series of naming discussions, `sciruby-examples` was born.
46
-
47
47
  ### Contributing
48
48
 
49
49
  [(Back to top)](#list-of-contents)
@@ -0,0 +1,20 @@
1
+ # RELEASE POLICY
2
+
3
+ Applicable from networkx v0.0.0 onwards
4
+
5
+ ### Versioning
6
+
7
+ NetworkX follows semantic versioning whereby the version number is always in the form MAJOR.MINOR.PATCH
8
+
9
+ - Patch bump : Bug fixes
10
+ - Minor bump : New features (with backwards compatibility)
11
+ - Major bump : API breaking changes
12
+
13
+ For Major and Minor bumps release candidates should be released around 2 weeks prior to the bump and are indicated by MAJOR.MINOR.0.rc.
14
+
15
+ For more information see the full semantic versioning specification at http://semver.org/.
16
+
17
+ ### Release Timing
18
+
19
+ Patch releases should be done after every fix of a major bug (as tagged in the github issue tracker).
20
+ Major releases should be kept to the minimum.
@@ -1 +1,37 @@
1
- require 'networkx/version'
1
+ require 'set'
2
+ require 'nmatrix'
3
+ require 'rb_heap'
4
+ require 'securerandom'
5
+ require_relative 'networkx/version'
6
+ require_relative 'networkx/graph'
7
+ require_relative 'networkx/digraph'
8
+ require_relative 'networkx/multigraph'
9
+ require_relative 'networkx/multidigraph'
10
+ require_relative 'networkx/traversals/bfs'
11
+ require_relative 'networkx/traversals/dfs'
12
+ require_relative 'networkx/traversals/edge_dfs'
13
+ require_relative 'networkx/shortest_path/unweighted'
14
+ require_relative 'networkx/to_matrix'
15
+ require_relative 'networkx/shortest_path/dense'
16
+ require_relative 'networkx/shortest_path/weighted'
17
+ require_relative 'networkx/shortest_path/astar'
18
+ require_relative 'networkx/operators/product'
19
+ require_relative 'networkx/operators/binary'
20
+ require_relative 'networkx/operators/unary'
21
+ require_relative 'networkx/operators/all'
22
+ require_relative 'networkx/flow/utils'
23
+ require_relative 'networkx/flow/edmondskarp'
24
+ require_relative 'networkx/flow/shortestaugmentingpath'
25
+ require_relative 'networkx/flow/capacityscaling'
26
+ require_relative 'networkx/flow/preflowpush'
27
+ require_relative 'networkx/auxillary_functions/cliques'
28
+ require_relative 'networkx/auxillary_functions/dag'
29
+ require_relative 'networkx/auxillary_functions/eccentricity'
30
+ require_relative 'networkx/auxillary_functions/mis'
31
+ require_relative 'networkx/auxillary_functions/mst'
32
+ require_relative 'networkx/auxillary_functions/union_find'
33
+ require_relative 'networkx/auxillary_functions/vitality'
34
+ require_relative 'networkx/auxillary_functions/wiener'
35
+ require_relative 'networkx/auxillary_functions/cycles'
36
+ require_relative 'networkx/link_analysis/hits'
37
+ require_relative 'networkx/link_analysis/pagerank'
@@ -0,0 +1,65 @@
1
+ module NetworkX
2
+ # TODO: Reduce method complexity and method length
3
+
4
+ # Returns all cliques in the graph
5
+ #
6
+ # @param graph [Graph, MultiGraph] a graph
7
+ #
8
+ # @return [Array<Array<Object>>] Arrays of nodes in the cliques
9
+ def self.find_cliques(graph)
10
+ return nil if graph.nodes.empty?
11
+ q = [nil]
12
+ adj = {}
13
+ graph.nodes.each_key { |u| adj[u] = [] }
14
+ graph.adj.each { |u, u_edges| u_edges.each_key { |v| adj[u] << v if u != v } }
15
+
16
+ subg = graph.nodes.keys
17
+ cand = graph.nodes.keys
18
+ u = subg.max { |n_1, n_2| (cand & adj[n_1]).length <=> (cand & adj[n_2]).length }
19
+ ext_u = cand - adj[u]
20
+ stack = []
21
+ cliques = []
22
+ begin
23
+ loop do
24
+ if !ext_u.empty?
25
+ q_elem = ext_u.pop
26
+ cand.delete(q_elem)
27
+ q[-1] = q_elem
28
+ adj_q = adj[q_elem]
29
+ subg_q = subg & adj_q
30
+ if subg_q.empty?
31
+ cliques << q[0..(q.length - 1)]
32
+ else
33
+ cand_q = cand & adj_q
34
+ unless cand_q.empty?
35
+ stack << [subg, cand, ext_u]
36
+ q << nil
37
+ subg = subg_q
38
+ cand = cand_q
39
+ u = subg.max { |n_1, n_2| (cand & adj[n_1]).length <=> (cand & adj[n_2]).length }
40
+ ext_u = cand - adj[u]
41
+ end
42
+ end
43
+ else
44
+ q.pop
45
+ subg, cand, ext_u = stack.pop
46
+ end
47
+ end
48
+ rescue NoMethodError
49
+ return cliques
50
+ end
51
+ end
52
+
53
+ # Returns the number of cliques in a graph containing a node
54
+ #
55
+ # @param graph [Graph, MultiGraph] a graph
56
+ # @param node [Object] a node
57
+ #
58
+ # @return [Numeric] Number of cliques containing the given node
59
+ def self.number_of_cliques(graph, node)
60
+ cliques = find_cliques(graph)
61
+ num_cliq_arr = []
62
+ cliques.each { |c| num_cliq_arr << 1 if c.include?(node) }
63
+ num_cliq_arr.length
64
+ end
65
+ end
@@ -0,0 +1,104 @@
1
+ module NetworkX
2
+ # TODO: Reduce method complexity and method length
3
+
4
+ # Returns all basis cycles in graph
5
+ #
6
+ # @param graph [Graph] a graph
7
+ # @param root [Object, Nil] root for the graph cycles
8
+ #
9
+ # @return [Array<Array<Object>>] Arrays of nodes in the cycles
10
+ def self.cycle_basis(graph, root=nil)
11
+ gnodes = graph.nodes.keys
12
+ cycles = []
13
+ until gnodes.empty?
14
+ root = gnodes.shift if root.nil?
15
+ stack = [root]
16
+ pred = {root => root}
17
+ used = {root => []}
18
+ until stack.empty?
19
+ z = stack.shift
20
+ zused = used[z]
21
+ graph.adj[z].each_key do |u|
22
+ if !used.key?(u)
23
+ pred[u] = z
24
+ stack << u
25
+ used[u] = [z]
26
+ elsif u == z
27
+ cycles << [z]
28
+ elsif !zused.include?(u)
29
+ pn = used[u]
30
+ cycle = [u, z]
31
+ p = pred[z]
32
+ until pn.include?(p)
33
+ cycle << p
34
+ p = pred[p]
35
+ end
36
+ cycle << p
37
+ cycles << cycle
38
+ used[u] << z
39
+ used[u] = used[u].uniq
40
+ end
41
+ end
42
+ end
43
+ gnodes -= pred.keys
44
+ root = nil
45
+ end
46
+ cycles
47
+ end
48
+
49
+ # TODO: Reduce method complexity and method length
50
+
51
+ # Returns the cycle containing the given node
52
+ #
53
+ # @param graph [Graph, DiGraph] a graph
54
+ # @param node [Object] node to be included in the cycle
55
+ #
56
+ # @return [Array<Array<Object>>] Arrays of nodes in the cycle
57
+ def self.find_cycle(graph, node)
58
+ explored = Set.new
59
+ cycle = []
60
+ final_node = nil
61
+ unless explored.include?(node)
62
+ edges = []
63
+ seen = [node]
64
+ active_nodes = [node]
65
+ previous_head = nil
66
+
67
+ edge_dfs(graph, node).each do |edge|
68
+ tail, head = edge
69
+ next if explored.include?(head)
70
+ if !previous_head.nil? && tail != previous_head
71
+ loop do
72
+ popped_edge = edges.pop
73
+ if popped_edge.nil?
74
+ edges = []
75
+ active_nodes = [tail]
76
+ break
77
+ else
78
+ popped_head = popped_edge[1]
79
+ active_nodes.delete!(popped_head)
80
+ end
81
+
82
+ unless edges.empty?
83
+ last_head = edges[-1][1]
84
+ break if tail == last_head
85
+ end
86
+ end
87
+ end
88
+ edges << edge
89
+
90
+ if active_nodes.include?(head)
91
+ cycle += edges
92
+ final_node = head
93
+ break
94
+ else
95
+ seen << head
96
+ active_nodes << head
97
+ previous_head = head
98
+ end
99
+ end
100
+ cycle.each_with_index { |edge, i| return cycle[i..(cycle.length - 1)] if final_node == edge[0] }
101
+ end
102
+ raise ArgumentError, 'No cycle found!' if cycle.empty?
103
+ end
104
+ end
@@ -0,0 +1,54 @@
1
+ module NetworkX
2
+ # Returns the descendants of a given node
3
+ #
4
+ # @param graph [Graph, DiGraph, MultiGraph, MultiDiGraph] a graph
5
+ # @param source [Object] node to find descendents of
6
+ #
7
+ # @return [Array<Object>] Array of the descendants
8
+ def self.descendants(graph, source)
9
+ raise ArgumentError, 'Source is not present in the graph!' unless graph.node?(source)
10
+ des = single_source_shortest_path_length(graph, source).map { |u, _| u }.uniq
11
+ des - [source]
12
+ end
13
+
14
+ # Returns the ancestors of a given node
15
+ #
16
+ # @param graph [Graph, DiGraph, MultiGraph, MultiDiGraph] a graph
17
+ # @param source [Object] node to find ancestors of
18
+ #
19
+ # @return [Array<Object>] Array of the ancestors
20
+ def self.ancestors(graph, source)
21
+ raise ArgumentError, 'Source is not present in the graph!' unless graph.node?(source)
22
+ anc = single_source_shortest_path_length(graph.reverse, source).map { |u, _| u }.uniq
23
+ anc - [source]
24
+ end
25
+
26
+ # TODO: Reduce method complexity and method length
27
+
28
+ # Returns the nodes arranged in the topologically sorted fashion
29
+ #
30
+ # @param graph [DiGraph] a graph
31
+ #
32
+ # @return [Array<Object>] Array of the nodes
33
+ def self.topological_sort(graph)
34
+ raise ArgumentError, 'Topological Sort not defined on undirected graphs!' unless graph.directed?
35
+ nodes = []
36
+ indegree_map = Hash[graph.nodes.each_key.map { |u| [u, graph.in_degree(u)] if graph.in_degree(u) > 0 }.compact]
37
+ zero_indegree = graph.nodes.each_key.map { |u| u if graph.in_degree(u).zero? }.compact
38
+
39
+ until zero_indegree.empty?
40
+ node = zero_indegree.shift
41
+ raise ArgumentError, 'Graph changed during iteration!' unless graph.nodes.key?(node)
42
+ graph.adj[node].each_key do |child|
43
+ indegree_map[child] -= 1
44
+ if indegree_map[child].zero?
45
+ zero_indegree << child
46
+ indegree_map.delete(child)
47
+ end
48
+ end
49
+ nodes << node
50
+ end
51
+ raise ArgumentError, 'Graph contains cycle or graph changed during iteration!' unless indegree_map.empty?
52
+ nodes
53
+ end
54
+ end