Source code for networkx.algorithms.assortativity.connectivity

from collections import defaultdict

import networkx as nx

__all__ = ["average_degree_connectivity"]


[docs] @nx._dispatchable(edge_attrs="weight") def average_degree_connectivity( G, source="in+out", target="in+out", nodes=None, weight=None ): r"""计算图的平均度连接性。 平均度连接性是具有度数 \( k \) 的节点的平均最近邻度数。对于加权图,可以使用在 [1]_ 中定义的加权平均邻居度数来计算类似的度量,对于节点 \( i \),定义为 .. math:: k_{nn,i}^{w} = \frac{1}{s_i} \sum_{j \in N(i)} w_{ij} k_j 其中 \( s_i \) 是节点 \( i \) 的加权度数, \( w_{ij} \) 是连接 \( i \) 和 \( j \) 的边的权重, \( N(i) \) 是节点 \( i \) 的邻居。 Parameters ---------- G : NetworkX 图 source : "in"|"out"|"in+out" (默认:"in+out") 仅限有向图。用于源节点的 "in" 或 "out" 度数。 target : "in"|"out"|"in+out" (默认:"in+out") 仅限有向图。用于目标节点的 "in" 或 "out" 度数。 nodes : 列表或可迭代对象(可选) 计算这些节点的邻居连接性。默认是所有节点。 weight : 字符串或 None, 可选 (默认=None) 作为权重使用的边属性。如果为 None,则每条边的权重为 1。 Returns ------- d : 字典 按度数 \( k \) 键值的字典,值为平均连接性。 Raises ------ NetworkXError 如果 `source` 或 `target` 不是 'in'、'out' 或 'in+out' 之一。 如果为无向图传递了 `source` 或 `target` 。 Examples -------- >>> G = nx.path_graph(4) >>> G.edges[1, 2]["weight"] = 3 >>> nx.average_degree_connectivity(G) {1: 2.0, 2: 1.5} >>> nx.average_degree_connectivity(G, weight="weight") {1: 2.0, 2: 1.75} See Also -------- average_neighbor_degree References ---------- .. [1] A. Barrat, M. Barthélemy, R. Pastor-Satorras, 和 A. Vespignani, "The architecture of complex weighted networks". PNAS 101 (11): 3747–3752 (2004). """ # First, determine the type of neighbors and the type of degree to use. if G.is_directed(): if source not in ("in", "out", "in+out"): raise nx.NetworkXError('source must be one of "in", "out", or "in+out"') if target not in ("in", "out", "in+out"): raise nx.NetworkXError('target must be one of "in", "out", or "in+out"') direction = {"out": G.out_degree, "in": G.in_degree, "in+out": G.degree} neighbor_funcs = { "out": G.successors, "in": G.predecessors, "in+out": G.neighbors, } source_degree = direction[source] target_degree = direction[target] neighbors = neighbor_funcs[source] # `reverse` indicates whether to look at the in-edge when # computing the weight of an edge. reverse = source == "in" else: if source != "in+out" or target != "in+out": raise nx.NetworkXError( f"source and target arguments are only supported for directed graphs" ) source_degree = G.degree target_degree = G.degree neighbors = G.neighbors reverse = False dsum = defaultdict(int) dnorm = defaultdict(int) # Check if `source_nodes` is actually a single node in the graph. source_nodes = source_degree(nodes) if nodes in G: source_nodes = [(nodes, source_degree(nodes))] for n, k in source_nodes: nbrdeg = target_degree(neighbors(n)) if weight is None: s = sum(d for n, d in nbrdeg) else: # weight nbr degree by weight of (n,nbr) edge if reverse: s = sum(G[nbr][n].get(weight, 1) * d for nbr, d in nbrdeg) else: s = sum(G[n][nbr].get(weight, 1) * d for nbr, d in nbrdeg) dnorm[k] += source_degree(n, weight=weight) dsum[k] += s # normalize return {k: avg if dnorm[k] == 0 else avg / dnorm[k] for k, avg in dsum.items()}