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()}