使用NetworkX计算图编辑距离遇循环瓶颈,求原因及替代方案
问题原因分析
- 迭代器遍历耗尽导致停滞:你使用的
nx.optimize_graph_edit_distance返回的是迭代器,会生成所有可能的编辑路径对应的GED值(从最优到次优)。你的for v in ...循环会强制遍历到迭代器完全耗尽,而非只取第一个最优值。单独测试时你可能只触发了迭代器的第一个值就终止,但循环里会遍历所有匹配组合——如果第4组图对的节点/边数量较多,可能存在大量匹配组合,导致程序看似“停滞”。 - 对比你注释掉的
nx.graph_edit_distance:该函数直接返回最小的GED(最优解),不会生成所有可能值,这也是单独测试时速度快的核心原因。
解决方案
1. 修复核心代码逻辑(最直接)
要么替换回nx.graph_edit_distance,要么在使用optimize版本时只取第一个最优值:
lst_of_dct = [] for g1, g2 in pair_list: # 直接遍历pair_list更简洁 result_dict = {} # 存储边列表 result_dict["my_graph1"] = [list(e) for e in g1.edges] result_dict["my_graph2"] = [list(e) for e in g2.edges] # 存储节点列表(转成list避免视图对象的引用问题) result_dict["labels_1"] = list(g1.nodes) result_dict["labels_2"] = list(g2.nodes) # 方案1:用graph_edit_distance直接取最优GED ged = nx.graph_edit_distance(g1, g2) # 方案2:若必须用optimize版本,仅取第一个最优值 # ged = next(nx.optimize_graph_edit_distance(g1, g2)) result_dict["ged"] = ged lst_of_dct.append(result_dict) print(f"完成第{len(lst_of_dct)}组")
注意:不要用dict作为变量名,这是Python内置类型,会覆盖内置函数。
2. 大规模数据的性能优化(无需拆分循环)
针对未来更大规模的数据集,用并行计算处理独立的图对GED计算,充分利用多核CPU:
from concurrent.futures import ProcessPoolExecutor def compute_ged(graph_pair): g1, g2 = graph_pair result_dict = {} result_dict["my_graph1"] = [list(e) for e in g1.edges] result_dict["my_graph2"] = [list(e) for e in g2.edges] result_dict["labels_1"] = list(g1.nodes) result_dict["labels_2"] = list(g2.nodes) result_dict["ged"] = nx.graph_edit_distance(g1, g2) return result_dict # 并行计算,max_workers设为None会自动匹配CPU核心数 with ProcessPoolExecutor(max_workers=None) as executor: lst_of_dct = list(executor.map(compute_ged, pair_list))
这种方式无需手动拆分循环,框架会自动分配任务到不同进程,速度能提升数倍(取决于CPU核心数)。
3. 额外内存优化
如果图的规模很大,避免存储完整的边/节点列表,只保留必要属性(比如节点标签、边数量等),减少内存占用,避免后续计算中内存溢出。
内容的提问来源于stack exchange,提问作者kmojanky
相关产品推荐
相关产品推荐

