File size: 4,366 Bytes
f911107 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
"""Weakly connected components."""
import networkx as nx
from networkx.utils.decorators import not_implemented_for
__all__ = [
"number_weakly_connected_components",
"weakly_connected_components",
"is_weakly_connected",
]
@not_implemented_for("undirected")
@nx._dispatch
def weakly_connected_components(G):
"""Generate weakly connected components of G.
Parameters
----------
G : NetworkX graph
A directed graph
Returns
-------
comp : generator of sets
A generator of sets of nodes, one for each weakly connected
component of G.
Raises
------
NetworkXNotImplemented
If G is undirected.
Examples
--------
Generate a sorted list of weakly connected components, largest first.
>>> G = nx.path_graph(4, create_using=nx.DiGraph())
>>> nx.add_path(G, [10, 11, 12])
>>> [
... len(c)
... for c in sorted(nx.weakly_connected_components(G), key=len, reverse=True)
... ]
[4, 3]
If you only want the largest component, it's more efficient to
use max instead of sort:
>>> largest_cc = max(nx.weakly_connected_components(G), key=len)
See Also
--------
connected_components
strongly_connected_components
Notes
-----
For directed graphs only.
"""
seen = set()
for v in G:
if v not in seen:
c = set(_plain_bfs(G, v))
seen.update(c)
yield c
@not_implemented_for("undirected")
@nx._dispatch
def number_weakly_connected_components(G):
"""Returns the number of weakly connected components in G.
Parameters
----------
G : NetworkX graph
A directed graph.
Returns
-------
n : integer
Number of weakly connected components
Raises
------
NetworkXNotImplemented
If G is undirected.
Examples
--------
>>> G = nx.DiGraph([(0, 1), (2, 1), (3, 4)])
>>> nx.number_weakly_connected_components(G)
2
See Also
--------
weakly_connected_components
number_connected_components
number_strongly_connected_components
Notes
-----
For directed graphs only.
"""
return sum(1 for wcc in weakly_connected_components(G))
@not_implemented_for("undirected")
@nx._dispatch
def is_weakly_connected(G):
"""Test directed graph for weak connectivity.
A directed graph is weakly connected if and only if the graph
is connected when the direction of the edge between nodes is ignored.
Note that if a graph is strongly connected (i.e. the graph is connected
even when we account for directionality), it is by definition weakly
connected as well.
Parameters
----------
G : NetworkX Graph
A directed graph.
Returns
-------
connected : bool
True if the graph is weakly connected, False otherwise.
Raises
------
NetworkXNotImplemented
If G is undirected.
Examples
--------
>>> G = nx.DiGraph([(0, 1), (2, 1)])
>>> G.add_node(3)
>>> nx.is_weakly_connected(G) # node 3 is not connected to the graph
False
>>> G.add_edge(2, 3)
>>> nx.is_weakly_connected(G)
True
See Also
--------
is_strongly_connected
is_semiconnected
is_connected
is_biconnected
weakly_connected_components
Notes
-----
For directed graphs only.
"""
if len(G) == 0:
raise nx.NetworkXPointlessConcept(
"""Connectivity is undefined for the null graph."""
)
return len(next(weakly_connected_components(G))) == len(G)
def _plain_bfs(G, source):
"""A fast BFS node generator
The direction of the edge between nodes is ignored.
For directed graphs only.
"""
n = len(G)
Gsucc = G._succ
Gpred = G._pred
seen = {source}
nextlevel = [source]
yield source
while nextlevel:
thislevel = nextlevel
nextlevel = []
for v in thislevel:
for w in Gsucc[v]:
if w not in seen:
seen.add(w)
nextlevel.append(w)
yield w
for w in Gpred[v]:
if w not in seen:
seen.add(w)
nextlevel.append(w)
yield w
if len(seen) == n:
return
|