Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/networkx/algorithms/boundary.py: 35%
20 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-10-20 07:00 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-10-20 07:00 +0000
1"""Routines to find the boundary of a set of nodes.
3An edge boundary is a set of edges, each of which has exactly one
4endpoint in a given set of nodes (or, in the case of directed graphs,
5the set of edges whose source node is in the set).
7A node boundary of a set *S* of nodes is the set of (out-)neighbors of
8nodes in *S* that are outside *S*.
10"""
11from itertools import chain
13import networkx as nx
15__all__ = ["edge_boundary", "node_boundary"]
18@nx._dispatch(edge_attrs={"data": "default"}, preserve_edge_attrs="data")
19def edge_boundary(G, nbunch1, nbunch2=None, data=False, keys=False, default=None):
20 """Returns the edge boundary of `nbunch1`.
22 The *edge boundary* of a set *S* with respect to a set *T* is the
23 set of edges (*u*, *v*) such that *u* is in *S* and *v* is in *T*.
24 If *T* is not specified, it is assumed to be the set of all nodes
25 not in *S*.
27 Parameters
28 ----------
29 G : NetworkX graph
31 nbunch1 : iterable
32 Iterable of nodes in the graph representing the set of nodes
33 whose edge boundary will be returned. (This is the set *S* from
34 the definition above.)
36 nbunch2 : iterable
37 Iterable of nodes representing the target (or "exterior") set of
38 nodes. (This is the set *T* from the definition above.) If not
39 specified, this is assumed to be the set of all nodes in `G`
40 not in `nbunch1`.
42 keys : bool
43 This parameter has the same meaning as in
44 :meth:`MultiGraph.edges`.
46 data : bool or object
47 This parameter has the same meaning as in
48 :meth:`MultiGraph.edges`.
50 default : object
51 This parameter has the same meaning as in
52 :meth:`MultiGraph.edges`.
54 Returns
55 -------
56 iterator
57 An iterator over the edges in the boundary of `nbunch1` with
58 respect to `nbunch2`. If `keys`, `data`, or `default`
59 are specified and `G` is a multigraph, then edges are returned
60 with keys and/or data, as in :meth:`MultiGraph.edges`.
62 Examples
63 --------
64 >>> G = nx.wheel_graph(6)
66 When nbunch2=None:
68 >>> list(nx.edge_boundary(G, (1, 3)))
69 [(1, 0), (1, 2), (1, 5), (3, 0), (3, 2), (3, 4)]
71 When nbunch2 is given:
73 >>> list(nx.edge_boundary(G, (1, 3), (2, 0)))
74 [(1, 0), (1, 2), (3, 0), (3, 2)]
76 Notes
77 -----
78 Any element of `nbunch` that is not in the graph `G` will be
79 ignored.
81 `nbunch1` and `nbunch2` are usually meant to be disjoint, but in
82 the interest of speed and generality, that is not required here.
84 """
85 nset1 = {n for n in nbunch1 if n in G}
86 # Here we create an iterator over edges incident to nodes in the set
87 # `nset1`. The `Graph.edges()` method does not provide a guarantee
88 # on the orientation of the edges, so our algorithm below must
89 # handle the case in which exactly one orientation, either (u, v) or
90 # (v, u), appears in this iterable.
91 if G.is_multigraph():
92 edges = G.edges(nset1, data=data, keys=keys, default=default)
93 else:
94 edges = G.edges(nset1, data=data, default=default)
95 # If `nbunch2` is not provided, then it is assumed to be the set
96 # complement of `nbunch1`. For the sake of efficiency, this is
97 # implemented by using the `not in` operator, instead of by creating
98 # an additional set and using the `in` operator.
99 if nbunch2 is None:
100 return (e for e in edges if (e[0] in nset1) ^ (e[1] in nset1))
101 nset2 = set(nbunch2)
102 return (
103 e
104 for e in edges
105 if (e[0] in nset1 and e[1] in nset2) or (e[1] in nset1 and e[0] in nset2)
106 )
109@nx._dispatch
110def node_boundary(G, nbunch1, nbunch2=None):
111 """Returns the node boundary of `nbunch1`.
113 The *node boundary* of a set *S* with respect to a set *T* is the
114 set of nodes *v* in *T* such that for some *u* in *S*, there is an
115 edge joining *u* to *v*. If *T* is not specified, it is assumed to
116 be the set of all nodes not in *S*.
118 Parameters
119 ----------
120 G : NetworkX graph
122 nbunch1 : iterable
123 Iterable of nodes in the graph representing the set of nodes
124 whose node boundary will be returned. (This is the set *S* from
125 the definition above.)
127 nbunch2 : iterable
128 Iterable of nodes representing the target (or "exterior") set of
129 nodes. (This is the set *T* from the definition above.) If not
130 specified, this is assumed to be the set of all nodes in `G`
131 not in `nbunch1`.
133 Returns
134 -------
135 set
136 The node boundary of `nbunch1` with respect to `nbunch2`.
138 Examples
139 --------
140 >>> G = nx.wheel_graph(6)
142 When nbunch2=None:
144 >>> list(nx.node_boundary(G, (3, 4)))
145 [0, 2, 5]
147 When nbunch2 is given:
149 >>> list(nx.node_boundary(G, (3, 4), (0, 1, 5)))
150 [0, 5]
152 Notes
153 -----
154 Any element of `nbunch` that is not in the graph `G` will be
155 ignored.
157 `nbunch1` and `nbunch2` are usually meant to be disjoint, but in
158 the interest of speed and generality, that is not required here.
160 """
161 nset1 = {n for n in nbunch1 if n in G}
162 bdy = set(chain.from_iterable(G[v] for v in nset1)) - nset1
163 # If `nbunch2` is not specified, it is assumed to be the set
164 # complement of `nbunch1`.
165 if nbunch2 is not None:
166 bdy &= set(nbunch2)
167 return bdy