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.
- checksums.yaml +5 -5
- data/{CODE_OF_CONDUCT.md → .github/CODE_OF_CONDUCT.md} +0 -0
- data/{CONTRIBUTING.md → .github/CONTRIBUTING.md} +20 -10
- data/{ISSUE_TEMPLATE.md → .github/ISSUE_TEMPLATE.md} +1 -1
- data/{PULL_REQUEST_TEMPLATE.md → .github/PULL_REQUEST_TEMPLATE.md} +2 -4
- data/.github/workflows/ci.yml +17 -0
- data/.github/workflows/doc.yml +23 -0
- data/.github/workflows/gem-push.yml +45 -0
- data/.rspec +0 -1
- data/.rubocop.yml +57 -71
- data/.yardopts +0 -1
- data/README.md +27 -27
- data/Rakefile +2 -3
- data/lib/networkx/auxillary_functions/cliques.rb +9 -12
- data/lib/networkx/auxillary_functions/cycles.rb +17 -7
- data/lib/networkx/auxillary_functions/dag.rb +10 -5
- data/lib/networkx/auxillary_functions/eccentricity.rb +2 -1
- data/lib/networkx/auxillary_functions/mis.rb +2 -2
- data/lib/networkx/auxillary_functions/mst.rb +1 -3
- data/lib/networkx/auxillary_functions/union_find.rb +92 -12
- data/lib/networkx/auxillary_functions/wiener.rb +1 -1
- data/lib/networkx/converters/to_csv.rb +1 -3
- data/lib/networkx/converters/to_json.rb +0 -2
- data/lib/networkx/digraph.rb +55 -49
- data/lib/networkx/flow/capacityscaling.rb +29 -35
- data/lib/networkx/flow/edmondskarp.rb +17 -15
- data/lib/networkx/flow/preflowpush.rb +29 -32
- data/lib/networkx/flow/shortestaugmentingpath.rb +17 -20
- data/lib/networkx/flow/utils.rb +6 -27
- data/lib/networkx/graph.rb +179 -72
- data/lib/networkx/link_analysis/hits.rb +9 -9
- data/lib/networkx/link_analysis/pagerank.rb +48 -6
- data/lib/networkx/multidigraph.rb +90 -81
- data/lib/networkx/multigraph.rb +91 -63
- data/lib/networkx/operators/all.rb +8 -4
- data/lib/networkx/operators/binary.rb +106 -128
- data/lib/networkx/operators/product.rb +61 -64
- data/lib/networkx/operators/unary.rb +1 -1
- data/lib/networkx/others/bridges.rb +30 -0
- data/lib/networkx/others/generators.rb +237 -0
- data/lib/networkx/others/grid_2d_graph.rb +38 -0
- data/lib/networkx/others/info.rb +11 -0
- data/lib/networkx/others/number_connected_components.rb +17 -0
- data/lib/networkx/others/reads.rb +52 -0
- data/lib/networkx/shortest_path/astar.rb +10 -8
- data/lib/networkx/shortest_path/dense.rb +1 -3
- data/lib/networkx/shortest_path/unweighted.rb +13 -16
- data/lib/networkx/shortest_path/weighted.rb +51 -42
- data/lib/networkx/to_matrix.rb +2 -3
- data/lib/networkx/traversals/bfs.rb +54 -2
- data/lib/networkx/traversals/dfs.rb +62 -6
- data/lib/networkx/traversals/edge_dfs.rb +36 -12
- data/lib/networkx/version.rb +1 -1
- data/lib/networkx.rb +7 -1
- data/networkx.gemspec +12 -13
- metadata +71 -81
- data/.rspec_formatter.rb +0 -24
- data/.travis.yml +0 -18
- data/Guardfile +0 -7
- data/RELEASE_POLICY.md +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4e86cfdb083751f6aa9d45d894dd4a83ec75623acd237c6cdc8e7cd356306409
|
4
|
+
data.tar.gz: 60ef78a9da3df8d7f61e297af48873795b21d9675138e953dd160597d9bfdc09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
|
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
|
25
|
+
3. Add code (, test, and YARD documentation).
|
26
26
|
|
27
|
-
4.
|
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
|
-
|
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
|
-
|
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
|
+
```
|
@@ -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 : (
|
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
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
|
-
|
7
|
-
- '
|
8
|
-
- '
|
9
|
-
- '
|
6
|
+
- 'spec/**/*_spec.rb'
|
7
|
+
- 'Gemfile'
|
8
|
+
- 'Rakefile'
|
9
|
+
- '*.gemspace'
|
10
10
|
DisplayCopNames: true
|
11
|
-
TargetRubyVersion: 2.2
|
12
11
|
|
13
|
-
|
12
|
+
require:
|
13
|
+
- rubocop-rspec
|
14
|
+
- rubocop-rake
|
14
15
|
|
15
16
|
### Layouts ------------------------------------------------------------
|
16
17
|
|
17
|
-
|
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/
|
27
|
-
EnforcedStyle: no_space
|
28
|
-
|
29
|
-
Layout/SpaceAroundOperators:
|
21
|
+
Layout/SpaceBeforeBlockBraces:
|
30
22
|
Enabled: false
|
31
23
|
|
32
24
|
Layout/SpaceInsideBlockBraces:
|
33
|
-
|
25
|
+
Enabled: false
|
34
26
|
|
35
27
|
Layout/SpaceInsideHashLiteralBraces:
|
36
28
|
EnforcedStyle: no_space
|
37
29
|
|
38
|
-
###
|
39
|
-
|
40
|
-
Style/AndOr:
|
41
|
-
EnforcedStyle: conditionals
|
30
|
+
### Metrics ------------------------------------------------------------
|
42
31
|
|
43
|
-
|
32
|
+
Metrics:
|
44
33
|
Enabled: false
|
45
34
|
|
46
|
-
|
35
|
+
### Naming -------------------------------------------------------------
|
36
|
+
|
37
|
+
Naming/MethodParameterName:
|
47
38
|
Enabled: false
|
48
39
|
|
49
|
-
|
50
|
-
|
40
|
+
Naming/PredicateName:
|
41
|
+
Enabled: false
|
51
42
|
|
52
|
-
|
53
|
-
EnforcedStyle: compact
|
43
|
+
### Styles -------------------------------------------------------------
|
54
44
|
|
55
|
-
Style/
|
56
|
-
|
45
|
+
Style/CombinableLoops:
|
46
|
+
Enabled: false # there is case that it can't combined loop.
|
57
47
|
|
58
|
-
Style/
|
59
|
-
Enabled: false
|
60
|
-
|
61
|
-
Style/SingleLineBlockParams:
|
48
|
+
Style/Documentation:
|
62
49
|
Enabled: false
|
63
50
|
|
64
|
-
Style/
|
51
|
+
Style/FrozenStringLiteralComment:
|
65
52
|
Enabled: false
|
66
53
|
|
67
|
-
Style/
|
68
|
-
Enabled: false #
|
69
|
-
|
70
|
-
### Metrics ------------------------------------------------------------
|
54
|
+
Style/NumericPredicate:
|
55
|
+
Enabled: false # it is easier to read `size > 0` than `size.positive?`
|
71
56
|
|
72
|
-
|
73
|
-
Enabled:
|
57
|
+
Style/OptionalBooleanParameter:
|
58
|
+
Enabled: false # it is necessary to change distructively.
|
74
59
|
|
75
|
-
|
76
|
-
Enabled:
|
60
|
+
Style/ParallelAssignment:
|
61
|
+
Enabled: false # one line style is compact.
|
77
62
|
|
78
|
-
|
79
|
-
|
63
|
+
Style/PreferredHashMethods:
|
64
|
+
Enabled: false
|
80
65
|
|
81
|
-
|
82
|
-
Enabled:
|
66
|
+
Style/SymbolArray:
|
67
|
+
Enabled: false # general array literal is easy to read. no problem.
|
83
68
|
|
84
|
-
|
85
|
-
Enabled:
|
69
|
+
Style/ZeroLengthPredicate:
|
70
|
+
Enabled: false # it is so easy to read `a.size > 0` as `!a.empty?`
|
86
71
|
|
87
|
-
|
88
|
-
Enabled: true
|
72
|
+
### RSpec --------------------------------------------------------------
|
89
73
|
|
90
|
-
|
91
|
-
|
74
|
+
RSpec/MessageSpies:
|
75
|
+
EnforcedStyle: receive
|
92
76
|
|
93
|
-
|
94
|
-
Enabled:
|
77
|
+
RSpec/DescribedClass:
|
78
|
+
Enabled: false
|
95
79
|
|
96
|
-
|
97
|
-
|
80
|
+
RSpec/ExampleLength:
|
81
|
+
Max: 25
|
98
82
|
|
99
|
-
|
100
|
-
Enabled:
|
83
|
+
RSpec/FilePath:
|
84
|
+
Enabled: false # too many offense
|
101
85
|
|
102
|
-
|
103
|
-
|
86
|
+
RSpec/ImplicitSubject:
|
87
|
+
Enabled: false # too many offenses
|
104
88
|
|
105
|
-
|
89
|
+
RSpec/MultipleExpectations:
|
90
|
+
Max: 15
|
106
91
|
|
107
|
-
|
108
|
-
|
92
|
+
RSpec/NestedGroups:
|
93
|
+
Max: 5
|
109
94
|
|
110
|
-
|
95
|
+
RSpec/PredicateMatcher:
|
96
|
+
Enabled: false
|
111
97
|
|
112
|
-
RSpec/
|
113
|
-
|
98
|
+
RSpec/RepeatedExampleGroupBody:
|
99
|
+
Enabled: false
|
114
100
|
|
115
|
-
RSpec/
|
116
|
-
|
101
|
+
RSpec/RepeatedExampleGroupDescription:
|
102
|
+
Enabled: false # too many offenses
|
data/.yardopts
CHANGED
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.
|
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
|
-
|
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
|
-
|
15
|
-
|
16
|
-
[(Back to top)](#list-of-contents)
|
14
|
+
## Installing
|
17
15
|
|
18
|
-
- Clone the repository
|
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
|
-
|
29
|
-
g = NetworkX::Graph.new()
|
25
|
+
g = NetworkX::Graph.new
|
30
26
|
g.add_edge('start', 'stop')
|
31
27
|
```
|
32
28
|
|
33
|
-
|
29
|
+
## Document
|
34
30
|
|
35
|
-
|
31
|
+
You can read [Document](https://SciRuby.github.io/networkx.rb/) for this library.
|
36
32
|
|
37
|
-
|
33
|
+
## Roadmap
|
38
34
|
|
39
|
-
|
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
|
-
- `
|
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
|
-
- `
|
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
|
-
|
43
|
+
- `Graph` : The simplest of graphs.
|
44
|
+
This class handles just connections between different `Node`s via `Edge`s.
|
48
45
|
|
49
|
-
|
46
|
+
- `DirectedGraph` : Inherits from `Graph` class.
|
47
|
+
Uses directions between `Edge`s.
|
50
48
|
|
51
|
-
|
49
|
+
## Contributing
|
52
50
|
|
53
|
-
|
51
|
+
Your contributions are always welcome!
|
52
|
+
Please have a look at the [contribution guidelines](CONTRIBUTING.md) first. :tada:
|
54
53
|
|
55
|
-
|
54
|
+
## License
|
56
55
|
|
57
|
-
The MIT License 2017 - [Athitya Kumar](https://github.com/athityakumar).
|
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,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 { |
|
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
|
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 { |
|
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
|
-
|
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
|
-
|
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.
|
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
|
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 =
|
37
|
-
|
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.
|
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]
|