使用ndlib的SIR模型在2D网格网络运行时遇ValueError问题求助
解决ndlib SIR模型在2D网格网络中的初始化错误
问题背景
尝试使用ndlib的SIR模型分析2D网格网络中的疫情传播行为,实现代码如下:
import networkx as nx import ndlib.models.ModelConfig as mc import ndlib.models.epidemics as ep from ndlib.viz.mpl.DiffusionTrend import DiffusionTrend g3 = nx.grid_2d_graph(80,80) model3 = ep.SIRModel(g3) cfg = mc.Configuration() cfg.add_model_parameter('lambda',beta) cfg.add_model_parameter("fraction_infected",0.05) cfg.add_model_parameter('beta',0.9) cfg.add_model_parameter('gamma',0.05) model3.set_initial_status(cfg) iterations3 = model3.iteration_bunch(500) trends3 = model3.build_trends(iterations3)
执行model3.set_initial_status(cfg)时触发错误:
ValueError Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_11068/1868465894.py in <module> 7 cfg.add_model_parameter('gamma',0.05) 8 ----> 9 model3.set_initial_status(cfg) 10 iterations3 = model3.iteration_bunch(500) 11 trends3 = model3.build_trends(iterations3) ~\anaconda3\lib\site-packages\ndlib\models\DiffusionModel.py in set_initial_status(self, configuration) 173 174 available_nodes = [n for n in self.status if self.status[n] == 0] ---> 175 sampled_nodes = np.random.choice(available_nodes, int(number_of_initial_infected), replace=False) 176 for k in sampled_nodes: 177 self.status[k] = self.available_statuses['Infected'] mtrand.pyx in numpy.random.mtrand.RandomState.choice() ValueError: a must be 1-dimensional
错误原因
nx.grid_2d_graph(80,80)生成的节点是二元组格式(例如(0,0)、(0,1)),而ndlib在初始化感染节点时调用的np.random.choice不支持将多维元素(元组)作为采样输入,因此抛出a must be 1-dimensional的错误。
解决方案
将网格图的节点标签转换为整数ID,使用NetworkX的nx.convert_node_labels_to_integers()函数即可实现,该函数会把原有的二元组节点替换为连续的整数(0,1,2,...),同时保留网络的拓扑结构不变。
修改后的代码如下:
import networkx as nx import ndlib.models.ModelConfig as mc import ndlib.models.epidemics as ep from ndlib.viz.mpl.DiffusionTrend import DiffusionTrend # 生成2D网格图并转换节点标签为整数 g3 = nx.grid_2d_graph(80,80) g3 = nx.convert_node_labels_to_integers(g3) # 新增节点标签转换步骤 model3 = ep.SIRModel(g3) cfg = mc.Configuration() # 移除无效参数:SIR模型无需lambda,且原代码中beta变量未定义 # cfg.add_model_parameter('lambda',beta) cfg.add_model_parameter("fraction_infected",0.05) cfg.add_model_parameter('beta',0.9) cfg.add_model_parameter('gamma',0.05) model3.set_initial_status(cfg) iterations3 = model3.iteration_bunch(500) trends3 = model3.build_trends(iterations3) # 可选:绘制传播趋势图 viz = DiffusionTrend(model3, trends3) viz.plot()
额外说明:原代码中cfg.add_model_parameter('lambda',beta)存在两个问题:一是beta变量未定义,二是SIR模型的核心参数为beta(感染率)和gamma(恢复率),lambda属于SI/SIS等其他模型的参数,因此建议移除该行避免冗余配置。
内容的提问来源于stack exchange,提问作者Howlhoff
相关产品推荐
相关产品推荐

