comparison planemo/lib/python3.7/site-packages/networkx/algorithms/cuts.py @ 1:56ad4e20f292 draft

"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
author guerler
date Fri, 31 Jul 2020 00:32:28 -0400
parents
children
comparison
equal deleted inserted replaced
0:d30785e31577 1:56ad4e20f292
1 # -*- coding: utf-8 -*-
2 # cuts.py - functions for computing and evaluating cuts
3 #
4 # Copyright 2011 Ben Edwards <bedwards@cs.unm.edu>.
5 # Copyright 2011 Aric Hagberg <hagberg@lanl.gov>.
6 # Copyright 2015 NetworkX developers.
7 #
8 # This file is part of NetworkX.
9 #
10 # NetworkX is distributed under a BSD license; see LICENSE.txt for more
11 # information.
12 """Functions for finding and evaluating cuts in a graph.
13
14 """
15
16 from itertools import chain
17
18 import networkx as nx
19
20 __all__ = ['boundary_expansion', 'conductance', 'cut_size', 'edge_expansion',
21 'mixing_expansion', 'node_expansion', 'normalized_cut_size',
22 'volume']
23
24
25 # TODO STILL NEED TO UPDATE ALL THE DOCUMENTATION!
26
27 def cut_size(G, S, T=None, weight=None):
28 """Returns the size of the cut between two sets of nodes.
29
30 A *cut* is a partition of the nodes of a graph into two sets. The
31 *cut size* is the sum of the weights of the edges "between" the two
32 sets of nodes.
33
34 Parameters
35 ----------
36 G : NetworkX graph
37
38 S : sequence
39 A sequence of nodes in `G`.
40
41 T : sequence
42 A sequence of nodes in `G`. If not specified, this is taken to
43 be the set complement of `S`.
44
45 weight : object
46 Edge attribute key to use as weight. If not specified, edges
47 have weight one.
48
49 Returns
50 -------
51 number
52 Total weight of all edges from nodes in set `S` to nodes in
53 set `T` (and, in the case of directed graphs, all edges from
54 nodes in `T` to nodes in `S`).
55
56 Examples
57 --------
58 In the graph with two cliques joined by a single edges, the natural
59 bipartition of the graph into two blocks, one for each clique,
60 yields a cut of weight one::
61
62 >>> G = nx.barbell_graph(3, 0)
63 >>> S = {0, 1, 2}
64 >>> T = {3, 4, 5}
65 >>> nx.cut_size(G, S, T)
66 1
67
68 Each parallel edge in a multigraph is counted when determining the
69 cut size::
70
71 >>> G = nx.MultiGraph(['ab', 'ab'])
72 >>> S = {'a'}
73 >>> T = {'b'}
74 >>> nx.cut_size(G, S, T)
75 2
76
77 Notes
78 -----
79 In a multigraph, the cut size is the total weight of edges including
80 multiplicity.
81
82 """
83 edges = nx.edge_boundary(G, S, T, data=weight, default=1)
84 if G.is_directed():
85 edges = chain(edges, nx.edge_boundary(G, T, S, data=weight, default=1))
86 return sum(weight for u, v, weight in edges)
87
88
89 def volume(G, S, weight=None):
90 """Returns the volume of a set of nodes.
91
92 The *volume* of a set *S* is the sum of the (out-)degrees of nodes
93 in *S* (taking into account parallel edges in multigraphs). [1]
94
95 Parameters
96 ----------
97 G : NetworkX graph
98
99 S : sequence
100 A sequence of nodes in `G`.
101
102 weight : object
103 Edge attribute key to use as weight. If not specified, edges
104 have weight one.
105
106 Returns
107 -------
108 number
109 The volume of the set of nodes represented by `S` in the graph
110 `G`.
111
112 See also
113 --------
114 conductance
115 cut_size
116 edge_expansion
117 edge_boundary
118 normalized_cut_size
119
120 References
121 ----------
122 .. [1] David Gleich.
123 *Hierarchical Directed Spectral Graph Partitioning*.
124 <https://www.cs.purdue.edu/homes/dgleich/publications/Gleich%202005%20-%20hierarchical%20directed%20spectral.pdf>
125
126 """
127 degree = G.out_degree if G.is_directed() else G.degree
128 return sum(d for v, d in degree(S, weight=weight))
129
130
131 def 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 : sequence
142 A sequence of nodes in `G`.
143
144 T : sequence
145 A sequence 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 def conductance(G, S, T=None, weight=None):
184 """Returns the conductance of two sets of nodes.
185
186 The *conductance* is the quotient of the cut size and the smaller of
187 the volumes of the two sets. [1]
188
189 Parameters
190 ----------
191 G : NetworkX graph
192
193 S : sequence
194 A sequence of nodes in `G`.
195
196 T : sequence
197 A sequence of nodes in `G`.
198
199 weight : object
200 Edge attribute key to use as weight. If not specified, edges
201 have weight one.
202
203 Returns
204 -------
205 number
206 The conductance between the two sets `S` and `T`.
207
208 See also
209 --------
210 cut_size
211 edge_expansion
212 normalized_cut_size
213 volume
214
215 References
216 ----------
217 .. [1] David Gleich.
218 *Hierarchical Directed Spectral Graph Partitioning*.
219 <https://www.cs.purdue.edu/homes/dgleich/publications/Gleich%202005%20-%20hierarchical%20directed%20spectral.pdf>
220
221 """
222 if T is None:
223 T = set(G) - set(S)
224 num_cut_edges = cut_size(G, S, T, weight=weight)
225 volume_S = volume(G, S, weight=weight)
226 volume_T = volume(G, T, weight=weight)
227 return num_cut_edges / min(volume_S, volume_T)
228
229
230 def edge_expansion(G, S, T=None, weight=None):
231 """Returns the edge expansion between two node sets.
232
233 The *edge expansion* is the quotient of the cut size and the smaller
234 of the cardinalities of the two sets. [1]
235
236 Parameters
237 ----------
238 G : NetworkX graph
239
240 S : sequence
241 A sequence of nodes in `G`.
242
243 T : sequence
244 A sequence of nodes in `G`.
245
246 weight : object
247 Edge attribute key to use as weight. If not specified, edges
248 have weight one.
249
250 Returns
251 -------
252 number
253 The edge expansion between the two sets `S` and `T`.
254
255 See also
256 --------
257 boundary_expansion
258 mixing_expansion
259 node_expansion
260
261 References
262 ----------
263 .. [1] Fan Chung.
264 *Spectral Graph Theory*.
265 (CBMS Regional Conference Series in Mathematics, No. 92),
266 American Mathematical Society, 1997, ISBN 0-8218-0315-8
267 <http://www.math.ucsd.edu/~fan/research/revised.html>
268
269 """
270 if T is None:
271 T = set(G) - set(S)
272 num_cut_edges = cut_size(G, S, T=T, weight=weight)
273 return num_cut_edges / min(len(S), len(T))
274
275
276 def mixing_expansion(G, S, T=None, weight=None):
277 """Returns the mixing expansion between two node sets.
278
279 The *mixing expansion* is the quotient of the cut size and twice the
280 number of edges in the graph. [1]
281
282 Parameters
283 ----------
284 G : NetworkX graph
285
286 S : sequence
287 A sequence of nodes in `G`.
288
289 T : sequence
290 A sequence of nodes in `G`.
291
292 weight : object
293 Edge attribute key to use as weight. If not specified, edges
294 have weight one.
295
296 Returns
297 -------
298 number
299 The mixing expansion between the two sets `S` and `T`.
300
301 See also
302 --------
303 boundary_expansion
304 edge_expansion
305 node_expansion
306
307 References
308 ----------
309 .. [1] Vadhan, Salil P.
310 "Pseudorandomness."
311 *Foundations and Trends
312 in Theoretical Computer Science* 7.1–3 (2011): 1–336.
313 <https://doi.org/10.1561/0400000010>
314
315 """
316 num_cut_edges = cut_size(G, S, T=T, weight=weight)
317 num_total_edges = G.number_of_edges()
318 return num_cut_edges / (2 * num_total_edges)
319
320
321 # TODO What is the generalization to two arguments, S and T? Does the
322 # denominator become `min(len(S), len(T))`?
323 def node_expansion(G, S):
324 """Returns the node expansion of the set `S`.
325
326 The *node expansion* is the quotient of the size of the node
327 boundary of *S* and the cardinality of *S*. [1]
328
329 Parameters
330 ----------
331 G : NetworkX graph
332
333 S : sequence
334 A sequence of nodes in `G`.
335
336 Returns
337 -------
338 number
339 The node expansion of the set `S`.
340
341 See also
342 --------
343 boundary_expansion
344 edge_expansion
345 mixing_expansion
346
347 References
348 ----------
349 .. [1] Vadhan, Salil P.
350 "Pseudorandomness."
351 *Foundations and Trends
352 in Theoretical Computer Science* 7.1–3 (2011): 1–336.
353 <https://doi.org/10.1561/0400000010>
354
355 """
356 neighborhood = set(chain.from_iterable(G.neighbors(v) for v in S))
357 return len(neighborhood) / len(S)
358
359
360 # TODO What is the generalization to two arguments, S and T? Does the
361 # denominator become `min(len(S), len(T))`?
362 def boundary_expansion(G, S):
363 """Returns the boundary expansion of the set `S`.
364
365 The *boundary expansion* is the quotient of the size of the edge
366 boundary and the cardinality of *S*. [1]
367
368 Parameters
369 ----------
370 G : NetworkX graph
371
372 S : sequence
373 A sequence of nodes in `G`.
374
375 Returns
376 -------
377 number
378 The boundary expansion of the set `S`.
379
380 See also
381 --------
382 edge_expansion
383 mixing_expansion
384 node_expansion
385
386 References
387 ----------
388 .. [1] Vadhan, Salil P.
389 "Pseudorandomness."
390 *Foundations and Trends in Theoretical Computer Science*
391 7.1–3 (2011): 1–336.
392 <https://doi.org/10.1561/0400000010>
393
394 """
395 return len(nx.node_boundary(G, S)) / len(S)