Source code for networkx.algorithms.boundary

"""用于查找一组节点的边界的例程。

边边界是一组边,其中每条边恰好有一个端点在给定的一组节点中(或者在有向图的情况下,是指源节点在集合中的边)。

一组节点 *S* 的节点边界是 *S* 中节点的(出)邻居中不在 *S* 内的节点集合。

"""

from itertools import chain

import networkx as nx

__all__ = ["edge_boundary", "node_boundary"]


[docs] @nx._dispatchable(edge_attrs={"data": "default"}, preserve_edge_attrs="data") def edge_boundary(G, nbunch1, nbunch2=None, data=False, keys=False, default=None): """返回 `nbunch1` 的边缘边界。 集合 *S* 相对于集合 *T* 的*边缘边界*是所有边 (*u*, *v*) 的集合,其中 *u* 在 *S* 中,*v* 在 *T* 中。如果未指定 *T*,则假定它是所有不在 *S* 中的节点的集合。 Parameters ---------- G : NetworkX 图 nbunch1 : 可迭代对象 图中表示节点集合的可迭代对象,其边缘边界将被返回。(这是上述定义中的集合 *S*。) nbunch2 : 可迭代对象 表示目标(或“外部”)节点集合的可迭代对象。(这是上述定义中的集合 *T*。)如果未指定,则假定它是 `G` 中所有不在 `nbunch1` 中的节点集合。 keys : bool 此参数与 :meth:`MultiGraph.edges` 中的含义相同。 data : bool 或 object 此参数与 :meth:`MultiGraph.edges` 中的含义相同。 default : object 此参数与 :meth:`MultiGraph.edges` 中的含义相同。 Returns ------- 迭代器 一个迭代器,遍历 `nbunch1` 相对于 `nbunch2` 的边缘边界中的边。如果指定了 `keys` 、 `data` 或 `default` ,并且 `G` 是多图,则边将返回带有键和/或数据,如 :meth:`MultiGraph.edges` 中所示。 Examples -------- >>> G = nx.wheel_graph(6) 当 nbunch2=None 时: >>> list(nx.edge_boundary(G, (1, 3))) [(1, 0), (1, 2), (1, 5), (3, 0), (3, 2), (3, 4)] 当 nbunch2 被指定时: >>> list(nx.edge_boundary(G, (1, 3), (2, 0))) [(1, 0), (1, 2), (3, 0), (3, 2)] Notes ----- 任何在 `nbunch` 中但不在图 `G` 中的元素将被忽略。 `nbunch1` 和 `nbunch2` 通常应是互斥的,但为了速度和通用性,这里并不要求如此。 """ nset1 = {n for n in nbunch1 if n in G} # Here we create an iterator over edges incident to nodes in the set # `nset1`. The `Graph.edges()` method does not provide a guarantee # on the orientation of the edges, so our algorithm below must # handle the case in which exactly one orientation, either (u, v) or # (v, u), appears in this iterable. if G.is_multigraph(): edges = G.edges(nset1, data=data, keys=keys, default=default) else: edges = G.edges(nset1, data=data, default=default) # If `nbunch2` is not provided, then it is assumed to be the set # complement of `nbunch1`. For the sake of efficiency, this is # implemented by using the `not in` operator, instead of by creating # an additional set and using the `in` operator. if nbunch2 is None: return (e for e in edges if (e[0] in nset1) ^ (e[1] in nset1)) nset2 = set(nbunch2) return ( e for e in edges if (e[0] in nset1 and e[1] in nset2) or (e[1] in nset1 and e[0] in nset2) )
[docs] @nx._dispatchable def node_boundary(G, nbunch1, nbunch2=None): """返回 `nbunch1` 的节点边界。 集合 *S* 相对于集合 *T* 的*节点边界*是集合 *T* 中的节点 *v* 的集合,使得对于 *S* 中的某个节点 *u*,存在一条边连接 *u* 和 *v*。如果未指定 *T*,则假定它是所有不在 *S* 中的节点的集合。 Parameters ---------- G : NetworkX 图 nbunch1 : 可迭代对象 图中表示节点集合的可迭代对象,其节点边界将被返回。(这是上述定义中的集合 *S*。) nbunch2 : 可迭代对象 表示目标(或“外部”)节点集合的可迭代对象。(这是上述定义中的集合 *T*。)如果未指定,则假定它是 `G` 中不在 `nbunch1` 中的所有节点的集合。 Returns ------- 集合 `nbunch1` 相对于 `nbunch2` 的节点边界。 Examples -------- >>> G = nx.wheel_graph(6) 当 nbunch2=None 时: >>> list(nx.node_boundary(G, (3, 4))) [0, 2, 5] 当 nbunch2 被指定时: >>> list(nx.node_boundary(G, (3, 4), (0, 1, 5))) [0, 5] Notes ----- 任何在 `nbunch` 中但不在图 `G` 中的元素将被忽略。 `nbunch1` 和 `nbunch2` 通常意味着是不相交的,但为了速度和通用性,这里并不要求如此。 """ nset1 = {n for n in nbunch1 if n in G} bdy = set(chain.from_iterable(G[v] for v in nset1)) - nset1 # If `nbunch2` is not specified, it is assumed to be the set # complement of `nbunch1`. if nbunch2 is not None: bdy &= set(nbunch2) return bdy