网络随机故障模拟疑问:核心比例为何始终无法降至0?
有向网络随机故障模拟:核心比例未降至0的问题分析与解决
问题场景
使用NetworkX模拟有向网络的随机节点故障,每一步计算剩余核心比例(最大弱连通分量节点数/原网络节点数)。预期核心比例从1开始,随节点移除逐步降至0,但实际最终稳定在一个非零值。已确认原网络是弱连通的,修改num_nodes_removed的范围上限加1后问题解决,需确认该操作是否正确。
原模拟代码
import networkx as nx import matplotlib.pyplot as plt import scipy.sparse as sp import pandas as pd import random N = G.number_of_nodes() M = 1 num_nodes_removed = range(0, G.number_of_nodes(), M) simulations = 1000 random_attack_core_proportions = [] for i in range(simulations): C = G.copy() # A copy of the original network proportions = [] for nodes_removed in num_nodes_removed: if C.number_of_nodes() > 0: core = max(nx.weakly_connected_components(C), key=len) # This measures the largest connected component. core_proportion = len(core) / N # Calculating len(Core) which is no. of remaining nodes and N is the number of the original nodes. else: core_proportion = 0 proportions.append(core_proportion) if C.number_of_nodes() > 0: node_to_remove = random.choice(list(C.nodes)) C.remove_node(node_to_remove) random_attack_core_proportions.append(proportions) average_proportions = [sum(proportions)/simulations for proportions in zip(*random_attack_core_proportions)] plt.xlabel('Number of nodes removed') plt.ylabel('Proportion of nodes in core') plt.plot(num_nodes_removed, average_proportions, marker='s') plt.grid() plt.show()
问题根源
问题出在range(0, G.number_of_nodes(), M)的取值逻辑:
- Python的
range是左闭右开区间,生成的数值从起始值开始,直到小于结束值时停止。 - 当原网络节点数为N,
range(0, N, 1)生成的序列是[0,1,2,...,N-1],共N个值。对应循环执行N次,每次移除1个节点,最终只移除了N-1个节点,网络中还剩1个节点,此时核心比例为1/N,无法降至0。
验证修改的正确性
将num_nodes_removed的定义改为:
num_nodes_removed = range(0, G.number_of_nodes() + 1, M)
这个修改是完全正确的,原因如下:
- 新的range序列会包含
N这个值,对应移除全部N个节点的场景 - 循环执行N+1次:
- 第一次
nodes_removed=0:未移除节点,核心比例为1 - 后续每次移除1个节点,直到
nodes_removed=N时,网络已无节点,核心比例为0
- 第一次
- 最终生成的
average_proportions会包含从1到0的完整变化过程,符合预期的直觉结果
内容的提问来源于stack exchange,提问作者Madflâneur
相关产品推荐
相关产品推荐

