如何在python字典中识别根节点?

如何在python字典中识别根节点?,python,data-structures,graph,Python,Data Structures,Graph,我有一个python字典,它表示一个图形。我希望识别根节点/独立节点,以便可以同时处理它们,然后下一个节点将成为根节点/独立节点。 我对如何在python中实现这种技术感到困惑 下面是一个示例词典: my_graph = { 1:[4], 2:[6], 3:[9], 4:[5,7], 5:[8], 6:[], 7:[],

我有一个python字典,它表示一个图形。我希望识别根节点/独立节点,以便可以同时处理它们,然后下一个节点将成为根节点/独立节点。 我对如何在python中实现这种技术感到困惑

下面是一个示例词典:

my_graph = {
            1:[4],
            2:[6],
            3:[9],
            4:[5,7],
            5:[8],
            6:[],
            7:[],
            8:[],
            9:[]
           }
我将把这个过程划分为不同的框架。根据上述词典得出的预期结果如下:

1-开始: 根/独立节点为=1,2,3

2-第1帧之后 根/独立节点=4,6,9

3-第2帧之后 根节点/独立节点=5,7

4-第3帧之后 根/独立节点为=8

编辑1: 我试图以任何形式获得序列,例如列表、数组或任何其他类似数据结构,以给定字典中节点的依赖关系图,其中每个子节点都依赖于其父节点,因此不能在父节点之前进行处理。作为下一步,我希望获得一些并行性,即我可以一次处理所有根节点


我一直在阅读,但不确定它们是否是最终的解决方案,或者我可以用一些简单的方法来实现。

听起来你想执行一个任务

您可以使用库来为您进行升降,它将确定节点处理的依赖关系和顺序:

import toposort

my_graph = {
            1:[4],
            2:[6],
            3:[9],
            4:[5,7],
            5:[8],
            6:[],
            7:[],
            8:[],
            9:[]
           }

# change values to sets (required by toposort)
for key, value in my_graph.items():
    my_graph[key] = set(value)

result = toposort.toposort(my_graph)
print(list(result))
[{6,7,8,9},{2,3,5},{4},{1}]

这称为“拓扑排序”。一个简单的算法是

  • 在节点和“传入”弧数之间建立映射
  • 处理具有0的节点(这些是“根”)并在继续时更新计数器(当处理所有邻居的节点递减计数器时)
  • 如果图形不是树(存在循环),则可能在完成之前停止。在这种情况下,您将得到一个点,其中图形不是空的,但没有可用的根

    就你而言

    def tsort(graph): 
        counts = dict((k, 0) for k in graph) 
        for n, neighbors in graph.items(): 
            for nh in neighbors: 
                counts[nh] = counts[nh] + 1 
        while graph: 
            roots = [k for k in graph if counts[k] == 0] 
            if not roots: 
                raise RuntimeError("Cycles present, no topological sort possible") 
            print("roots", roots) 
            for r in roots: 
                print("Processing", r) 
                for nh in graph[r]: 
                    counts[nh] -= 1 
                del graph[r] 
    
    更容易:

    while d: #'d' is a dictionary
        roots = set(d).difference(*d.values())
        print(roots)
        [d.pop(k) for k in roots]
    
    或以递归方式:

    def traverse(d):
        if d:
            roots = set(d).difference(*d.values())
            print(roots)
            [d.pop(k) for k in roots]
            return traverse(d)
    
    无论哪种方式打印:

    set([1, 2, 3])
    set([4, 6, 9])
    set([5, 7])
    set([8])
    

    到目前为止你试过什么?请用代码演示一下。你能提供更多的上下文吗?如果我们看到您想要解决的问题,这将有助于回答您的问题。@thomi我已经在“编辑1”标签下添加了一个解释。如果您仍然不能理解我的意思,请提出进一步的问题,我很乐意解释。或者你可以写下你目前对这个问题的理解。@Sophos我正试图在纸上找出解决方案。我已经写了很多python脚本,但那只是为了测试不同的想法。我认为这不是预期的output@muruDiaz:是的。。。根是没有任何“传入”链接的所有节点,它们可以是多个。唯一的问题是循环(在这种情况下,不可能进行拓扑排序)。对于较小和较大的字典,哪一个更好?你能分享一下他们的业绩比较吗?