networkx 0.1.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/{CODE_OF_CONDUCT.md → .github/CODE_OF_CONDUCT.md} +0 -0
  3. data/{CONTRIBUTING.md → .github/CONTRIBUTING.md} +20 -10
  4. data/{ISSUE_TEMPLATE.md → .github/ISSUE_TEMPLATE.md} +1 -1
  5. data/{PULL_REQUEST_TEMPLATE.md → .github/PULL_REQUEST_TEMPLATE.md} +2 -4
  6. data/.github/workflows/ci.yml +17 -0
  7. data/.github/workflows/doc.yml +23 -0
  8. data/.rspec +0 -1
  9. data/.rubocop.yml +57 -71
  10. data/.yardopts +0 -1
  11. data/README.md +32 -34
  12. data/Rakefile +2 -3
  13. data/lib/networkx/auxillary_functions/cliques.rb +9 -12
  14. data/lib/networkx/auxillary_functions/cycles.rb +17 -7
  15. data/lib/networkx/auxillary_functions/dag.rb +10 -5
  16. data/lib/networkx/auxillary_functions/eccentricity.rb +2 -1
  17. data/lib/networkx/auxillary_functions/mis.rb +2 -2
  18. data/lib/networkx/auxillary_functions/mst.rb +1 -3
  19. data/lib/networkx/auxillary_functions/union_find.rb +92 -12
  20. data/lib/networkx/auxillary_functions/wiener.rb +1 -1
  21. data/lib/networkx/converters/to_csv.rb +1 -3
  22. data/lib/networkx/converters/to_json.rb +0 -2
  23. data/lib/networkx/digraph.rb +55 -49
  24. data/lib/networkx/flow/capacityscaling.rb +29 -35
  25. data/lib/networkx/flow/edmondskarp.rb +17 -15
  26. data/lib/networkx/flow/preflowpush.rb +29 -32
  27. data/lib/networkx/flow/shortestaugmentingpath.rb +17 -20
  28. data/lib/networkx/flow/utils.rb +6 -27
  29. data/lib/networkx/graph.rb +179 -72
  30. data/lib/networkx/link_analysis/hits.rb +9 -9
  31. data/lib/networkx/link_analysis/pagerank.rb +29 -31
  32. data/lib/networkx/multidigraph.rb +90 -81
  33. data/lib/networkx/multigraph.rb +91 -63
  34. data/lib/networkx/operators/all.rb +8 -4
  35. data/lib/networkx/operators/binary.rb +106 -128
  36. data/lib/networkx/operators/product.rb +61 -64
  37. data/lib/networkx/operators/unary.rb +1 -1
  38. data/lib/networkx/others/bridges.rb +30 -0
  39. data/lib/networkx/others/generators.rb +237 -0
  40. data/lib/networkx/others/grid_2d_graph.rb +38 -0
  41. data/lib/networkx/others/info.rb +11 -0
  42. data/lib/networkx/others/number_connected_components.rb +17 -0
  43. data/lib/networkx/others/reads.rb +52 -0
  44. data/lib/networkx/shortest_path/astar.rb +10 -8
  45. data/lib/networkx/shortest_path/dense.rb +1 -3
  46. data/lib/networkx/shortest_path/unweighted.rb +13 -16
  47. data/lib/networkx/shortest_path/weighted.rb +51 -42
  48. data/lib/networkx/to_matrix.rb +2 -3
  49. data/lib/networkx/traversals/bfs.rb +54 -2
  50. data/lib/networkx/traversals/dfs.rb +62 -6
  51. data/lib/networkx/traversals/edge_dfs.rb +36 -12
  52. data/lib/networkx/version.rb +1 -1
  53. data/lib/networkx.rb +7 -1
  54. data/networkx.gemspec +17 -14
  55. metadata +74 -84
  56. data/.rspec_formatter.rb +0 -24
  57. data/.travis.yml +0 -18
  58. data/Guardfile +0 -7
  59. data/RELEASE_POLICY.md +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 805b70cf94db86eb3c9e144fe644e6f94f4e664a
4
- data.tar.gz: 71f71c73039b7b666763268ce87c3780bd9853fb
2
+ SHA256:
3
+ metadata.gz: 39e75c0ad21604275a008c53a29f282d681f3c50cb7648470cc6e4e2cffa5071
4
+ data.tar.gz: 93e93f5a2603beb715b38856518ed47e698c0978c5ff02a737a7baff68357e8c
5
5
  SHA512:
6
- metadata.gz: 0f19f6aba21c6c12c7ce027e3067dc00e071235661e8f63287f92dc27ed3e332751cbb3526484e8095520e8d1fd29dfd7672f9fd93b55169372043ed6aa220d0
7
- data.tar.gz: fe7846c3da4f617441bdb86720861074cb98da48c849b8f3507c867b7dbfee2909d4eb336bc79c904be407b887c8653ef46036d89021e31cdb37ffa7f93b1786
6
+ metadata.gz: 1ce185b8e9246db7b791d4d1800b39d1ad9a5f1036c99899842554c31e2400469d775acd382c2dfc27275857db58e66228062502bffefb16ddca4c3a63b346fe
7
+ data.tar.gz: 9b615db49ec2ba5e06bbfecf1710849d079661b301a85493740434eae464bfd74c250c38c31ed2cc5dfb93983cb2c7315fe27452c2f6a243051ac1f80512816b
File without changes
@@ -11,10 +11,10 @@ Please proceed with a Pull Request only after you're assigned. It'd be sad if yo
11
11
 
12
12
  # Developing the gem
13
13
 
14
- 1. Clone this repository and install all the required gem dependencies.
14
+ 1. Fork this repository and clone it and install all the required gem dependencies.
15
15
 
16
16
  ```sh
17
- git clone https://github.com/athityakumar/networkx.rb.git
17
+ git clone https://github.com/`your_github_user_id`/networkx.rb.git
18
18
  cd networkx.rb
19
19
  gem install bundler
20
20
  bundle install
@@ -22,13 +22,9 @@ Please proceed with a Pull Request only after you're assigned. It'd be sad if yo
22
22
 
23
23
  2. Checkout to a different git branch (say, `adds-new-feature`).
24
24
 
25
- 3. Add any gem dependencies required, appropriately to the gemspec file or Gemfile.
25
+ 3. Add code (, test, and YARD documentation).
26
26
 
27
- 4. Add code and YARD documentation.
28
-
29
- 5. Add tests to `spec/networkx/filename_spec.rb`. Add any files required for testing in the `spec/fixtures/` directory.
30
-
31
- 6. Run the rspec test-suite.
27
+ 4. Run the rspec test-suite.
32
28
  ```sh
33
29
  # Runs test suite for all files
34
30
  bundle exec rspec
@@ -37,7 +33,7 @@ Please proceed with a Pull Request only after you're assigned. It'd be sad if yo
37
33
  bundle exec rspec spec/networkx/filename_spec.rb
38
34
  ```
39
35
 
40
- 7. Run the rubocop for static code quality comments.
36
+ 5. Run the rubocop for static code quality comments.
41
37
 
42
38
  ```sh
43
39
  # Runs rubocop test for all files
@@ -47,4 +43,18 @@ Please proceed with a Pull Request only after you're assigned. It'd be sad if yo
47
43
  bundle exec rubocop lib/networkx/filename.rb
48
44
  ```
49
45
 
50
- 8. Send a Pull Request back to this repository. :tada:
46
+ 6. Send a Pull Request back to this repository. :tada:
47
+
48
+ # Note: YARD Document
49
+
50
+ You can create YARD documentation
51
+
52
+ 1. Create Document for `doc` directory with `yard` command
53
+ 2. Create server via `yard server` command
54
+ 3. open Browser with `open http://0.0.0.0:8808` e.t.c.
55
+
56
+ ```
57
+ $ yard
58
+ $ yard server
59
+ $ open http://0.0.0.0:8808
60
+ ```
@@ -12,4 +12,4 @@ Thanks for opening this issue. Add a brief description of what this issue is, an
12
12
  - Developer mode :
13
13
  - [ ] Code quality
14
14
  - [ ] Tests
15
- - [ ] Documentation
15
+ - [ ] Documentation
@@ -1,12 +1,10 @@
1
- ### Description
2
-
3
1
  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
2
 
5
- - Relevant Issues : (required)
3
+ - Relevant Issues : (optional)
6
4
  - Relevant PRs : (optional)
7
5
  - Type of change :
8
6
  - [ ] New feature
9
7
  - [ ] Bug fix for existing feature
10
8
  - [ ] Code quality improvement
11
9
  - [ ] Addition or Improvement of tests
12
- - [ ] Addition or Improvement of documentation
10
+ - [ ] Addition or Improvement of documentation
@@ -0,0 +1,17 @@
1
+ name: test
2
+ on: [push, pull_request]
3
+ jobs:
4
+ build:
5
+ name: ${{ matrix.os }} Ruby ${{ matrix.ruby }}
6
+ runs-on: ${{ matrix.os }}-latest
7
+ strategy:
8
+ matrix:
9
+ os: [ 'ubuntu', 'macos' ]
10
+ ruby: [ '2.7', '3.0', '3.1' ]
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ - uses: ruby/setup-ruby@v1
14
+ with:
15
+ ruby-version: ${{ matrix.ruby }}
16
+ bundler-cache: true
17
+ - run: bundle exec rspec
@@ -0,0 +1,23 @@
1
+ name: doc
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - uses: actions/checkout@v3
14
+ - uses: ruby/setup-ruby@v1
15
+ with:
16
+ ruby-version: 3.1
17
+ - name: Generate document
18
+ run: gem install -N yard && yard doc
19
+ - name: Publish Documentation on GitHub Pages
20
+ uses: peaceiris/actions-gh-pages@v3
21
+ with:
22
+ github_token: ${{ secrets.GITHUB_TOKEN }}
23
+ publish_dir: ./doc
data/.rspec CHANGED
@@ -1,2 +1 @@
1
- --color
2
1
  --require spec_helper
data/.rubocop.yml CHANGED
@@ -1,116 +1,102 @@
1
- require: rubocop-rspec
2
-
3
1
  AllCops:
2
+ NewCops: enable
3
+ TargetRubyVersion: 2.7
4
4
  Include:
5
5
  - 'lib/**/*'
6
- Exclude:
7
- - 'vendor/**/*'
8
- - 'benchmarks/*'
9
- - 'profile/*'
6
+ - 'spec/**/*_spec.rb'
7
+ - 'Gemfile'
8
+ - 'Rakefile'
9
+ - '*.gemspec'
10
10
  DisplayCopNames: true
11
- TargetRubyVersion: 2.2
12
11
 
13
- # Preferred codebase style ---------------------------------------------
12
+ require:
13
+ - rubocop-rspec
14
+ - rubocop-rake
14
15
 
15
16
  ### Layouts ------------------------------------------------------------
16
17
 
17
- Layout/AlignParameters:
18
- EnforcedStyle: with_fixed_indentation
19
-
20
- Layout/ExtraSpacing:
21
- AllowForAlignment: true
22
-
23
- Layout/SpaceAfterComma:
18
+ Lint/AmbiguousOperatorPrecedence:
24
19
  Enabled: false
25
20
 
26
- Layout/SpaceAroundEqualsInParameterDefault:
27
- EnforcedStyle: no_space
28
-
29
- Layout/SpaceAroundOperators:
21
+ Layout/SpaceBeforeBlockBraces:
30
22
  Enabled: false
31
23
 
32
24
  Layout/SpaceInsideBlockBraces:
33
- EnforcedStyle: space
25
+ Enabled: false
34
26
 
35
27
  Layout/SpaceInsideHashLiteralBraces:
36
28
  EnforcedStyle: no_space
37
29
 
38
- ### Styles -------------------------------------------------------------
39
-
40
- Style/AndOr:
41
- EnforcedStyle: conditionals
30
+ ### Metrics ------------------------------------------------------------
42
31
 
43
- Style/DoubleNegation:
32
+ Metrics:
44
33
  Enabled: false
45
34
 
46
- Style/EmptyCaseCondition:
35
+ ### Naming -------------------------------------------------------------
36
+
37
+ Naming/MethodParameterName:
47
38
  Enabled: false
48
39
 
49
- Style/EmptyElse:
50
- EnforcedStyle: empty
40
+ Naming/PredicateName:
41
+ Enabled: false
51
42
 
52
- Style/EmptyMethod:
53
- EnforcedStyle: compact
43
+ ### Styles -------------------------------------------------------------
54
44
 
55
- Style/FormatString:
56
- EnforcedStyle: percent
45
+ Style/CombinableLoops:
46
+ Enabled: false # there is case that it can't combined loop.
57
47
 
58
- Style/ParallelAssignment:
59
- Enabled: false
60
-
61
- Style/SingleLineBlockParams:
48
+ Style/Documentation:
62
49
  Enabled: false
63
50
 
64
- Style/PerlBackrefs:
51
+ Style/FrozenStringLiteralComment:
65
52
  Enabled: false
66
53
 
67
- Style/Documentation:
68
- Enabled: false # TODO
69
-
70
- ### Metrics ------------------------------------------------------------
54
+ Style/NumericPredicate:
55
+ Enabled: false # it is easier to read `size > 0` than `size.positive?`
71
56
 
72
- Metrics/AbcSize:
73
- Enabled: true
57
+ Style/OptionalBooleanParameter:
58
+ Enabled: false # it is necessary to change distructively.
74
59
 
75
- Metrics/BlockLength:
76
- Enabled: true
60
+ Style/ParallelAssignment:
61
+ Enabled: false # one line style is compact.
77
62
 
78
- Metrics/ClassLength:
79
- Max: 200
63
+ Style/PreferredHashMethods:
64
+ Enabled: false
80
65
 
81
- Metrics/CyclomaticComplexity:
82
- Enabled: true
66
+ Style/SymbolArray:
67
+ Enabled: false # general array literal is easy to read. no problem.
83
68
 
84
- Metrics/PerceivedComplexity:
85
- Enabled: true
69
+ Style/ZeroLengthPredicate:
70
+ Enabled: false # it is so easy to read `a.size > 0` as `!a.empty?`
86
71
 
87
- Metrics/BlockNesting:
88
- Enabled: true
72
+ ### RSpec --------------------------------------------------------------
89
73
 
90
- Metrics/LineLength:
91
- Max: 120
74
+ RSpec/MessageSpies:
75
+ EnforcedStyle: receive
92
76
 
93
- Metrics/MethodLength:
94
- Enabled: true
77
+ RSpec/DescribedClass:
78
+ Enabled: false
95
79
 
96
- Metrics/ModuleLength:
97
- Enabled: true
80
+ RSpec/ExampleLength:
81
+ Max: 25
98
82
 
99
- Style/MultilineBlockChain:
100
- Enabled: true
83
+ RSpec/FilePath:
84
+ Enabled: false # too many offense
101
85
 
102
- Metrics/ParameterLists:
103
- Max: 10
86
+ RSpec/ImplicitSubject:
87
+ Enabled: false # too many offenses
104
88
 
105
- ### Naming -------------------------------------------------------------
89
+ RSpec/MultipleExpectations:
90
+ Max: 15
106
91
 
107
- Naming/VariableNumber:
108
- EnforcedStyle: snake_case
92
+ RSpec/NestedGroups:
93
+ Max: 5
109
94
 
110
- ### RSpec --------------------------------------------------------------
95
+ RSpec/PredicateMatcher:
96
+ Enabled: false
111
97
 
112
- RSpec/MessageSpies:
113
- EnforcedStyle: receive
98
+ RSpec/RepeatedExampleGroupBody:
99
+ Enabled: false
114
100
 
115
- RSpec/NestedGroups:
116
- Max: 5
101
+ RSpec/RepeatedExampleGroupDescription:
102
+ Enabled: false # too many offenses
data/.yardopts CHANGED
@@ -1,2 +1 @@
1
1
  --markup markdown
2
- --markup-provider redcarpet
data/README.md CHANGED
@@ -1,57 +1,55 @@
1
1
  # NetworkX.rb
2
2
 
3
- [NetworkX](https://networkx.github.io/) is a very popular Python library, that handles various use-cases of the Graph Data Structure. This project intends to provide a working alternative to the Ruby community, by closely mimicing as many features as possible.
3
+ [![Gem Version](https://badge.fury.io/rb/networkx.svg)](https://badge.fury.io/rb/networkx)
4
4
 
5
- *This project has begun just now, and a v0.1.0 release with basic Graph classes can be expected by January 2018.*
5
+ [NetworkX](https://networkx.github.io/) is a very popular Python library, that handles various use-cases of the Graph Data Structure.
6
+ This project intends to provide a working alternative to the Ruby community, by closely mimicing as many features as possible.
6
7
 
7
- ### List of contents
8
+ ## List of contents
8
9
 
9
10
  - [Installing](#installing)
10
- - [Roadmap](#roadmap)
11
+ - [Usage](#Usage)
12
+ - [Document](#document)
11
13
  - [Contributing](#contributing)
12
14
  - [License](#license)
13
15
 
14
- ### Installing
16
+ ## Installing
15
17
 
16
- [(Back to top)](#list-of-contents)
18
+ - install it yourself as:
19
+ ```console
20
+ $ gem install networkx
21
+ ```
17
22
 
18
- - Clone the repository with `git clone git@github.com:athityakumar/networkx.rb.git`
19
- - Navigate to networkx with `cd networkx.rb`
20
- - Install dependencies with `gem install bundler && bundle install`
21
- - Install networkx gem with `rake install`
22
- - Start checking out in PRY / IRB console :
23
+
24
+ - Or use Bundler & Gemfile
25
+ 1. add this line to your application's Gemfile:
26
+ ```ruby
27
+ gem 'networkx'
28
+ ```
29
+ 2. And then execute:
30
+ ```console
31
+ $ bundle install
32
+ ```
33
+
34
+ ## Usage
23
35
 
24
36
  ```ruby
25
37
  require 'networkx'
26
- #=> true
27
38
 
28
- # Yet to be implemented
29
- g = NetworkX::Graph.new()
39
+ g = NetworkX::Graph.new
30
40
  g.add_edge('start', 'stop')
31
41
  ```
32
42
 
33
- ### Roadmap
34
-
35
- [(Back to top)](#list-of-contents)
36
-
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 :
38
-
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
-
41
- - `Edge` : This class should be capable of handling different types of edges. Though a basic undirected Graph doesn't store any metadata in the edges, weighted edges and parametric edges are something that need to be handled.
42
-
43
- - `Graph` : The simplest of graphs. This class handles just connections between different `Node`s via `Edge`s.
44
-
45
- - `DirectedGraph` : Inherits from `Graph` class. Uses directions between `Edge`s.
46
-
47
- ### Contributing
43
+ ## Document
48
44
 
49
- [(Back to top)](#list-of-contents)
45
+ You can read [Document](https://SciRuby.github.io/networkx.rb/) for this library.
50
46
 
51
- Your contributions are always welcome! Please have a look at the [contribution guidelines](CONTRIBUTING.md) first. :tada:
47
+ ## Contributing
52
48
 
53
- ### License
49
+ Your contributions are always welcome!
50
+ Please have a look at the [contribution guidelines](CONTRIBUTING.md) first. :tada:
54
51
 
55
- [(Back to top)](#list-of-contents)
52
+ ## License
56
53
 
57
- The MIT License 2017 - [Athitya Kumar](https://github.com/athityakumar). Please have a look at the [LICENSE.md](LICENSE.md) for more details.
54
+ The MIT License 2017 - [Athitya Kumar](https://github.com/athityakumar).
55
+ Please have a look at the [LICENSE.md](LICENSE.md) for more details.
data/Rakefile CHANGED
@@ -1,7 +1,6 @@
1
- require 'bundler/setup'
1
+ require 'bundler/gem_tasks'
2
2
 
3
- require 'rubygems/tasks'
4
- Gem::Tasks.new
3
+ require 'bundler/setup'
5
4
 
6
5
  require 'rspec/core/rake_task'
7
6
  RSpec::Core::RakeTask.new
@@ -1,6 +1,4 @@
1
1
  module NetworkX
2
- # TODO: Reduce method complexity and method length
3
-
4
2
  # Returns all cliques in the graph
5
3
  #
6
4
  # @param graph [Graph, MultiGraph] a graph
@@ -8,6 +6,7 @@ module NetworkX
8
6
  # @return [Array<Array<Object>>] Arrays of nodes in the cliques
9
7
  def self.find_cliques(graph)
10
8
  return nil if graph.nodes.empty?
9
+
11
10
  q = [nil]
12
11
  adj = {}
13
12
  graph.nodes.each_key { |u| adj[u] = [] }
@@ -15,13 +14,16 @@ module NetworkX
15
14
 
16
15
  subg = graph.nodes.keys
17
16
  cand = graph.nodes.keys
18
- u = subg.max { |n_1, n_2| (cand & adj[n_1]).length <=> (cand & adj[n_2]).length }
17
+ u = subg.max { |n1, n2| (cand & adj[n1]).length <=> (cand & adj[n2]).length }
19
18
  ext_u = cand - adj[u]
20
19
  stack = []
21
20
  cliques = []
22
21
  begin
23
22
  loop do
24
- if !ext_u.empty?
23
+ if ext_u.empty?
24
+ q.pop
25
+ subg, cand, ext_u = stack.pop
26
+ else
25
27
  q_elem = ext_u.pop
26
28
  cand.delete(q_elem)
27
29
  q[-1] = q_elem
@@ -36,17 +38,14 @@ module NetworkX
36
38
  q << nil
37
39
  subg = subg_q
38
40
  cand = cand_q
39
- u = subg.max { |n_1, n_2| (cand & adj[n_1]).length <=> (cand & adj[n_2]).length }
41
+ u = subg.max { |n1, n2| (cand & adj[n1]).length <=> (cand & adj[n2]).length }
40
42
  ext_u = cand - adj[u]
41
43
  end
42
44
  end
43
- else
44
- q.pop
45
- subg, cand, ext_u = stack.pop
46
45
  end
47
46
  end
48
47
  rescue NoMethodError
49
- return cliques
48
+ cliques
50
49
  end
51
50
  end
52
51
 
@@ -58,8 +57,6 @@ module NetworkX
58
57
  # @return [Numeric] Number of cliques containing the given node
59
58
  def self.number_of_cliques(graph, node)
60
59
  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
60
+ cliques.count { |c| c.include?(node) }
64
61
  end
65
62
  end
@@ -1,13 +1,11 @@
1
1
  module NetworkX
2
- # TODO: Reduce method complexity and method length
3
-
4
2
  # Returns all basis cycles in graph
5
3
  #
6
4
  # @param graph [Graph] a graph
7
5
  # @param root [Object, Nil] root for the graph cycles
8
6
  #
9
7
  # @return [Array<Array<Object>>] Arrays of nodes in the cycles
10
- def self.cycle_basis(graph, root=nil)
8
+ def self.cycle_basis(graph, root = nil)
11
9
  gnodes = graph.nodes.keys
12
10
  cycles = []
13
11
  until gnodes.empty?
@@ -19,7 +17,7 @@ module NetworkX
19
17
  z = stack.shift
20
18
  zused = used[z]
21
19
  graph.adj[z].each_key do |u|
22
- if !used.key?(u)
20
+ if !used.has_key?(u)
23
21
  pred[u] = z
24
22
  stack << u
25
23
  used[u] = [z]
@@ -46,8 +44,6 @@ module NetworkX
46
44
  cycles
47
45
  end
48
46
 
49
- # TODO: Reduce method complexity and method length
50
-
51
47
  # Returns the cycle containing the given node
52
48
  #
53
49
  # @param graph [Graph, DiGraph] a graph
@@ -67,6 +63,7 @@ module NetworkX
67
63
  edge_dfs(graph, node).each do |edge|
68
64
  tail, head = edge
69
65
  next if explored.include?(head)
66
+
70
67
  if !previous_head.nil? && tail != previous_head
71
68
  loop do
72
69
  popped_edge = edges.pop
@@ -76,7 +73,7 @@ module NetworkX
76
73
  break
77
74
  else
78
75
  popped_head = popped_edge[1]
79
- active_nodes.delete!(popped_head)
76
+ active_nodes.delete(popped_head)
80
77
  end
81
78
 
82
79
  unless edges.empty?
@@ -101,4 +98,17 @@ module NetworkX
101
98
  end
102
99
  raise ArgumentError, 'No cycle found!' if cycle.empty?
103
100
  end
101
+
102
+ # Returns whether the given undirected cycle has cycle.
103
+ #
104
+ # @param undirected_graph [Graph] an undirected graph
105
+ #
106
+ # @return [book] true if the given graph has cycle. otherwise, false.
107
+ def self.cycle?(undirected_graph)
108
+ uf = NetworkX::UnionFind.new
109
+ undirected_graph.edges.each do |x, y|
110
+ uf[x] == uf[y] ? (return [x, y]) : uf.unite(x, y)
111
+ end
112
+ false
113
+ end
104
114
  end
@@ -7,6 +7,7 @@ module NetworkX
7
7
  # @return [Array<Object>] Array of the descendants
8
8
  def self.descendants(graph, source)
9
9
  raise ArgumentError, 'Source is not present in the graph!' unless graph.node?(source)
10
+
10
11
  des = single_source_shortest_path_length(graph, source).map { |u, _| u }.uniq
11
12
  des - [source]
12
13
  end
@@ -19,12 +20,11 @@ module NetworkX
19
20
  # @return [Array<Object>] Array of the ancestors
20
21
  def self.ancestors(graph, source)
21
22
  raise ArgumentError, 'Source is not present in the graph!' unless graph.node?(source)
23
+
22
24
  anc = single_source_shortest_path_length(graph.reverse, source).map { |u, _| u }.uniq
23
25
  anc - [source]
24
26
  end
25
27
 
26
- # TODO: Reduce method complexity and method length
27
-
28
28
  # Returns the nodes arranged in the topologically sorted fashion
29
29
  #
30
30
  # @param graph [DiGraph] a graph
@@ -32,13 +32,17 @@ module NetworkX
32
32
  # @return [Array<Object>] Array of the nodes
33
33
  def self.topological_sort(graph)
34
34
  raise ArgumentError, 'Topological Sort not defined on undirected graphs!' unless graph.directed?
35
+
35
36
  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
37
+ indegree_map = graph.nodes.each_key.map do |u|
38
+ [u, graph.in_degree(u)] if graph.in_degree(u).positive?
39
+ end.compact.to_h
40
+ zero_indegree = graph.nodes.each_key.select { |u| graph.in_degree(u).zero? }
38
41
 
39
42
  until zero_indegree.empty?
40
43
  node = zero_indegree.shift
41
- raise ArgumentError, 'Graph changed during iteration!' unless graph.nodes.key?(node)
44
+ raise ArgumentError, 'Graph changed during iteration!' unless graph.nodes.has_key?(node)
45
+
42
46
  graph.adj[node].each_key do |child|
43
47
  indegree_map[child] -= 1
44
48
  if indegree_map[child].zero?
@@ -49,6 +53,7 @@ module NetworkX
49
53
  nodes << node
50
54
  end
51
55
  raise ArgumentError, 'Graph contains cycle or graph changed during iteration!' unless indegree_map.empty?
56
+
52
57
  nodes
53
58
  end
54
59
  end
@@ -5,12 +5,13 @@ module NetworkX
5
5
  # @param node [Object] node to find the eccentricity of
6
6
  #
7
7
  # @return [Array<Numeric>, Numeric] eccentricity/eccentricites of all nodes
8
- def self.eccentricity(graph, node=nil)
8
+ def self.eccentricity(graph, node = nil)
9
9
  e = {}
10
10
  graph.nodes.each do |u, _|
11
11
  length = single_source_shortest_path_length(graph, u)
12
12
  l = length.length
13
13
  raise ArgumentError, 'Found infinite path length!' unless l == graph.nodes.length
14
+
14
15
  e[u] = length.max_by { |a| a[1] }[1]
15
16
  end
16
17
  node.nil? ? e : e[node]
@@ -1,6 +1,4 @@
1
1
  module NetworkX
2
- # TODO: Reduce method complexity and method length
3
-
4
2
  # Returns the maximal independent set of a graph
5
3
  #
6
4
  # @param graph [Graph, DiGraph, MultiGraph, MultiDiGraph] a graph
@@ -9,9 +7,11 @@ module NetworkX
9
7
  # @return [Numeric] radius of the graph
10
8
  def self.maximal_independent_set(graph, nodes)
11
9
  raise 'The array containing the nodes should be a subset of the graph!' if (graph.nodes.keys - nodes).empty?
10
+
12
11
  neighbours = []
13
12
  nodes.each { |u| graph.adj[u].each { |v, _| neighbours |= [v] } }
14
13
  raise 'Nodes is not an independent set of graph!' if (neighbours - nodes).empty?
14
+
15
15
  available_nodes = graph.nodes.keys - (neighbours | nodes)
16
16
  until available_nodes.empty?
17
17
  node = available_nodes.sample
@@ -11,8 +11,6 @@ module NetworkX
11
11
  edges
12
12
  end
13
13
 
14
- # TODO: Reduce method complexity and method length
15
-
16
14
  # Returns the minimum spanning tree of a graph
17
15
  #
18
16
  # @param graph [Graph, DiGraph] a graph
@@ -27,7 +25,7 @@ module NetworkX
27
25
  edge = edges.shift
28
26
  unless union_find.connected?(edge[0][0], edge[0][1])
29
27
  union_find.union(edge[0][0], edge[0][1])
30
- mst.add_edge(edge[0][0], edge[0][1], graph.adj[edge[0][0]][edge[0][1]])
28
+ mst.add_edge(edge[0][0], edge[0][1], **graph.adj[edge[0][0]][edge[0][1]])
31
29
  end
32
30
  end
33
31
  mst