scikit-network 0.31.0__cp310-cp310-win_amd64.whl → 0.33.0__cp310-cp310-win_amd64.whl
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.
Potentially problematic release.
This version of scikit-network might be problematic. Click here for more details.
- {scikit_network-0.31.0.dist-info → scikit_network-0.33.0.dist-info}/AUTHORS.rst +3 -1
- {scikit_network-0.31.0.dist-info → scikit_network-0.33.0.dist-info}/METADATA +27 -5
- scikit_network-0.33.0.dist-info/RECORD +228 -0
- {scikit_network-0.31.0.dist-info → scikit_network-0.33.0.dist-info}/WHEEL +1 -1
- sknetwork/__init__.py +1 -1
- sknetwork/classification/base.py +1 -1
- sknetwork/classification/base_rank.py +3 -3
- sknetwork/classification/diffusion.py +25 -16
- sknetwork/classification/knn.py +23 -16
- sknetwork/classification/metrics.py +4 -4
- sknetwork/classification/pagerank.py +12 -8
- sknetwork/classification/propagation.py +25 -17
- sknetwork/classification/tests/test_diffusion.py +10 -0
- sknetwork/classification/vote.cp310-win_amd64.pyd +0 -0
- sknetwork/classification/vote.cpp +14549 -8668
- sknetwork/clustering/__init__.py +3 -1
- sknetwork/clustering/base.py +1 -1
- sknetwork/clustering/kcenters.py +253 -0
- sknetwork/clustering/leiden.py +242 -0
- sknetwork/clustering/leiden_core.cp310-win_amd64.pyd +0 -0
- sknetwork/clustering/leiden_core.cpp +31564 -0
- sknetwork/clustering/leiden_core.pyx +124 -0
- sknetwork/clustering/louvain.py +118 -83
- sknetwork/clustering/louvain_core.cp310-win_amd64.pyd +0 -0
- sknetwork/clustering/louvain_core.cpp +21876 -16332
- sknetwork/clustering/louvain_core.pyx +86 -94
- sknetwork/clustering/postprocess.py +2 -2
- sknetwork/clustering/propagation_clustering.py +4 -4
- sknetwork/clustering/tests/test_API.py +7 -3
- sknetwork/clustering/tests/test_kcenters.py +60 -0
- sknetwork/clustering/tests/test_leiden.py +34 -0
- sknetwork/clustering/tests/test_louvain.py +2 -3
- sknetwork/data/__init__.py +1 -1
- sknetwork/data/base.py +7 -2
- sknetwork/data/load.py +20 -25
- sknetwork/data/models.py +15 -15
- sknetwork/data/parse.py +57 -34
- sknetwork/data/tests/test_API.py +3 -3
- sknetwork/data/tests/test_base.py +2 -2
- sknetwork/data/tests/test_parse.py +9 -12
- sknetwork/data/tests/test_toy_graphs.py +33 -33
- sknetwork/data/toy_graphs.py +35 -43
- sknetwork/embedding/__init__.py +0 -1
- sknetwork/embedding/base.py +23 -19
- sknetwork/embedding/force_atlas.py +3 -2
- sknetwork/embedding/louvain_embedding.py +1 -27
- sknetwork/embedding/random_projection.py +5 -3
- sknetwork/embedding/spectral.py +0 -73
- sknetwork/embedding/svd.py +0 -4
- sknetwork/embedding/tests/test_API.py +4 -28
- sknetwork/embedding/tests/test_louvain_embedding.py +13 -13
- sknetwork/embedding/tests/test_spectral.py +2 -5
- sknetwork/embedding/tests/test_svd.py +7 -1
- sknetwork/gnn/base_layer.py +3 -3
- sknetwork/gnn/gnn_classifier.py +41 -87
- sknetwork/gnn/layer.py +1 -1
- sknetwork/gnn/loss.py +1 -1
- sknetwork/gnn/optimizer.py +4 -3
- sknetwork/gnn/tests/test_base_layer.py +4 -4
- sknetwork/gnn/tests/test_gnn_classifier.py +12 -39
- sknetwork/gnn/utils.py +8 -8
- sknetwork/hierarchy/base.py +27 -0
- sknetwork/hierarchy/louvain_hierarchy.py +55 -47
- sknetwork/hierarchy/paris.cp310-win_amd64.pyd +0 -0
- sknetwork/hierarchy/paris.cpp +27667 -20915
- sknetwork/hierarchy/paris.pyx +11 -10
- sknetwork/hierarchy/postprocess.py +16 -16
- sknetwork/hierarchy/tests/test_algos.py +5 -0
- sknetwork/hierarchy/tests/test_metrics.py +4 -4
- sknetwork/linalg/__init__.py +1 -1
- sknetwork/linalg/diteration.cp310-win_amd64.pyd +0 -0
- sknetwork/linalg/diteration.cpp +13916 -8050
- sknetwork/linalg/{normalization.py → normalizer.py} +17 -14
- sknetwork/linalg/operators.py +1 -1
- sknetwork/linalg/ppr_solver.py +1 -1
- sknetwork/linalg/push.cp310-win_amd64.pyd +0 -0
- sknetwork/linalg/push.cpp +23187 -16973
- sknetwork/linalg/tests/test_normalization.py +3 -7
- sknetwork/linalg/tests/test_operators.py +2 -6
- sknetwork/linalg/tests/test_ppr.py +1 -1
- sknetwork/linkpred/base.py +12 -1
- sknetwork/linkpred/nn.py +6 -6
- sknetwork/path/distances.py +11 -4
- sknetwork/path/shortest_path.py +1 -1
- sknetwork/path/tests/test_distances.py +7 -0
- sknetwork/path/tests/test_search.py +2 -2
- sknetwork/ranking/base.py +11 -6
- sknetwork/ranking/betweenness.cp310-win_amd64.pyd +0 -0
- sknetwork/ranking/betweenness.cpp +5256 -2190
- sknetwork/ranking/pagerank.py +13 -12
- sknetwork/ranking/tests/test_API.py +0 -2
- sknetwork/ranking/tests/test_betweenness.py +1 -1
- sknetwork/ranking/tests/test_pagerank.py +11 -5
- sknetwork/regression/base.py +18 -1
- sknetwork/regression/diffusion.py +30 -14
- sknetwork/regression/tests/test_diffusion.py +8 -0
- sknetwork/topology/__init__.py +3 -1
- sknetwork/topology/cliques.cp310-win_amd64.pyd +0 -0
- sknetwork/topology/cliques.cpp +23528 -16848
- sknetwork/topology/core.cp310-win_amd64.pyd +0 -0
- sknetwork/topology/core.cpp +22849 -16581
- sknetwork/topology/cycles.py +243 -0
- sknetwork/topology/minheap.cp310-win_amd64.pyd +0 -0
- sknetwork/topology/minheap.cpp +19495 -13469
- sknetwork/topology/structure.py +2 -42
- sknetwork/topology/tests/test_cycles.py +65 -0
- sknetwork/topology/tests/test_structure.py +2 -16
- sknetwork/topology/triangles.cp310-win_amd64.pyd +0 -0
- sknetwork/topology/triangles.cpp +5283 -1397
- sknetwork/topology/triangles.pyx +7 -4
- sknetwork/topology/weisfeiler_lehman_core.cp310-win_amd64.pyd +0 -0
- sknetwork/topology/weisfeiler_lehman_core.cpp +14781 -8915
- sknetwork/utils/__init__.py +1 -1
- sknetwork/utils/format.py +1 -1
- sknetwork/utils/membership.py +2 -2
- sknetwork/utils/values.py +5 -3
- sknetwork/visualization/__init__.py +2 -2
- sknetwork/visualization/dendrograms.py +55 -7
- sknetwork/visualization/graphs.py +261 -44
- sknetwork/visualization/tests/test_dendrograms.py +9 -9
- sknetwork/visualization/tests/test_graphs.py +63 -57
- scikit_network-0.31.0.dist-info/RECORD +0 -221
- sknetwork/embedding/louvain_hierarchy.py +0 -142
- sknetwork/embedding/tests/test_louvain_hierarchy.py +0 -19
- {scikit_network-0.31.0.dist-info → scikit_network-0.33.0.dist-info}/LICENSE +0 -0
- {scikit_network-0.31.0.dist-info → scikit_network-0.33.0.dist-info}/top_level.txt +0 -0
sknetwork/ranking/pagerank.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
"""
|
|
4
|
-
Created
|
|
4
|
+
Created in May 2019
|
|
5
5
|
@author: Nathan de Lara <nathan.delara@polytechnique.org>
|
|
6
6
|
@author: Thomas Bonald <bonald@enst.fr>
|
|
7
7
|
"""
|
|
@@ -9,7 +9,6 @@ from typing import Union, Optional
|
|
|
9
9
|
|
|
10
10
|
import numpy as np
|
|
11
11
|
from scipy import sparse
|
|
12
|
-
from scipy.sparse.linalg import LinearOperator
|
|
13
12
|
|
|
14
13
|
from sknetwork.linalg.ppr_solver import get_pagerank
|
|
15
14
|
from sknetwork.ranking.base import BaseRanking
|
|
@@ -73,24 +72,26 @@ class PageRank(BaseRanking):
|
|
|
73
72
|
self.tol = tol
|
|
74
73
|
self.bipartite = None
|
|
75
74
|
|
|
76
|
-
def fit(self, input_matrix: Union[sparse.csr_matrix, np.ndarray
|
|
75
|
+
def fit(self, input_matrix: Union[sparse.csr_matrix, np.ndarray],
|
|
77
76
|
weights: Optional[Union[dict, np.ndarray]] = None, weights_row: Optional[Union[dict, np.ndarray]] = None,
|
|
78
77
|
weights_col: Optional[Union[dict, np.ndarray]] = None, force_bipartite: bool = False) -> 'PageRank':
|
|
79
|
-
"""
|
|
78
|
+
"""Compute the pagerank of each node.
|
|
80
79
|
|
|
81
80
|
Parameters
|
|
82
81
|
----------
|
|
83
|
-
input_matrix :
|
|
82
|
+
input_matrix : sparse.csr_matrix, np.ndarray
|
|
84
83
|
Adjacency matrix or biadjacency matrix of the graph.
|
|
85
|
-
weights :
|
|
86
|
-
|
|
87
|
-
Restart distribution as a vector or a dict (node: weight).
|
|
84
|
+
weights : np.ndarray, dict
|
|
85
|
+
Weights of the restart distribution for Personalized PageRank.
|
|
88
86
|
If ``None``, the uniform distribution is used (no personalization, default).
|
|
89
|
-
weights_row,
|
|
90
|
-
|
|
91
|
-
|
|
87
|
+
weights_row : np.ndarray, dict
|
|
88
|
+
Weights on rows of the restart distribution for Personalized PageRank.
|
|
89
|
+
Used for bipartite graphs.
|
|
92
90
|
If both weights_row and weights_col are ``None`` (default), the uniform distribution on rows is used.
|
|
93
|
-
|
|
91
|
+
weights_col : np.ndarray, dict
|
|
92
|
+
Weights on columns of the restart distribution for Personalized PageRank.
|
|
93
|
+
Used for bipartite graphs.
|
|
94
|
+
force_bipartite : bool
|
|
94
95
|
If ``True``, consider the input matrix as the biadjacency matrix of a bipartite graph.
|
|
95
96
|
Returns
|
|
96
97
|
-------
|
|
@@ -17,8 +17,6 @@ class TestPageRank(unittest.TestCase):
|
|
|
17
17
|
score = method.fit_predict(adjacency)
|
|
18
18
|
self.assertEqual(score.shape, (n, ))
|
|
19
19
|
self.assertTrue(min(score) >= 0)
|
|
20
|
-
score = method.fit_transform(adjacency)
|
|
21
|
-
self.assertEqual(score.shape, (n,))
|
|
22
20
|
|
|
23
21
|
def test_bipartite(self):
|
|
24
22
|
biadjacency = test_bigraph()
|
|
@@ -7,7 +7,7 @@ import unittest
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
|
|
9
9
|
from sknetwork.data.models import cyclic_digraph
|
|
10
|
-
from sknetwork.data.test_graphs import test_bigraph
|
|
10
|
+
from sknetwork.data.test_graphs import test_graph, test_digraph, test_bigraph
|
|
11
11
|
from sknetwork.ranking.pagerank import PageRank
|
|
12
12
|
|
|
13
13
|
|
|
@@ -37,8 +37,8 @@ class TestPageRank(unittest.TestCase):
|
|
|
37
37
|
seeds_array[0] = 1.
|
|
38
38
|
seeds_dict = {0: 1}
|
|
39
39
|
|
|
40
|
-
scores1 = pagerank.
|
|
41
|
-
scores2 = pagerank.
|
|
40
|
+
scores1 = pagerank.fit_predict(self.adjacency, seeds_array)
|
|
41
|
+
scores2 = pagerank.fit_predict(self.adjacency, seeds_dict)
|
|
42
42
|
self.assertAlmostEqual(np.linalg.norm(scores1 - scores2), 0.)
|
|
43
43
|
|
|
44
44
|
def test_input(self):
|
|
@@ -48,9 +48,15 @@ class TestPageRank(unittest.TestCase):
|
|
|
48
48
|
|
|
49
49
|
def test_damping(self):
|
|
50
50
|
pagerank = PageRank(damping_factor=0.99)
|
|
51
|
-
scores = pagerank.
|
|
51
|
+
scores = pagerank.fit_predict(self.adjacency)
|
|
52
52
|
self.assertAlmostEqual(np.linalg.norm(scores - self.truth), 0.)
|
|
53
53
|
|
|
54
54
|
pagerank = PageRank(damping_factor=0.01)
|
|
55
|
-
scores = pagerank.
|
|
55
|
+
scores = pagerank.fit_predict(self.adjacency)
|
|
56
56
|
self.assertAlmostEqual(np.linalg.norm(scores - self.truth), 0.)
|
|
57
|
+
|
|
58
|
+
def test_bigraph(self):
|
|
59
|
+
pagerank = PageRank()
|
|
60
|
+
for adjacency in [test_graph(), test_digraph(), test_bigraph()]:
|
|
61
|
+
pagerank.fit(adjacency, weights_col={0: 1})
|
|
62
|
+
self.assertAlmostEqual(np.linalg.norm(pagerank.scores_col_ - pagerank.predict(columns=True)), 0.)
|
sknetwork/regression/base.py
CHANGED
|
@@ -26,8 +26,25 @@ class BaseRegressor(Algorithm, ABC):
|
|
|
26
26
|
def __init__(self):
|
|
27
27
|
self.values_ = None
|
|
28
28
|
|
|
29
|
+
def predict(self, columns: bool = False) -> np.ndarray:
|
|
30
|
+
"""Return the values predicted by the algorithm.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
columns : bool
|
|
35
|
+
If ``True``, return the prediction for columns.
|
|
36
|
+
|
|
37
|
+
Returns
|
|
38
|
+
-------
|
|
39
|
+
values : np.ndarray
|
|
40
|
+
Values.
|
|
41
|
+
"""
|
|
42
|
+
if columns:
|
|
43
|
+
return self.values_col_
|
|
44
|
+
return self.values_
|
|
45
|
+
|
|
29
46
|
def fit_predict(self, *args, **kwargs) -> np.ndarray:
|
|
30
|
-
"""Fit algorithm to data and return the
|
|
47
|
+
"""Fit algorithm to data and return the values. Same parameters as the ``fit`` method.
|
|
31
48
|
|
|
32
49
|
Returns
|
|
33
50
|
-------
|
|
@@ -10,9 +10,9 @@ from typing import Union, Optional, Tuple
|
|
|
10
10
|
import numpy as np
|
|
11
11
|
from scipy import sparse
|
|
12
12
|
|
|
13
|
-
from sknetwork.linalg.
|
|
13
|
+
from sknetwork.linalg.normalizer import normalize
|
|
14
14
|
from sknetwork.regression.base import BaseRegressor
|
|
15
|
-
from sknetwork.utils
|
|
15
|
+
from sknetwork.utils import get_adjacency_values, get_degrees
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
def init_temperatures(seeds: np.ndarray, init: Optional[float]) -> Tuple[np.ndarray, np.ndarray]:
|
|
@@ -30,6 +30,12 @@ def init_temperatures(seeds: np.ndarray, init: Optional[float]) -> Tuple[np.ndar
|
|
|
30
30
|
class Diffusion(BaseRegressor):
|
|
31
31
|
"""Regression by diffusion along the edges, given the temperatures of some seed nodes (heat equation).
|
|
32
32
|
|
|
33
|
+
The row vector of tempreatures :math:`T` evolves like:
|
|
34
|
+
|
|
35
|
+
:math:`T \\gets (1-\\alpha) T + \\alpha PT`
|
|
36
|
+
|
|
37
|
+
where :math:`\\alpha` is the damping factor and :math:`P` is the transition matrix of the random walk in the graph.
|
|
38
|
+
|
|
33
39
|
All values are updated, including those of seed nodes (free diffusion).
|
|
34
40
|
See ``Dirichlet`` for diffusion with boundary constraints.
|
|
35
41
|
|
|
@@ -37,6 +43,8 @@ class Diffusion(BaseRegressor):
|
|
|
37
43
|
----------
|
|
38
44
|
n_iter : int
|
|
39
45
|
Number of iterations of the diffusion (must be positive).
|
|
46
|
+
damping_factor : float
|
|
47
|
+
Damping factor.
|
|
40
48
|
|
|
41
49
|
Attributes
|
|
42
50
|
----------
|
|
@@ -49,29 +57,31 @@ class Diffusion(BaseRegressor):
|
|
|
49
57
|
Example
|
|
50
58
|
-------
|
|
51
59
|
>>> from sknetwork.data import house
|
|
52
|
-
>>> diffusion = Diffusion(n_iter=
|
|
60
|
+
>>> diffusion = Diffusion(n_iter=1)
|
|
53
61
|
>>> adjacency = house()
|
|
54
62
|
>>> values = {0: 1, 2: 0}
|
|
55
63
|
>>> values_pred = diffusion.fit_predict(adjacency, values)
|
|
56
|
-
>>> np.round(values_pred,
|
|
57
|
-
array([0.
|
|
64
|
+
>>> np.round(values_pred, 1)
|
|
65
|
+
array([0.8, 0.5, 0.2, 0.4, 0.6])
|
|
58
66
|
|
|
59
67
|
References
|
|
60
68
|
----------
|
|
61
69
|
Chung, F. (2007). The heat kernel as the pagerank of a graph. Proceedings of the National Academy of Sciences.
|
|
62
70
|
"""
|
|
63
|
-
def __init__(self, n_iter: int = 3):
|
|
71
|
+
def __init__(self, n_iter: int = 3, damping_factor: float = 0.5):
|
|
64
72
|
super(Diffusion, self).__init__()
|
|
65
73
|
|
|
66
74
|
if n_iter <= 0:
|
|
67
75
|
raise ValueError('The number of iterations must be positive.')
|
|
68
76
|
else:
|
|
69
77
|
self.n_iter = n_iter
|
|
78
|
+
self.damping_factor = damping_factor
|
|
70
79
|
self.bipartite = None
|
|
71
80
|
|
|
72
81
|
def fit(self, input_matrix: Union[sparse.csr_matrix, np.ndarray],
|
|
73
|
-
values: Optional[Union[dict,
|
|
74
|
-
|
|
82
|
+
values: Optional[Union[dict, list, np.ndarray]] = None,
|
|
83
|
+
values_row: Optional[Union[dict, list, np.ndarray]] = None,
|
|
84
|
+
values_col: Optional[Union[dict, list, np.ndarray]] = None, init: Optional[float] = None,
|
|
75
85
|
force_bipartite: bool = False) -> 'Diffusion':
|
|
76
86
|
"""Compute the diffusion (temperatures at equilibrium).
|
|
77
87
|
|
|
@@ -98,7 +108,13 @@ class Diffusion(BaseRegressor):
|
|
|
98
108
|
values_row=values_row,
|
|
99
109
|
values_col=values_col)
|
|
100
110
|
values, _ = init_temperatures(values, init)
|
|
101
|
-
diffusion = normalize(adjacency)
|
|
111
|
+
diffusion = normalize(adjacency.T.tocsr())
|
|
112
|
+
degrees = get_degrees(diffusion)
|
|
113
|
+
diag = sparse.diags((degrees == 0).astype(int)).tocsr()
|
|
114
|
+
diffusion += diag
|
|
115
|
+
|
|
116
|
+
diffusion = (1 - self.damping_factor) * sparse.identity(len(degrees)).tocsr() + self.damping_factor * diffusion
|
|
117
|
+
|
|
102
118
|
for i in range(self.n_iter):
|
|
103
119
|
values = diffusion.dot(values)
|
|
104
120
|
|
|
@@ -110,10 +126,9 @@ class Diffusion(BaseRegressor):
|
|
|
110
126
|
|
|
111
127
|
|
|
112
128
|
class Dirichlet(BaseRegressor):
|
|
113
|
-
"""Regression by the Dirichlet problem
|
|
114
|
-
(heat diffusion with boundary constraints).
|
|
129
|
+
"""Regression by the Dirichlet problem (heat diffusion with boundary constraints).
|
|
115
130
|
|
|
116
|
-
|
|
131
|
+
The temperatures of some seed nodes are fixed. The temperatures of other nodes are computed.
|
|
117
132
|
|
|
118
133
|
Parameters
|
|
119
134
|
----------
|
|
@@ -153,8 +168,9 @@ class Dirichlet(BaseRegressor):
|
|
|
153
168
|
self.bipartite = None
|
|
154
169
|
|
|
155
170
|
def fit(self, input_matrix: Union[sparse.csr_matrix, np.ndarray],
|
|
156
|
-
values: Optional[Union[dict,
|
|
157
|
-
|
|
171
|
+
values: Optional[Union[dict, list, np.ndarray]] = None,
|
|
172
|
+
values_row: Optional[Union[dict, list, np.ndarray]] = None,
|
|
173
|
+
values_col: Optional[Union[dict, list, np.ndarray]] = None, init: Optional[float] = None,
|
|
158
174
|
force_bipartite: bool = False) -> 'Dirichlet':
|
|
159
175
|
"""Compute the solution to the Dirichlet problem (temperatures at equilibrium).
|
|
160
176
|
|
|
@@ -14,6 +14,13 @@ class TestDiffusion(unittest.TestCase):
|
|
|
14
14
|
def setUp(self):
|
|
15
15
|
self.algos = [Diffusion(), Dirichlet()]
|
|
16
16
|
|
|
17
|
+
def test_predict(self):
|
|
18
|
+
adjacency = test_graph()
|
|
19
|
+
for algo in self.algos:
|
|
20
|
+
values = algo.fit_predict(adjacency, {0: 0, 1: 1, 2: 0.5})
|
|
21
|
+
values_ = algo.predict()
|
|
22
|
+
self.assertAlmostEqual(np.linalg.norm(values - values_), 0)
|
|
23
|
+
|
|
17
24
|
def test_no_iter(self):
|
|
18
25
|
with self.assertRaises(ValueError):
|
|
19
26
|
Diffusion(n_iter=-1)
|
|
@@ -35,6 +42,7 @@ class TestDiffusion(unittest.TestCase):
|
|
|
35
42
|
self.assertTrue(np.all(values <= 1) and np.all(values >= 0))
|
|
36
43
|
values = algo.fit_predict(biadjacency, values_row={0: 0.1}, values_col={1: 2}, init=0.3)
|
|
37
44
|
self.assertTrue(np.all(values <= 2) and np.all(values >= 0.1))
|
|
45
|
+
self.assertAlmostEqual(np.linalg.norm(algo.values_col_ - algo.predict(columns=True)), 0)
|
|
38
46
|
|
|
39
47
|
def test_initial_state(self):
|
|
40
48
|
for adjacency in [test_graph(), test_digraph()]:
|
sknetwork/topology/__init__.py
CHANGED
|
@@ -2,5 +2,7 @@
|
|
|
2
2
|
from sknetwork.topology.cliques import count_cliques
|
|
3
3
|
from sknetwork.topology.core import get_core_decomposition
|
|
4
4
|
from sknetwork.topology.triangles import count_triangles, get_clustering_coefficient
|
|
5
|
-
from sknetwork.topology.structure import
|
|
5
|
+
from sknetwork.topology.structure import is_connected, is_bipartite, is_symmetric, get_connected_components, \
|
|
6
|
+
get_largest_connected_component
|
|
7
|
+
from sknetwork.topology.cycles import is_acyclic, get_cycles, break_cycles
|
|
6
8
|
from sknetwork.topology.weisfeiler_lehman import color_weisfeiler_lehman, are_isomorphic
|
|
Binary file
|