networkx 0.1.0 → 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} +21 -11
- data/.github/ISSUE_TEMPLATE.md +15 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +10 -0
- 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 +56 -63
- data/.yardopts +0 -1
- data/README.md +27 -27
- data/Rakefile +2 -3
- data/lib/networkx/auxillary_functions/cliques.rb +62 -0
- data/lib/networkx/auxillary_functions/cycles.rb +114 -0
- data/lib/networkx/auxillary_functions/dag.rb +59 -0
- data/lib/networkx/auxillary_functions/eccentricity.rb +37 -0
- data/lib/networkx/auxillary_functions/mis.rb +23 -0
- data/lib/networkx/auxillary_functions/mst.rb +33 -0
- data/lib/networkx/auxillary_functions/union_find.rb +104 -0
- data/lib/networkx/auxillary_functions/vitality.rb +13 -0
- data/lib/networkx/auxillary_functions/wiener.rb +13 -0
- data/lib/networkx/converters/to_csv.rb +45 -0
- data/lib/networkx/converters/to_json.rb +37 -0
- data/lib/networkx/digraph.rb +234 -0
- data/lib/networkx/flow/capacityscaling.rb +249 -0
- data/lib/networkx/flow/edmondskarp.rb +115 -0
- data/lib/networkx/flow/preflowpush.rb +249 -0
- data/lib/networkx/flow/shortestaugmentingpath.rb +154 -0
- data/lib/networkx/flow/utils.rb +139 -0
- data/lib/networkx/graph.rb +448 -0
- data/lib/networkx/link_analysis/hits.rb +59 -0
- data/lib/networkx/link_analysis/pagerank.rb +89 -0
- data/lib/networkx/multidigraph.rb +249 -0
- data/lib/networkx/multigraph.rb +199 -0
- data/lib/networkx/operators/all.rb +65 -0
- data/lib/networkx/operators/binary.rb +222 -0
- data/lib/networkx/operators/product.rb +201 -0
- data/lib/networkx/operators/unary.rb +17 -0
- 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 +73 -0
- data/lib/networkx/shortest_path/dense.rb +29 -0
- data/lib/networkx/shortest_path/unweighted.rb +136 -0
- data/lib/networkx/shortest_path/weighted.rb +417 -0
- data/lib/networkx/to_matrix.rb +51 -0
- data/lib/networkx/traversals/bfs.rb +110 -0
- data/lib/networkx/traversals/dfs.rb +135 -0
- data/lib/networkx/traversals/edge_dfs.rb +114 -0
- data/lib/networkx/version.rb +1 -1
- data/lib/networkx.rb +43 -1
- data/networkx.gemspec +14 -12
- metadata +118 -62
- data/.rspec_formatter.rb +0 -24
- data/.travis.yml +0 -18
- data/Guardfile +0 -7
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,24 +11,20 @@ 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
|
18
|
-
cd
|
17
|
+
git clone https://github.com/`your_github_user_id`/networkx.rb.git
|
18
|
+
cd networkx.rb
|
19
19
|
gem install bundler
|
20
20
|
bundle install
|
21
21
|
```
|
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
|
+
```
|
@@ -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,10 @@
|
|
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.
|
2
|
+
|
3
|
+
- Relevant Issues : (optional)
|
4
|
+
- Relevant PRs : (optional)
|
5
|
+
- Type of change :
|
6
|
+
- [ ] New feature
|
7
|
+
- [ ] Bug fix for existing feature
|
8
|
+
- [ ] Code quality improvement
|
9
|
+
- [ ] Addition or Improvement of tests
|
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,109 +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.1
|
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
|
-
###
|
30
|
+
### Metrics ------------------------------------------------------------
|
39
31
|
|
40
|
-
|
41
|
-
|
32
|
+
Metrics:
|
33
|
+
Enabled: false
|
42
34
|
|
43
|
-
|
35
|
+
### Naming -------------------------------------------------------------
|
36
|
+
|
37
|
+
Naming/MethodParameterName:
|
44
38
|
Enabled: false
|
45
39
|
|
46
|
-
|
40
|
+
Naming/PredicateName:
|
47
41
|
Enabled: false
|
48
42
|
|
49
|
-
|
50
|
-
|
43
|
+
### Styles -------------------------------------------------------------
|
44
|
+
|
45
|
+
Style/CombinableLoops:
|
46
|
+
Enabled: false # there is case that it can't combined loop.
|
51
47
|
|
52
|
-
Style/
|
53
|
-
|
48
|
+
Style/Documentation:
|
49
|
+
Enabled: false
|
54
50
|
|
55
|
-
Style/
|
51
|
+
Style/FrozenStringLiteralComment:
|
56
52
|
Enabled: false
|
57
53
|
|
58
|
-
Style/
|
59
|
-
|
54
|
+
Style/NumericPredicate:
|
55
|
+
Enabled: false # it is easier to read `size > 0` than `size.positive?`
|
56
|
+
|
57
|
+
Style/OptionalBooleanParameter:
|
58
|
+
Enabled: false # it is necessary to change distructively.
|
60
59
|
|
61
60
|
Style/ParallelAssignment:
|
62
|
-
Enabled: false
|
61
|
+
Enabled: false # one line style is compact.
|
63
62
|
|
64
|
-
Style/
|
63
|
+
Style/PreferredHashMethods:
|
65
64
|
Enabled: false
|
66
65
|
|
67
|
-
Style/
|
68
|
-
Enabled: false
|
66
|
+
Style/SymbolArray:
|
67
|
+
Enabled: false # general array literal is easy to read. no problem.
|
69
68
|
|
70
|
-
Style/
|
71
|
-
Enabled: false #
|
69
|
+
Style/ZeroLengthPredicate:
|
70
|
+
Enabled: false # it is so easy to read `a.size > 0` as `!a.empty?`
|
72
71
|
|
73
|
-
###
|
72
|
+
### RSpec --------------------------------------------------------------
|
74
73
|
|
75
|
-
|
76
|
-
|
74
|
+
RSpec/MessageSpies:
|
75
|
+
EnforcedStyle: receive
|
77
76
|
|
78
|
-
|
79
|
-
|
80
|
-
- 'spec/**/*'
|
77
|
+
RSpec/DescribedClass:
|
78
|
+
Enabled: false
|
81
79
|
|
82
|
-
|
83
|
-
Max:
|
80
|
+
RSpec/ExampleLength:
|
81
|
+
Max: 25
|
84
82
|
|
85
|
-
|
86
|
-
|
83
|
+
RSpec/FilePath:
|
84
|
+
Enabled: false # too many offense
|
87
85
|
|
88
|
-
|
89
|
-
|
86
|
+
RSpec/ImplicitSubject:
|
87
|
+
Enabled: false # too many offenses
|
90
88
|
|
91
|
-
|
89
|
+
RSpec/MultipleExpectations:
|
92
90
|
Max: 15
|
93
91
|
|
94
|
-
|
95
|
-
Max:
|
92
|
+
RSpec/NestedGroups:
|
93
|
+
Max: 5
|
96
94
|
|
97
|
-
|
95
|
+
RSpec/PredicateMatcher:
|
98
96
|
Enabled: false
|
99
97
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
### RSpec --------------------------------------------------------------
|
104
|
-
|
105
|
-
RSpec/MessageSpies:
|
106
|
-
EnforcedStyle: receive
|
98
|
+
RSpec/RepeatedExampleGroupBody:
|
99
|
+
Enabled: false
|
107
100
|
|
108
|
-
RSpec/
|
109
|
-
|
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
|
-
|
14
|
+
## Installing
|
15
15
|
|
16
|
-
- 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.
|
17
19
|
- Navigate to networkx with `cd networkx.rb`
|
18
20
|
- Install dependencies with `gem install bundler && bundle install`
|
19
|
-
- Install networkx gem with `rake install`
|
20
|
-
- Start checking out in PRY / IRB console :
|
21
21
|
|
22
22
|
```ruby
|
23
23
|
require 'networkx'
|
24
|
-
#=> true
|
25
24
|
|
26
|
-
|
27
|
-
g = NetworkX::Graph.new()
|
25
|
+
g = NetworkX::Graph.new
|
28
26
|
g.add_edge('start', 'stop')
|
29
27
|
```
|
30
28
|
|
31
|
-
|
32
|
-
|
33
|
-
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 :
|
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
|
-
- `DirectedGraph` : Inherits from `Graph` class. Uses directions between `Edge`s.
|
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
@@ -0,0 +1,62 @@
|
|
1
|
+
module NetworkX
|
2
|
+
# Returns all cliques in the graph
|
3
|
+
#
|
4
|
+
# @param graph [Graph, MultiGraph] a graph
|
5
|
+
#
|
6
|
+
# @return [Array<Array<Object>>] Arrays of nodes in the cliques
|
7
|
+
def self.find_cliques(graph)
|
8
|
+
return nil if graph.nodes.empty?
|
9
|
+
|
10
|
+
q = [nil]
|
11
|
+
adj = {}
|
12
|
+
graph.nodes.each_key { |u| adj[u] = [] }
|
13
|
+
graph.adj.each { |u, u_edges| u_edges.each_key { |v| adj[u] << v if u != v } }
|
14
|
+
|
15
|
+
subg = graph.nodes.keys
|
16
|
+
cand = graph.nodes.keys
|
17
|
+
u = subg.max { |n1, n2| (cand & adj[n1]).length <=> (cand & adj[n2]).length }
|
18
|
+
ext_u = cand - adj[u]
|
19
|
+
stack = []
|
20
|
+
cliques = []
|
21
|
+
begin
|
22
|
+
loop do
|
23
|
+
if ext_u.empty?
|
24
|
+
q.pop
|
25
|
+
subg, cand, ext_u = stack.pop
|
26
|
+
else
|
27
|
+
q_elem = ext_u.pop
|
28
|
+
cand.delete(q_elem)
|
29
|
+
q[-1] = q_elem
|
30
|
+
adj_q = adj[q_elem]
|
31
|
+
subg_q = subg & adj_q
|
32
|
+
if subg_q.empty?
|
33
|
+
cliques << q[0..(q.length - 1)]
|
34
|
+
else
|
35
|
+
cand_q = cand & adj_q
|
36
|
+
unless cand_q.empty?
|
37
|
+
stack << [subg, cand, ext_u]
|
38
|
+
q << nil
|
39
|
+
subg = subg_q
|
40
|
+
cand = cand_q
|
41
|
+
u = subg.max { |n1, n2| (cand & adj[n1]).length <=> (cand & adj[n2]).length }
|
42
|
+
ext_u = cand - adj[u]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
rescue NoMethodError
|
48
|
+
cliques
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns the number of cliques in a graph containing a node
|
53
|
+
#
|
54
|
+
# @param graph [Graph, MultiGraph] a graph
|
55
|
+
# @param node [Object] a node
|
56
|
+
#
|
57
|
+
# @return [Numeric] Number of cliques containing the given node
|
58
|
+
def self.number_of_cliques(graph, node)
|
59
|
+
cliques = find_cliques(graph)
|
60
|
+
cliques.count { |c| c.include?(node) }
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module NetworkX
|
2
|
+
# Returns all basis cycles in graph
|
3
|
+
#
|
4
|
+
# @param graph [Graph] a graph
|
5
|
+
# @param root [Object, Nil] root for the graph cycles
|
6
|
+
#
|
7
|
+
# @return [Array<Array<Object>>] Arrays of nodes in the cycles
|
8
|
+
def self.cycle_basis(graph, root = nil)
|
9
|
+
gnodes = graph.nodes.keys
|
10
|
+
cycles = []
|
11
|
+
until gnodes.empty?
|
12
|
+
root = gnodes.shift if root.nil?
|
13
|
+
stack = [root]
|
14
|
+
pred = {root => root}
|
15
|
+
used = {root => []}
|
16
|
+
until stack.empty?
|
17
|
+
z = stack.shift
|
18
|
+
zused = used[z]
|
19
|
+
graph.adj[z].each_key do |u|
|
20
|
+
if !used.has_key?(u)
|
21
|
+
pred[u] = z
|
22
|
+
stack << u
|
23
|
+
used[u] = [z]
|
24
|
+
elsif u == z
|
25
|
+
cycles << [z]
|
26
|
+
elsif !zused.include?(u)
|
27
|
+
pn = used[u]
|
28
|
+
cycle = [u, z]
|
29
|
+
p = pred[z]
|
30
|
+
until pn.include?(p)
|
31
|
+
cycle << p
|
32
|
+
p = pred[p]
|
33
|
+
end
|
34
|
+
cycle << p
|
35
|
+
cycles << cycle
|
36
|
+
used[u] << z
|
37
|
+
used[u] = used[u].uniq
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
gnodes -= pred.keys
|
42
|
+
root = nil
|
43
|
+
end
|
44
|
+
cycles
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns the cycle containing the given node
|
48
|
+
#
|
49
|
+
# @param graph [Graph, DiGraph] a graph
|
50
|
+
# @param node [Object] node to be included in the cycle
|
51
|
+
#
|
52
|
+
# @return [Array<Array<Object>>] Arrays of nodes in the cycle
|
53
|
+
def self.find_cycle(graph, node)
|
54
|
+
explored = Set.new
|
55
|
+
cycle = []
|
56
|
+
final_node = nil
|
57
|
+
unless explored.include?(node)
|
58
|
+
edges = []
|
59
|
+
seen = [node]
|
60
|
+
active_nodes = [node]
|
61
|
+
previous_head = nil
|
62
|
+
|
63
|
+
edge_dfs(graph, node).each do |edge|
|
64
|
+
tail, head = edge
|
65
|
+
next if explored.include?(head)
|
66
|
+
|
67
|
+
if !previous_head.nil? && tail != previous_head
|
68
|
+
loop do
|
69
|
+
popped_edge = edges.pop
|
70
|
+
if popped_edge.nil?
|
71
|
+
edges = []
|
72
|
+
active_nodes = [tail]
|
73
|
+
break
|
74
|
+
else
|
75
|
+
popped_head = popped_edge[1]
|
76
|
+
active_nodes.delete(popped_head)
|
77
|
+
end
|
78
|
+
|
79
|
+
unless edges.empty?
|
80
|
+
last_head = edges[-1][1]
|
81
|
+
break if tail == last_head
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
edges << edge
|
86
|
+
|
87
|
+
if active_nodes.include?(head)
|
88
|
+
cycle += edges
|
89
|
+
final_node = head
|
90
|
+
break
|
91
|
+
else
|
92
|
+
seen << head
|
93
|
+
active_nodes << head
|
94
|
+
previous_head = head
|
95
|
+
end
|
96
|
+
end
|
97
|
+
cycle.each_with_index { |edge, i| return cycle[i..(cycle.length - 1)] if final_node == edge[0] }
|
98
|
+
end
|
99
|
+
raise ArgumentError, 'No cycle found!' if cycle.empty?
|
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
|
114
|
+
end
|