Python 实现结点依赖的执行顺序算法

44 阅读1分钟

当前结点依赖关系

我们需要按条件顺序执行以下结点,即没有依赖的前置结点优先执行,所以在这个关系下,我们发现 A出度(前置结点个数)为 0, 所以先移除 A

此时 B出度为 0, 把 B 移除

此时 C出度为 0, 把 C 移除

所以执行的顺序是 ABC

这个过程是可以迭代执行的

while 结点数 > 0
    1、移除出度为 0 的结点并打印
    2、遍历所有结点
    3、结点中的前置结点移除(1、中移除的结点)

全部代码

class Node:
    def __init__(self, value:str) -> None:
        # 前置结点 (1->n)
        self.pre = []
        # 结点值
        self.value = value
        pass

    def print(self)->str:
        if len(self.pre) == 0:
            print(self.value)
        else:
            for index,item in enumerate(self.pre):
                if index == 0:
                    print("{}->{}".format(self.value, self.pre[0].value))
                else:
                    print("|->{}".format(item))

    def __str__(self) -> str:
        return self.value

# 以这个三个结点为例
A = Node('A')
B = Node('B')
C = Node('C')

# B->A
B.pre.append(A)
# C->A
C.pre.append(A)
# C->B
C.pre.append(B)

# 结点列表(用于遍历)
node_list = [C,B,A]

# 保存排序后的列表
list_sort = []
print("-----------------关系打印----------------")
for item in node_list:    
    item.print()

print("-----------------排序后打印----------------")
while len(node_list)>0: # 列表为空时退出循环
    # 找到出度为 0 的结点
    no_pre_list = list(filter(lambda item:len(item.pre) == 0, node_list)) 

    # 移除前置条件的结点
    for delete in no_pre_list:
        list_sort.append(delete.value) # 纳入排序列表
        node_list.remove(delete)

    no_pre_list_set = set([item.value for item in no_pre_list])
    # 移除所有结点里没有出度的前置结点
    for node in node_list:
        pre_set = set([item.value for item in node.pre])
        # 前置结点和无出度结点的交集
        jiao_set = no_pre_list_set & pre_set  
        if jiao_set:
            remove_list = [pre for pre in node.pre if pre.value in jiao_set]
            for remove in remove_list:
                node.pre.remove(remove)                

print(list_sort)

打印结果

-----------------关系打印----------------
C->A
|->B
B->A
A
-----------------排序后打印----------------
['A', 'B', 'C']