Spaces:
Running
Running
"""Connected components.""" | |
import networkx as nx | |
from networkx.utils.decorators import not_implemented_for | |
from ...utils import arbitrary_element | |
__all__ = [ | |
"number_connected_components", | |
"connected_components", | |
"is_connected", | |
"node_connected_component", | |
] | |
def connected_components(G): | |
"""Generate connected components. | |
Parameters | |
---------- | |
G : NetworkX graph | |
An undirected graph | |
Returns | |
------- | |
comp : generator of sets | |
A generator of sets of nodes, one for each component of G. | |
Raises | |
------ | |
NetworkXNotImplemented | |
If G is directed. | |
Examples | |
-------- | |
Generate a sorted list of connected components, largest first. | |
>>> G = nx.path_graph(4) | |
>>> nx.add_path(G, [10, 11, 12]) | |
>>> [len(c) for c in sorted(nx.connected_components(G), key=len, reverse=True)] | |
[4, 3] | |
If you only want the largest connected component, it's more | |
efficient to use max instead of sort. | |
>>> largest_cc = max(nx.connected_components(G), key=len) | |
To create the induced subgraph of each component use: | |
>>> S = [G.subgraph(c).copy() for c in nx.connected_components(G)] | |
See Also | |
-------- | |
strongly_connected_components | |
weakly_connected_components | |
Notes | |
----- | |
For undirected graphs only. | |
""" | |
seen = set() | |
for v in G: | |
if v not in seen: | |
c = _plain_bfs(G, v) | |
seen.update(c) | |
yield c | |
def number_connected_components(G): | |
"""Returns the number of connected components. | |
Parameters | |
---------- | |
G : NetworkX graph | |
An undirected graph. | |
Returns | |
------- | |
n : integer | |
Number of connected components | |
Examples | |
-------- | |
>>> G = nx.Graph([(0, 1), (1, 2), (5, 6), (3, 4)]) | |
>>> nx.number_connected_components(G) | |
3 | |
See Also | |
-------- | |
connected_components | |
number_weakly_connected_components | |
number_strongly_connected_components | |
Notes | |
----- | |
For undirected graphs only. | |
""" | |
return sum(1 for cc in connected_components(G)) | |
def is_connected(G): | |
"""Returns True if the graph is connected, False otherwise. | |
Parameters | |
---------- | |
G : NetworkX Graph | |
An undirected graph. | |
Returns | |
------- | |
connected : bool | |
True if the graph is connected, false otherwise. | |
Raises | |
------ | |
NetworkXNotImplemented | |
If G is directed. | |
Examples | |
-------- | |
>>> G = nx.path_graph(4) | |
>>> print(nx.is_connected(G)) | |
True | |
See Also | |
-------- | |
is_strongly_connected | |
is_weakly_connected | |
is_semiconnected | |
is_biconnected | |
connected_components | |
Notes | |
----- | |
For undirected graphs only. | |
""" | |
if len(G) == 0: | |
raise nx.NetworkXPointlessConcept( | |
"Connectivity is undefined ", "for the null graph." | |
) | |
return sum(1 for node in _plain_bfs(G, arbitrary_element(G))) == len(G) | |
def node_connected_component(G, n): | |
"""Returns the set of nodes in the component of graph containing node n. | |
Parameters | |
---------- | |
G : NetworkX Graph | |
An undirected graph. | |
n : node label | |
A node in G | |
Returns | |
------- | |
comp : set | |
A set of nodes in the component of G containing node n. | |
Raises | |
------ | |
NetworkXNotImplemented | |
If G is directed. | |
Examples | |
-------- | |
>>> G = nx.Graph([(0, 1), (1, 2), (5, 6), (3, 4)]) | |
>>> nx.node_connected_component(G, 0) # nodes of component that contains node 0 | |
{0, 1, 2} | |
See Also | |
-------- | |
connected_components | |
Notes | |
----- | |
For undirected graphs only. | |
""" | |
return _plain_bfs(G, n) | |
def _plain_bfs(G, source): | |
"""A fast BFS node generator""" | |
adj = G._adj | |
n = len(adj) | |
seen = {source} | |
nextlevel = [source] | |
while nextlevel: | |
thislevel = nextlevel | |
nextlevel = [] | |
for v in thislevel: | |
for w in adj[v]: | |
if w not in seen: | |
seen.add(w) | |
nextlevel.append(w) | |
if len(seen) == n: | |
return seen | |
return seen | |