【问题标题】:Networkx Graph get sequence number for each nodeNetworkx Graph获取每个节点的序列号
【发布时间】:2021-03-02 06:01:35
【问题描述】:

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

当前图表

未来图

【问题讨论】:

  • 如果您在问题(多个)中包含输入和输出的简单示例,将会有所帮助。目前,我不确定您想要的输出是什么样的。
  • 我已经添加了。当前和期望\未来的图形表示。感谢您的评论

标签: python networkx


【解决方案1】:

你想要做的叫做“在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', 'h'),
    ('i', 'f'),
    ('h', 'j'),
    ('j', 'k'),
])

让我们像您的第一张图片一样绘制它(我建议您使用 Graphviz 布局):

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

然后我们使用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,
    pos=nx.nx_agraph.graphviz_layout(G, prog='dot'),
    node_color='#FF0000',
    labels={n: G.nodes[n]['level'] for n in G.nodes}
)

这是想要的结果:

【讨论】:

  • 感谢您的解决方案和解释。我是第一次这样做,仍然能够非常清楚地遵循您的解释 - 干杯!!
猜你喜欢
  • 2019-10-11
  • 1970-01-01
  • 1970-01-01
  • 2018-05-06
  • 1970-01-01
  • 2020-06-25
  • 2016-07-04
  • 2017-10-12
  • 1970-01-01
相关资源
最近更新 更多