Python 卡恩的订单不正确';s算法

Python 卡恩的订单不正确';s算法,python,graph-algorithm,topological-sort,Python,Graph Algorithm,Topological Sort,我试图用Kahn的算法实现拓扑排序: from collections import defaultdict def ordering(graph:dict): in_counts = defaultdict(int) for k, v in graph.items(): if not k in in_counts: in_counts[k] = 0 for in_node in v: in_cou

我试图用Kahn的算法实现拓扑排序:

from collections import defaultdict

def ordering(graph:dict):
    in_counts = defaultdict(int)
    for k, v in graph.items():
        if not k in in_counts:
            in_counts[k] = 0
        for in_node in v:
            in_counts[in_node] += 1

    queue = []
    for in_node in in_counts.keys():
        if in_counts[in_node] == 0:
            queue.append(in_node)

    topological_order = []

    while queue:
        print("in_counts:", in_counts)
        print("queue:", queue)
        current_node = queue.pop(0)
        topological_order.append(current_node)
        print("result:", topological_order)
        if not current_node in graph:
            continue
        for in_node in graph[current_node]:
            in_counts[in_node] -= 1
            if in_counts[in_node] == 0:
                queue.append(in_node)

    return topological_order

print(ordering({'GTTGA': ['CTGAG'], 'TTCAC': ['GTTGA'], 'AAGGC': ['GTTGA', 'TAACA', 'TTCAC'], 'CGGGC': ['GTTGA', 'TAACA'], 'CCCTC': ['GTTGA', 'TAACA', 'TTCAC', 'AAGGC', 'CGGGC', 'CTGAG'], 'AGCTT': ['GTTGA']}))

调试输出:

in_counts: defaultdict(<class 'int'>, {'GTTGA': 5, 'CTGAG': 2, 'TTCAC': 2, 'AAGGC': 1, 'TAACA': 3, 'CGGGC': 1, 'CCCTC': 0, 'AGCTT': 0})
queue: ['CCCTC', 'AGCTT']
result: ['CCCTC']
in_counts: defaultdict(<class 'int'>, {'GTTGA': 4, 'CTGAG': 1, 'TTCAC': 1, 'AAGGC': 0, 'TAACA': 2, 'CGGGC': 0, 'CCCTC': 0, 'AGCTT': 0})
queue: ['AGCTT', 'AAGGC', 'CGGGC']
result: ['CCCTC', 'AGCTT']
in_counts: defaultdict(<class 'int'>, {'GTTGA': 3, 'CTGAG': 1, 'TTCAC': 1, 'AAGGC': 0, 'TAACA': 2, 'CGGGC': 0, 'CCCTC': 0, 'AGCTT': 0})
queue: ['AAGGC', 'CGGGC']
result: ['CCCTC', 'AGCTT', 'AAGGC']
in_counts: defaultdict(<class 'int'>, {'GTTGA': 2, 'CTGAG': 1, 'TTCAC': 0, 'AAGGC': 0, 'TAACA': 1, 'CGGGC': 0, 'CCCTC': 0, 'AGCTT': 0})
queue: ['CGGGC', 'TTCAC']
result: ['CCCTC', 'AGCTT', 'AAGGC', 'CGGGC']
in_counts: defaultdict(<class 'int'>, {'GTTGA': 1, 'CTGAG': 1, 'TTCAC': 0, 'AAGGC': 0, 'TAACA': 0, 'CGGGC': 0, 'CCCTC': 0, 'AGCTT': 0})
queue: ['TTCAC', 'TAACA']
result: ['CCCTC', 'AGCTT', 'AAGGC', 'CGGGC', 'TTCAC']
in_counts: defaultdict(<class 'int'>, {'GTTGA': 0, 'CTGAG': 1, 'TTCAC': 0, 'AAGGC': 0, 'TAACA': 0, 'CGGGC': 0, 'CCCTC': 0, 'AGCTT': 0})
queue: ['TAACA', 'GTTGA']
result: ['CCCTC', 'AGCTT', 'AAGGC', 'CGGGC', 'TTCAC', 'TAACA']
in_counts: defaultdict(<class 'int'>, {'GTTGA': 0, 'CTGAG': 1, 'TTCAC': 0, 'AAGGC': 0, 'TAACA': 0, 'CGGGC': 0, 'CCCTC': 0, 'AGCTT': 0})
queue: ['GTTGA']
result: ['CCCTC', 'AGCTT', 'AAGGC', 'CGGGC', 'TTCAC', 'TAACA', 'GTTGA']
in_counts: defaultdict(<class 'int'>, {'GTTGA': 0, 'CTGAG': 0, 'TTCAC': 0, 'AAGGC': 0, 'TAACA': 0, 'CGGGC': 0, 'CCCTC': 0, 'AGCTT': 0})
queue: ['CTGAG']
result: ['CCCTC', 'AGCTT', 'AAGGC', 'CGGGC', 'TTCAC', 'TAACA', 'GTTGA', 'CTGAG']
这与我的结果不同(见上文)

我知道
cggc
应该放在
CCCTC
之后,但是我不明白这怎么会与算法不冲突:一开始
CCCTC
AGCTT
的in度都是
0
,而
cggc
AGCTT
之后进入队列


我遗漏了什么?

我没有详细阅读您的示例,只是想确定一下:您是否意识到图形顶点的拓扑排序不是唯一的,因此尽管不同,您的算法可能会给出一个很好的答案?@m.raynal这是有道理的,我看不出什么能使我的答案与预期相符。我怀疑每个步骤都有一个我看不到的首选选项。顺序将取决于队列的行为(它弹出元素的顺序)。我认为有两种方法可以确保您的算法确实执行良好。您可以编写一个程序来测试您的输出是否确实是有效的拓扑排序,或者实现以字典顺序返回第一个拓扑排序,这具有唯一性的优点。Python 3.9有一个内置的拓扑排序器:
['CCCTC', 'CGGGC', 'AGCTT', 'AAGGC', 'TAACA', 'TTCAC', 'GTTGA', 'CTGAG']