如何在NetworkX中实现有向无标度网络的Price模型?
构建有向无标度网络(Price模型)的NetworkX实现方案
直接用NetworkX内置函数
NetworkX已经内置了基于Price模型的有向无标度网络生成工具——scale_free_graph(),默认生成的就是有向图,完全满足你的需求:
import networkx as nx # 生成包含1000个节点的有向无标度网络 G = nx.scale_free_graph(1000) # 可选:移除自环(Price模型通常不含自环) G.remove_edges_from(nx.selfloop_edges(G))
这个函数支持通过alpha、beta、gamma参数调整生成规则,对应Price模型中新增节点时的不同行为比例。
你调整BA模型失败的原因
你尝试用出度计算连接权重,但Price模型的核心是入度优先连接——新节点更倾向于连接到入度高的旧节点,而非出度高的。用out_degree计算概率完全不符合模型逻辑,这是你实现失败的关键。
正确的优先连接逻辑应该基于目标节点的入度,示例代码片段如下:
import random # 假设G是当前的有向图,new_node是刚加入的新节点 existing_nodes = list(G.nodes())[:-1] # 排除新节点自身 # 获取每个旧节点的入度 in_degrees = [G.in_degree(node) for node in existing_nodes] total_in_degree = sum(in_degrees) + 1e-6 # 加小值避免除以0 # 计算每个节点被连接的概率(与入度成正比) connection_probs = [deg / total_in_degree for deg in in_degrees] # 按概率选择目标节点 target_node = random.choices(existing_nodes, weights=connection_probs, k=1)[0] G.add_edge(new_node, target_node)
手动实现完整Price模型
如果需要完全自定义逻辑,这里是一个简化版的手动实现:
import networkx as nx import random def price_model(n_nodes, m=1): """ 参数: n_nodes: 最终网络的节点总数 m: 每个新节点添加的边数(默认1) 返回: 基于Price模型生成的有向无标度网络 """ # 初始化网络:先创建m个初始节点并添加初始边 G = nx.DiGraph() G.add_nodes_from(range(m)) for i in range(m): for j in range(m): if i != j: G.add_edge(i, j) # 逐步添加新节点 for new_node in range(m, n_nodes): G.add_node(new_node) existing_nodes = [n for n in G.nodes() if n != new_node] in_degrees = [G.in_degree(n) for n in existing_nodes] total_in = sum(in_degrees) # 初始阶段总入度为0时随机选择 if total_in == 0: targets = random.sample(existing_nodes, k=m) else: probs = [deg / total_in for deg in in_degrees] targets = random.choices(existing_nodes, weights=probs, k=m) # 添加新节点到目标节点的边 for target in targets: G.add_edge(new_node, target) # 移除自环(可选操作) G.remove_edges_from(nx.selfloop_edges(G)) return G # 使用示例 G = price_model(1000, m=2) print(f"网络平均入度: {sum(d for _, d in G.in_degree()) / G.number_of_nodes():.2f}")
内容的提问来源于stack exchange,提问作者TomT
相关产品推荐
相关产品推荐

