Networkx Graph 获取每个节点的序列号

问题描述

我正在使用 networkx 生成如下所示的有向图。如何对节点进行编号,使其遵循从最低到最大的序列,并且当节点拆分为多个节点时,所有以下节点都获得相同的序列号。反之,也可以将多个节点合并为一个节点

当前图表

Current Graph

未来图表

Future Graph

解决方法

您想要做的称为“directed acyclic graph”中的排名节点。

Networkx 没有内置函数(据我所知),但可以通过简单的算法来完成:

  1. 如果节点没有前辈,则其等级设置为 1。
  2. 如果节点有前驱,则其等级设置为“最大前驱等级”加1

以下是 Networkx 图的示例:

import networkx as nx

# Create graph
G = nx.DiGraph()
G.add_edges_from([
    ('a','b'),('b','c'),('d','e'),('e','f'),('f','g'),('g','h'),('c',('i',('h','j'),('j','k'),])

让我们把它画成你的第一张图片(我建议你使用 Graphviz 布局):

nx.draw(
    G,pos=nx.nx_agraph.graphviz_layout(G,prog='dot'),node_color='#FF0000'
)

enter image description here

然后我们使用 topological sorting 进行适当的 DAG 迭代并使用上层算法:

for node in nx.topological_sort(G):
    if not len(list(G.predecessors(node))):
        G.nodes[node]['level'] = 1
    else:
        G.nodes[node]['level'] = max(
            G.nodes[n]['level']
            for n in G.predecessors(node)
        ) + 1

然后我们将在 "level" 变量中获得我们的排名数

>>> G.nodes.data('level')

NodeDataView({'i': 1,'a': 1,'g': 4,'b': 2,'d': 1,'j': 6,'k': 7,'c': 3,'e': 2,'h': 5,'f': 3},data='level')

最后我们使用节点等级作为标签绘制图形:

nx.draw(
    G,node_color='#FF0000',labels={n: G.nodes[n]['level'] for n in G.nodes}
)

这是想要的结果:

enter image description here