基于有向图边属性edge_id构建新图的更简便方法咨询
基于有向图边属性edge_id构建新图的更简便方法咨询
嘿,我注意到你现在通过找起始节点、遍历最短路径的方式来生成以edge_id为节点的新图,确实能实现需求,但其实有更通用、更直接的方法——毕竟如果原图结构更复杂(比如有多个独立路径分支、多终点),原来的方法可能会失效。
本质上我们要做的逻辑很清晰:把原有向图G中的每条边(用edge_id唯一标识)作为新图H的节点;当原G中边e1的终点是另一条边e2的起点时,就在新图H里给这两个edge_id之间连一条有向边。
下面是简化后的通用实现代码:
import networkx as nx import matplotlib.pyplot as plt edges = [("A","D", {"edge_id":1}), ("B","D", {"edge_id":2}), ("D", "G", {"edge_id":3}), ("C", "F", {"edge_id":4}), ("E", "F", {"edge_id":5}), ("F", "G", {"edge_id":6}), ("G", "I", {"edge_id":7}), ("H", "I", {"edge_id":8}), ("I", "J", {"edge_id":9}), ] # 构建原有向图G G = nx.DiGraph() G.add_edges_from(edges) # 生成以edge_id为节点的新图H(核心逻辑) H = nx.DiGraph() # 先把所有edge_id作为节点加入新图 edge_id_map = {(u, v): attr["edge_id"] for u, v, attr in G.edges(data=True)} H.add_nodes_from(edge_id_map.values()) # 遍历每条原边,找到所有衔接的后续边,在新图中连边 for u, v, attr in G.edges(data=True): current_edge_id = attr["edge_id"] # 找所有以当前边终点v为起点的后续边 for succ_u, succ_v, succ_attr in G.edges(v, data=True): succ_edge_id = succ_attr["edge_id"] H.add_edge(current_edge_id, succ_edge_id) # 可视化部分 fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10,5)) pos = nx.spring_layout(G) nx.draw(G, with_labels=True, pos=pos, ax=ax[0]) ax[0].set_title("原有的向图G") nx.draw(H, with_labels=True, pos=nx.spring_layout(H), ax=ax[1]) ax[1].set_title("以edge_id为节点的新图H") plt.show()
这个方法的优势
- 通用性更强:不管原图有多少个起始节点、终点,甚至有环结构,都能正确生成新图,完全不需要依赖“找入度/出度为0的节点”“遍历最短路径”这类场景受限的逻辑;
- 逻辑更直接:完全贴合需求本质——直接基于原边的衔接关系构建新图,没有冗余步骤;
- 效率更高:省去了路径遍历的开销,直接通过原边的邻接关系完成新图构建。
最终的可视化效果和你之前的结果一致:
- 左侧子图是原有的向图G,节点为A-J的字母,边对应各个带
edge_id的连接关系; - 右侧子图是转换后的新图H,节点为1-9的
edge_id值,边对应原边的衔接逻辑(比如原边1的终点是D,原边3的起点是D,所以H中1→3,以此类推)。
备注:内容来源于stack exchange,提问作者Bera
相关产品推荐
相关产品推荐

