networkx 0.1.1 → 0.2.0

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 (60) 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/.github/workflows/gem-push.yml +45 -0
  9. data/.rspec +0 -1
  10. data/.rubocop.yml +57 -71
  11. data/.yardopts +0 -1
  12. data/README.md +27 -27
  13. data/Rakefile +2 -3
  14. data/lib/networkx/auxillary_functions/cliques.rb +9 -12
  15. data/lib/networkx/auxillary_functions/cycles.rb +17 -7
  16. data/lib/networkx/auxillary_functions/dag.rb +10 -5
  17. data/lib/networkx/auxillary_functions/eccentricity.rb +2 -1
  18. data/lib/networkx/auxillary_functions/mis.rb +2 -2
  19. data/lib/networkx/auxillary_functions/mst.rb +1 -3
  20. data/lib/networkx/auxillary_functions/union_find.rb +92 -12
  21. data/lib/networkx/auxillary_functions/wiener.rb +1 -1
  22. data/lib/networkx/converters/to_csv.rb +1 -3
  23. data/lib/networkx/converters/to_json.rb +0 -2
  24. data/lib/networkx/digraph.rb +55 -49
  25. data/lib/networkx/flow/capacityscaling.rb +29 -35
  26. data/lib/networkx/flow/edmondskarp.rb +17 -15
  27. data/lib/networkx/flow/preflowpush.rb +29 -32
  28. data/lib/networkx/flow/shortestaugmentingpath.rb +17 -20
  29. data/lib/networkx/flow/utils.rb +6 -27
  30. data/lib/networkx/graph.rb +179 -72
  31. data/lib/networkx/link_analysis/hits.rb +9 -9
  32. data/lib/networkx/link_analysis/pagerank.rb +48 -6
  33. data/lib/networkx/multidigraph.rb +90 -81
  34. data/lib/networkx/multigraph.rb +91 -63
  35. data/lib/networkx/operators/all.rb +8 -4
  36. data/lib/networkx/operators/binary.rb +106 -128
  37. data/lib/networkx/operators/product.rb +61 -64
  38. data/lib/networkx/operators/unary.rb +1 -1
  39. data/lib/networkx/others/bridges.rb +30 -0
  40. data/lib/networkx/others/generators.rb +237 -0
  41. data/lib/networkx/others/grid_2d_graph.rb +38 -0
  42. data/lib/networkx/others/info.rb +11 -0
  43. data/lib/networkx/others/number_connected_components.rb +17 -0
  44. data/lib/networkx/others/reads.rb +52 -0
  45. data/lib/networkx/shortest_path/astar.rb +10 -8
  46. data/lib/networkx/shortest_path/dense.rb +1 -3
  47. data/lib/networkx/shortest_path/unweighted.rb +13 -16
  48. data/lib/networkx/shortest_path/weighted.rb +51 -42
  49. data/lib/networkx/to_matrix.rb +2 -3
  50. data/lib/networkx/traversals/bfs.rb +54 -2
  51. data/lib/networkx/traversals/dfs.rb +62 -6
  52. data/lib/networkx/traversals/edge_dfs.rb +36 -12
  53. data/lib/networkx/version.rb +1 -1
  54. data/lib/networkx.rb +7 -1
  55. data/networkx.gemspec +12 -13
  56. metadata +71 -81
  57. data/.rspec_formatter.rb +0 -24
  58. data/.travis.yml +0 -18
  59. data/Guardfile +0 -7
  60. 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: 4e86cfdb083751f6aa9d45d894dd4a83ec75623acd237c6cdc8e7cd356306409
4
+ data.tar.gz: 60ef78a9da3df8d7f61e297af48873795b21d9675138e953dd160597d9bfdc09
5
5
  SHA512:
6
- metadata.gz: 0f19f6aba21c6c12c7ce027e3067dc00e071235661e8f63287f92dc27ed3e332751cbb3526484e8095520e8d1fd29dfd7672f9fd93b55169372043ed6aa220d0
7
- data.tar.gz: fe7846c3da4f617441bdb86720861074cb98da48c849b8f3507c867b7dbfee2909d4eb336bc79c904be407b887c8653ef46036d89021e31cdb37ffa7f93b1786
6
+ metadata.gz: a7d64db11e72ecd05bba646d89116da859caa2e48b9063b158780e625c7fdf802cd840c3aace32a00314762805a27fa1373b36795462d7640f4ed7385466d403
7
+ data.tar.gz: 46886910fc5f3bb550fb089af740bb5c0e32cd5a1ff3dd2394a13256ddc3f6b4e9f32c48c37d2d827b2bc8edba36cd0894201aec833a2fb4d59318f7fb85b7ae
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
@@ -0,0 +1,45 @@
1
+ name: Ruby Gem
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ build:
11
+ name: Build + Publish
12
+ runs-on: ubuntu-latest
13
+ permissions:
14
+ contents: read
15
+ packages: write
16
+
17
+ steps:
18
+ - uses: actions/checkout@v2
19
+ - name: Set up Ruby 2.6
20
+ uses: actions/setup-ruby@v1
21
+ with:
22
+ ruby-version: 2.6.x
23
+
24
+ - name: Publish to GPR
25
+ run: |
26
+ mkdir -p $HOME/.gem
27
+ touch $HOME/.gem/credentials
28
+ chmod 0600 $HOME/.gem/credentials
29
+ printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
30
+ gem build *.gemspec
31
+ gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
32
+ env:
33
+ GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
34
+ OWNER: ${{ github.repository_owner }}
35
+
36
+ - name: Publish to RubyGems
37
+ run: |
38
+ mkdir -p $HOME/.gem
39
+ touch $HOME/.gem/credentials
40
+ chmod 0600 $HOME/.gem/credentials
41
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
42
+ gem build *.gemspec
43
+ gem push *.gem
44
+ env:
45
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
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: 3.0
4
4
  Include:
5
5
  - 'lib/**/*'
6
- Exclude:
7
- - 'vendor/**/*'
8
- - 'benchmarks/*'
9
- - 'profile/*'
6
+ - 'spec/**/*_spec.rb'
7
+ - 'Gemfile'
8
+ - 'Rakefile'
9
+ - '*.gemspace'
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,57 @@
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
+ [NetworkX](https://networkx.github.io/) is a very popular Python library, that handles various use-cases of the Graph Data Structure.
4
+ This project intends to provide a working alternative to the Ruby community, by closely mimicing as many features as possible.
4
5
 
5
- *This project has begun just now, and a v0.1.0 release with basic Graph classes can be expected by January 2018.*
6
-
7
- ### List of contents
6
+ ## List of contents
8
7
 
9
8
  - [Installing](#installing)
9
+ - [Document](#document)
10
10
  - [Roadmap](#roadmap)
11
11
  - [Contributing](#contributing)
12
12
  - [License](#license)
13
13
 
14
- ### Installing
15
-
16
- [(Back to top)](#list-of-contents)
14
+ ## Installing
17
15
 
18
- - Clone the repository with `git clone git@github.com:athityakumar/networkx.rb.git`
16
+ - Clone the repository or fork
17
+ - Clone this repository with `git clone https://github.com/SciRuby/networkx.rb.git`
18
+ - or You can fork and do clone it.
19
19
  - Navigate to networkx with `cd networkx.rb`
20
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
21
 
24
22
  ```ruby
25
23
  require 'networkx'
26
- #=> true
27
24
 
28
- # Yet to be implemented
29
- g = NetworkX::Graph.new()
25
+ g = NetworkX::Graph.new
30
26
  g.add_edge('start', 'stop')
31
27
  ```
32
28
 
33
- ### Roadmap
29
+ ## Document
34
30
 
35
- [(Back to top)](#list-of-contents)
31
+ You can read [Document](https://SciRuby.github.io/networkx.rb/) for this library.
36
32
 
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 :
33
+ ## Roadmap
38
34
 
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.
35
+ 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 :
42
36
 
43
- - `Graph` : The simplest of graphs. This class handles just connections between different `Node`s via `Edge`s.
37
+ - `Node` : This class should be capable of handling different types of nodes (not just `String` / `Integer`).
38
+ A possible complex use-case could be XML nodes.
44
39
 
45
- - `DirectedGraph` : Inherits from `Graph` class. Uses directions between `Edge`s.
40
+ - `Edge` : This class should be capable of handling different types of edges.
41
+ 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.
46
42
 
47
- ### Contributing
43
+ - `Graph` : The simplest of graphs.
44
+ This class handles just connections between different `Node`s via `Edge`s.
48
45
 
49
- [(Back to top)](#list-of-contents)
46
+ - `DirectedGraph` : Inherits from `Graph` class.
47
+ Uses directions between `Edge`s.
50
48
 
51
- Your contributions are always welcome! Please have a look at the [contribution guidelines](CONTRIBUTING.md) first. :tada:
49
+ ## Contributing
52
50
 
53
- ### License
51
+ Your contributions are always welcome!
52
+ Please have a look at the [contribution guidelines](CONTRIBUTING.md) first. :tada:
54
53
 
55
- [(Back to top)](#list-of-contents)
54
+ ## License
56
55
 
57
- The MIT License 2017 - [Athitya Kumar](https://github.com/athityakumar). Please have a look at the [LICENSE.md](LICENSE.md) for more details.
56
+ The MIT License 2017 - [Athitya Kumar](https://github.com/athityakumar).
57
+ 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]