Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/networkx/algorithms/components/connected.py: 40%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

45 statements  

1"""Connected components.""" 

2 

3import networkx as nx 

4from networkx.utils.decorators import not_implemented_for 

5 

6from ...utils import arbitrary_element 

7 

8__all__ = [ 

9 "number_connected_components", 

10 "connected_components", 

11 "is_connected", 

12 "node_connected_component", 

13] 

14 

15 

16@not_implemented_for("directed") 

17@nx._dispatchable 

18def connected_components(G): 

19 """Generate connected components. 

20 

21 The connected components of an undirected graph partition the graph into 

22 disjoint sets of nodes. Each of these sets induces a subgraph of graph 

23 `G` that is connected and not part of any larger connected subgraph. 

24 

25 A graph is connected (:func:`is_connected`) if, for every pair of distinct 

26 nodes, there is a path between them. If there is a pair of nodes for 

27 which such path does not exist, the graph is not connected (also referred 

28 to as "disconnected"). 

29 

30 A graph consisting of a single node and no edges is connected. 

31 Connectivity is undefined for the null graph (graph with no nodes). 

32 

33 Parameters 

34 ---------- 

35 G : NetworkX graph 

36 An undirected graph 

37 

38 Yields 

39 ------ 

40 comp : set 

41 A set of nodes in one connected component of the graph. 

42 

43 Raises 

44 ------ 

45 NetworkXNotImplemented 

46 If G is directed. 

47 

48 Examples 

49 -------- 

50 Generate a sorted list of connected components, largest first. 

51 

52 >>> G = nx.path_graph(4) 

53 >>> nx.add_path(G, [10, 11, 12]) 

54 >>> [len(c) for c in sorted(nx.connected_components(G), key=len, reverse=True)] 

55 [4, 3] 

56 

57 If you only want the largest connected component, it's more 

58 efficient to use max instead of sort. 

59 

60 >>> largest_cc = max(nx.connected_components(G), key=len) 

61 

62 To create the induced subgraph of each component use: 

63 

64 >>> S = [G.subgraph(c).copy() for c in nx.connected_components(G)] 

65 

66 See Also 

67 -------- 

68 number_connected_components 

69 is_connected 

70 number_weakly_connected_components 

71 number_strongly_connected_components 

72 

73 Notes 

74 ----- 

75 This function is for undirected graphs only. For directed graphs, use 

76 :func:`strongly_connected_components` or 

77 :func:`weakly_connected_components`. 

78 

79 The algorithm is based on a Breadth-First Search (BFS) traversal and its 

80 time complexity is $O(n + m)$, where $n$ is the number of nodes and $m$ the 

81 number of edges in the graph. 

82 

83 """ 

84 seen = set() 

85 n = len(G) # must be outside the loop to avoid performance hit with graph views 

86 for v in G: 

87 if v not in seen: 

88 c = _plain_bfs(G, n - len(seen), v) 

89 seen.update(c) 

90 yield c 

91 

92 

93@not_implemented_for("directed") 

94@nx._dispatchable 

95def number_connected_components(G): 

96 """Returns the number of connected components. 

97 

98 The connected components of an undirected graph partition the graph into 

99 disjoint sets of nodes. Each of these sets induces a subgraph of graph 

100 `G` that is connected and not part of any larger connected subgraph. 

101 

102 A graph is connected (:func:`is_connected`) if, for every pair of distinct 

103 nodes, there is a path between them. If there is a pair of nodes for 

104 which such path does not exist, the graph is not connected (also referred 

105 to as "disconnected"). 

106 

107 A graph consisting of a single node and no edges is connected. 

108 Connectivity is undefined for the null graph (graph with no nodes). 

109 

110 Parameters 

111 ---------- 

112 G : NetworkX graph 

113 An undirected graph. 

114 

115 Returns 

116 ------- 

117 n : integer 

118 Number of connected components 

119 

120 Raises 

121 ------ 

122 NetworkXNotImplemented 

123 If G is directed. 

124 

125 Examples 

126 -------- 

127 >>> G = nx.Graph([(0, 1), (1, 2), (5, 6), (3, 4)]) 

128 >>> nx.number_connected_components(G) 

129 3 

130 

131 See Also 

132 -------- 

133 connected_components 

134 is_connected 

135 number_weakly_connected_components 

136 number_strongly_connected_components 

137 

138 Notes 

139 ----- 

140 This function is for undirected graphs only. For directed graphs, use 

141 :func:`number_strongly_connected_components` or 

142 :func:`number_weakly_connected_components`. 

143 

144 The algorithm is based on a Breadth-First Search (BFS) traversal and its 

145 time complexity is $O(n + m)$, where $n$ is the number of nodes and $m$ the 

146 number of edges in the graph. 

147 

148 """ 

149 return sum(1 for _ in connected_components(G)) 

150 

151 

152@not_implemented_for("directed") 

153@nx._dispatchable 

154def is_connected(G): 

155 """Returns True if the graph is connected, False otherwise. 

156 

157 A graph is connected if, for every pair of distinct nodes, there is a 

158 path between them. If there is a pair of nodes for which such path does 

159 not exist, the graph is not connected (also referred to as "disconnected"). 

160 

161 A graph consisting of a single node and no edges is connected. 

162 Connectivity is undefined for the null graph (graph with no nodes). 

163 

164 Parameters 

165 ---------- 

166 G : NetworkX Graph 

167 An undirected graph. 

168 

169 Returns 

170 ------- 

171 connected : bool 

172 True if the graph is connected, False otherwise. 

173 

174 Raises 

175 ------ 

176 NetworkXNotImplemented 

177 If G is directed. 

178 

179 Examples 

180 -------- 

181 >>> G = nx.path_graph(4) 

182 >>> print(nx.is_connected(G)) 

183 True 

184 

185 See Also 

186 -------- 

187 is_strongly_connected 

188 is_weakly_connected 

189 is_semiconnected 

190 is_biconnected 

191 connected_components 

192 

193 Notes 

194 ----- 

195 This function is for undirected graphs only. For directed graphs, use 

196 :func:`is_strongly_connected` or :func:`is_weakly_connected`. 

197 

198 The algorithm is based on a Breadth-First Search (BFS) traversal and its 

199 time complexity is $O(n + m)$, where $n$ is the number of nodes and $m$ the 

200 number of edges in the graph. 

201 

202 """ 

203 n = len(G) 

204 if n == 0: 

205 raise nx.NetworkXPointlessConcept( 

206 "Connectivity is undefined for the null graph." 

207 ) 

208 return len(next(connected_components(G))) == n 

209 

210 

211@not_implemented_for("directed") 

212@nx._dispatchable 

213def node_connected_component(G, n): 

214 """Returns the set of nodes in the component of graph containing node n. 

215 

216 A connected component is a set of nodes that induces a subgraph of graph 

217 `G` that is connected and not part of any larger connected subgraph. 

218 

219 A graph is connected (:func:`is_connected`) if, for every pair of distinct 

220 nodes, there is a path between them. If there is a pair of nodes for 

221 which such path does not exist, the graph is not connected (also referred 

222 to as "disconnected"). 

223 

224 A graph consisting of a single node and no edges is connected. 

225 Connectivity is undefined for the null graph (graph with no nodes). 

226 

227 Parameters 

228 ---------- 

229 G : NetworkX Graph 

230 An undirected graph. 

231 

232 n : node label 

233 A node in G 

234 

235 Returns 

236 ------- 

237 comp : set 

238 A set of nodes in the component of G containing node n. 

239 

240 Raises 

241 ------ 

242 NetworkXNotImplemented 

243 If G is directed. 

244 

245 Examples 

246 -------- 

247 >>> G = nx.Graph([(0, 1), (1, 2), (5, 6), (3, 4)]) 

248 >>> nx.node_connected_component(G, 0) # nodes of component that contains node 0 

249 {0, 1, 2} 

250 

251 See Also 

252 -------- 

253 connected_components 

254 

255 Notes 

256 ----- 

257 This function is for undirected graphs only. 

258 

259 The algorithm is based on a Breadth-First Search (BFS) traversal and its 

260 time complexity is $O(n + m)$, where $n$ is the number of nodes and $m$ the 

261 number of edges in the graph. 

262 

263 """ 

264 return _plain_bfs(G, len(G), n) 

265 

266 

267def _plain_bfs(G, n, source): 

268 """A fast BFS node generator""" 

269 adj = G._adj 

270 seen = {source} 

271 nextlevel = [source] 

272 while nextlevel: 

273 thislevel = nextlevel 

274 nextlevel = [] 

275 for v in thislevel: 

276 for w in adj[v]: 

277 if w not in seen: 

278 seen.add(w) 

279 nextlevel.append(w) 

280 if len(seen) == n: 

281 return seen 

282 return seen