如何遍历依赖图?

时间:2019-04-04 18:17:07

标签: python

我有一些需要根据规则集执行的任务。

例如:

        | - File2
File1  -
        | - File3

这意味着File1的任务必须在File2和File3之前执行。 我写了以下代码:

import json
    json_string = """
    {
        "file1": {
            "path_to_file": "file1.txt",
            "children": "file2,file3"
        },
        "file2": {
            "path_to_file": "file2.txt",
            "children": ""
        },
        "file3": {
            "path_to_file": "a/file3.txt",
            "children": ""
    }
"""


class Node(object):
    def __init__(self, name, path_to_file=None):
        self.name = name
        self.path_to_file = path_to_file
        self.children = []

    def add_child(self, obj):
        self.children.append(obj)

    def dump(self):
        print('%s' % (self.name))
        for obj in self.children:
            obj.dump()

name2info = json.loads(json_string)

def get_tree(name):
    info = name2info[name]
    root = Node(name, info['path_to_file'])
    for child in info['children'].split(","):
        if child:
            root.add_child(get_tree(child))
    return root

root = get_tree('file1')
root.dump()

哪个给我:

file1
file2
file3

在此示例中,print是节点中的execution function

问题在于此代码不适用于以下情况:

File1  -
        | - File3
File2  -

如果我有

   json_string = """
    {
        "file1": {
            "path_to_file": "file1.txt",
            "children": "file3"
        },
        "file2": {
            "path_to_file": "file2.txt",
            "children": "file3"
        },
        "file3": {
            "path_to_file": "a/file3.txt",
            "children": ""
    }

它将给我:

file1
file3
file2

应该是:

file1
file2
file3   #3 is child of 1 and 2 - it can be executed only after 1 & 2 are done.

基本上,每个节点只能在其所有父节点都完成其执行功能(打印)后才能执行执行功能(打印)。 我该怎么解决?

2 个答案:

答案 0 :(得分:2)

您的依赖关系树实际上不是树-它是DAG。在file1打印树时,不应打印file2

顺便说一句,您不应该将父项存储在json中,这将迫使您的系统成为一棵树。 (这可能很好,取决于您的要求)

答案 1 :(得分:0)

您要的算法是“拓扑排序”:图形元素的列表L,这样,如果AB中的L之前,则{ {1}}不是A的后代。这是一个标准的图形问题;现有的库应该处理它。这是其中的one

请注意,在一般DAG中,并不总是保证存在这样的顺序。