Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/networkx/algorithms/cuts.py: 40%

47 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-10-20 07:00 +0000

1"""Functions for finding and evaluating cuts in a graph. 

2 

3""" 

4 

5from itertools import chain 

6 

7import networkx as nx 

8 

9__all__ = [ 

10 "boundary_expansion", 

11 "conductance", 

12 "cut_size", 

13 "edge_expansion", 

14 "mixing_expansion", 

15 "node_expansion", 

16 "normalized_cut_size", 

17 "volume", 

18] 

19 

20 

21# TODO STILL NEED TO UPDATE ALL THE DOCUMENTATION! 

22 

23 

24@nx._dispatch(edge_attrs="weight") 

25def cut_size(G, S, T=None, weight=None): 

26 """Returns the size of the cut between two sets of nodes. 

27 

28 A *cut* is a partition of the nodes of a graph into two sets. The 

29 *cut size* is the sum of the weights of the edges "between" the two 

30 sets of nodes. 

31 

32 Parameters 

33 ---------- 

34 G : NetworkX graph 

35 

36 S : collection 

37 A collection of nodes in `G`. 

38 

39 T : collection 

40 A collection of nodes in `G`. If not specified, this is taken to 

41 be the set complement of `S`. 

42 

43 weight : object 

44 Edge attribute key to use as weight. If not specified, edges 

45 have weight one. 

46 

47 Returns 

48 ------- 

49 number 

50 Total weight of all edges from nodes in set `S` to nodes in 

51 set `T` (and, in the case of directed graphs, all edges from 

52 nodes in `T` to nodes in `S`). 

53 

54 Examples 

55 -------- 

56 In the graph with two cliques joined by a single edges, the natural 

57 bipartition of the graph into two blocks, one for each clique, 

58 yields a cut of weight one:: 

59 

60 >>> G = nx.barbell_graph(3, 0) 

61 >>> S = {0, 1, 2} 

62 >>> T = {3, 4, 5} 

63 >>> nx.cut_size(G, S, T) 

64 1 

65 

66 Each parallel edge in a multigraph is counted when determining the 

67 cut size:: 

68 

69 >>> G = nx.MultiGraph(["ab", "ab"]) 

70 >>> S = {"a"} 

71 >>> T = {"b"} 

72 >>> nx.cut_size(G, S, T) 

73 2 

74 

75 Notes 

76 ----- 

77 In a multigraph, the cut size is the total weight of edges including 

78 multiplicity. 

79 

80 """ 

81 edges = nx.edge_boundary(G, S, T, data=weight, default=1) 

82 if G.is_directed(): 

83 edges = chain(edges, nx.edge_boundary(G, T, S, data=weight, default=1)) 

84 return sum(weight for u, v, weight in edges) 

85 

86 

87@nx._dispatch(edge_attrs="weight") 

88def volume(G, S, weight=None): 

89 """Returns the volume of a set of nodes. 

90 

91 The *volume* of a set *S* is the sum of the (out-)degrees of nodes 

92 in *S* (taking into account parallel edges in multigraphs). [1] 

93 

94 Parameters 

95 ---------- 

96 G : NetworkX graph 

97 

98 S : collection 

99 A collection of nodes in `G`. 

100 

101 weight : object 

102 Edge attribute key to use as weight. If not specified, edges 

103 have weight one. 

104 

105 Returns 

106 ------- 

107 number 

108 The volume of the set of nodes represented by `S` in the graph 

109 `G`. 

110 

111 See also 

112 -------- 

113 conductance 

114 cut_size 

115 edge_expansion 

116 edge_boundary 

117 normalized_cut_size 

118 

119 References 

120 ---------- 

121 .. [1] David Gleich. 

122 *Hierarchical Directed Spectral Graph Partitioning*. 

123 <https://www.cs.purdue.edu/homes/dgleich/publications/Gleich%202005%20-%20hierarchical%20directed%20spectral.pdf> 

124 

125 """ 

126 degree = G.out_degree if G.is_directed() else G.degree 

127 return sum(d for v, d in degree(S, weight=weight)) 

128 

129 

130@nx._dispatch(edge_attrs="weight") 

131def normalized_cut_size(G, S, T=None, weight=None): 

132 """Returns the normalized size of the cut between two sets of nodes. 

133 

134 The *normalized cut size* is the cut size times the sum of the 

135 reciprocal sizes of the volumes of the two sets. [1] 

136 

137 Parameters 

138 ---------- 

139 G : NetworkX graph 

140 

141 S : collection 

142 A collection of nodes in `G`. 

143 

144 T : collection 

145 A collection of nodes in `G`. 

146 

147 weight : object 

148 Edge attribute key to use as weight. If not specified, edges 

149 have weight one. 

150 

151 Returns 

152 ------- 

153 number 

154 The normalized cut size between the two sets `S` and `T`. 

155 

156 Notes 

157 ----- 

158 In a multigraph, the cut size is the total weight of edges including 

159 multiplicity. 

160 

161 See also 

162 -------- 

163 conductance 

164 cut_size 

165 edge_expansion 

166 volume 

167 

168 References 

169 ---------- 

170 .. [1] David Gleich. 

171 *Hierarchical Directed Spectral Graph Partitioning*. 

172 <https://www.cs.purdue.edu/homes/dgleich/publications/Gleich%202005%20-%20hierarchical%20directed%20spectral.pdf> 

173 

174 """ 

175 if T is None: 

176 T = set(G) - set(S) 

177 num_cut_edges = cut_size(G, S, T=T, weight=weight) 

178 volume_S = volume(G, S, weight=weight) 

179 volume_T = volume(G, T, weight=weight) 

180 return num_cut_edges * ((1 / volume_S) + (1 / volume_T)) 

181 

182 

183@nx._dispatch(edge_attrs="weight") 

184def conductance(G, S, T=None, weight=None): 

185 """Returns the conductance of two sets of nodes. 

186 

187 The *conductance* is the quotient of the cut size and the smaller of 

188 the volumes of the two sets. [1] 

189 

190 Parameters 

191 ---------- 

192 G : NetworkX graph 

193 

194 S : collection 

195 A collection of nodes in `G`. 

196 

197 T : collection 

198 A collection of nodes in `G`. 

199 

200 weight : object 

201 Edge attribute key to use as weight. If not specified, edges 

202 have weight one. 

203 

204 Returns 

205 ------- 

206 number 

207 The conductance between the two sets `S` and `T`. 

208 

209 See also 

210 -------- 

211 cut_size 

212 edge_expansion 

213 normalized_cut_size 

214 volume 

215 

216 References 

217 ---------- 

218 .. [1] David Gleich. 

219 *Hierarchical Directed Spectral Graph Partitioning*. 

220 <https://www.cs.purdue.edu/homes/dgleich/publications/Gleich%202005%20-%20hierarchical%20directed%20spectral.pdf> 

221 

222 """ 

223 if T is None: 

224 T = set(G) - set(S) 

225 num_cut_edges = cut_size(G, S, T, weight=weight) 

226 volume_S = volume(G, S, weight=weight) 

227 volume_T = volume(G, T, weight=weight) 

228 return num_cut_edges / min(volume_S, volume_T) 

229 

230 

231@nx._dispatch(edge_attrs="weight") 

232def edge_expansion(G, S, T=None, weight=None): 

233 """Returns the edge expansion between two node sets. 

234 

235 The *edge expansion* is the quotient of the cut size and the smaller 

236 of the cardinalities of the two sets. [1] 

237 

238 Parameters 

239 ---------- 

240 G : NetworkX graph 

241 

242 S : collection 

243 A collection of nodes in `G`. 

244 

245 T : collection 

246 A collection of nodes in `G`. 

247 

248 weight : object 

249 Edge attribute key to use as weight. If not specified, edges 

250 have weight one. 

251 

252 Returns 

253 ------- 

254 number 

255 The edge expansion between the two sets `S` and `T`. 

256 

257 See also 

258 -------- 

259 boundary_expansion 

260 mixing_expansion 

261 node_expansion 

262 

263 References 

264 ---------- 

265 .. [1] Fan Chung. 

266 *Spectral Graph Theory*. 

267 (CBMS Regional Conference Series in Mathematics, No. 92), 

268 American Mathematical Society, 1997, ISBN 0-8218-0315-8 

269 <http://www.math.ucsd.edu/~fan/research/revised.html> 

270 

271 """ 

272 if T is None: 

273 T = set(G) - set(S) 

274 num_cut_edges = cut_size(G, S, T=T, weight=weight) 

275 return num_cut_edges / min(len(S), len(T)) 

276 

277 

278@nx._dispatch(edge_attrs="weight") 

279def mixing_expansion(G, S, T=None, weight=None): 

280 """Returns the mixing expansion between two node sets. 

281 

282 The *mixing expansion* is the quotient of the cut size and twice the 

283 number of edges in the graph. [1] 

284 

285 Parameters 

286 ---------- 

287 G : NetworkX graph 

288 

289 S : collection 

290 A collection of nodes in `G`. 

291 

292 T : collection 

293 A collection of nodes in `G`. 

294 

295 weight : object 

296 Edge attribute key to use as weight. If not specified, edges 

297 have weight one. 

298 

299 Returns 

300 ------- 

301 number 

302 The mixing expansion between the two sets `S` and `T`. 

303 

304 See also 

305 -------- 

306 boundary_expansion 

307 edge_expansion 

308 node_expansion 

309 

310 References 

311 ---------- 

312 .. [1] Vadhan, Salil P. 

313 "Pseudorandomness." 

314 *Foundations and Trends 

315 in Theoretical Computer Science* 7.1–3 (2011): 1–336. 

316 <https://doi.org/10.1561/0400000010> 

317 

318 """ 

319 num_cut_edges = cut_size(G, S, T=T, weight=weight) 

320 num_total_edges = G.number_of_edges() 

321 return num_cut_edges / (2 * num_total_edges) 

322 

323 

324# TODO What is the generalization to two arguments, S and T? Does the 

325# denominator become `min(len(S), len(T))`? 

326@nx._dispatch 

327def node_expansion(G, S): 

328 """Returns the node expansion of the set `S`. 

329 

330 The *node expansion* is the quotient of the size of the node 

331 boundary of *S* and the cardinality of *S*. [1] 

332 

333 Parameters 

334 ---------- 

335 G : NetworkX graph 

336 

337 S : collection 

338 A collection of nodes in `G`. 

339 

340 Returns 

341 ------- 

342 number 

343 The node expansion of the set `S`. 

344 

345 See also 

346 -------- 

347 boundary_expansion 

348 edge_expansion 

349 mixing_expansion 

350 

351 References 

352 ---------- 

353 .. [1] Vadhan, Salil P. 

354 "Pseudorandomness." 

355 *Foundations and Trends 

356 in Theoretical Computer Science* 7.1–3 (2011): 1–336. 

357 <https://doi.org/10.1561/0400000010> 

358 

359 """ 

360 neighborhood = set(chain.from_iterable(G.neighbors(v) for v in S)) 

361 return len(neighborhood) / len(S) 

362 

363 

364# TODO What is the generalization to two arguments, S and T? Does the 

365# denominator become `min(len(S), len(T))`? 

366@nx._dispatch 

367def boundary_expansion(G, S): 

368 """Returns the boundary expansion of the set `S`. 

369 

370 The *boundary expansion* is the quotient of the size 

371 of the node boundary and the cardinality of *S*. [1] 

372 

373 Parameters 

374 ---------- 

375 G : NetworkX graph 

376 

377 S : collection 

378 A collection of nodes in `G`. 

379 

380 Returns 

381 ------- 

382 number 

383 The boundary expansion of the set `S`. 

384 

385 See also 

386 -------- 

387 edge_expansion 

388 mixing_expansion 

389 node_expansion 

390 

391 References 

392 ---------- 

393 .. [1] Vadhan, Salil P. 

394 "Pseudorandomness." 

395 *Foundations and Trends in Theoretical Computer Science* 

396 7.1–3 (2011): 1–336. 

397 <https://doi.org/10.1561/0400000010> 

398 

399 """ 

400 return len(nx.node_boundary(G, S)) / len(S)