Source code for pynetim.graph.decomposition

"""图分解算法模块。

提供 K-shell、K-core 等图分解算法。
"""

from typing import Dict, TYPE_CHECKING

if TYPE_CHECKING:
    from .graph import IMGraph


[docs] def compute_k_shell_values(graph: 'IMGraph') -> Dict[int, int]: """计算图中所有节点的 K-shell 值。 使用 Batagelj-Zaversnik 算法,时间复杂度 O(m)。 K-shell 分解是一种识别网络核心层次结构的方法: - K-shell 值高的节点位于网络核心 - K-shell 值低的节点位于网络边缘 Args: graph: IMGraph 图对象。 Returns: Dict[int, int]: 节点到 K-shell 值的映射。 References: Batagelj, V., & Zaversnik, M. (2003). An O(m) algorithm for cores decomposition of networks. arXiv preprint cs/0310049. Kitsak, M., Gallos, L. K., Havlin, S., Liljeros, F., Muchnik, L., Stanley, H. E., & Makse, H. A. (2010). Identification of influential spreaders in complex networks. Nature physics, 6(11), 888-893. Example: >>> from pynetim import IMGraph >>> from pynetim.graph import compute_k_shell_values >>> >>> graph = IMGraph(edges, directed=True) >>> k_shell = compute_k_shell_values(graph) >>> print(k_shell) # {0: 1, 1: 2, 2: 1, ...} """ n = graph.num_nodes if n == 0: return {} nodes = list(range(n)) degree = {v: graph.out_degree(v) for v in nodes} md = max(degree.values()) if degree else 0 bins = [0] * (md + 1) for node in nodes: bins[degree[node]] += 1 start = 1 for d in range(md + 1): num = bins[d] bins[d] = start start += num pos = {node: -1 for node in nodes} vert = {p: -1 for p in range(1, n + 1)} for node in nodes: pos[node] = bins[degree[node]] vert[pos[node]] = node bins[degree[node]] += 1 for d in range(md, 0, -1): bins[d] = bins[d - 1] bins[0] = 1 nbrs = {v: list(graph.out_neighbors(v)) for v in nodes} for p in range(1, n + 1): v = vert[p] for u in nbrs[v]: if degree[u] > degree[v]: du = degree[u] pu = pos[u] pw = bins[du] w = vert[pw] if u != w: pos[u] = pw vert[pu] = w pos[w] = pu vert[pw] = u bins[du] += 1 degree[u] -= 1 return degree
__all__ = ['compute_k_shell_values']