什么是拓扑排序(特殊情况下)有向无环图的最有效算法?

时间:2016-09-11 18:33:39

标签: python algorithm python-3.x directed-acyclic-graphs topological-sort

我有一个数据集,它是有向无环图(DAG)的特例。我的DAG中的节点有0或1个弧。所有弧都是相等加权的(也就是说,弧中包含的唯一信息是它指向的节点,没有“距离”或“成本”或“权重”)。

我的用户将以半随机顺序输入节点,期望保留无弧节点的顺序,但所有弧在指向它们的节点之前进行排序(因此以子项排序)。

这是一个表示我的数据的简化类:

class Node:
    def __init__(self, name, arc=None):
        self.name = str(name)
        self.arc = str(arc)

(注意self.arc是指向节点的字符串表示,而不是对象本身)

所以,给出这样的输入:

input = [Node('A'),
         Node('B'),
         Node('C'),
         Node('Z', 'Y'),
         Node('X', 'W'),
         Node('Y', 'X'),
         Node('W')]

你会得到这样的输出,最好使用最少的循环和中间数据结构:

output = [Node('A'),
          Node('B'),
          Node('C'),
          Node('W'),
          Node('X', 'W'),
          Node('Y', 'X'),
          Node('Z', 'Y')]

1 个答案:

答案 0 :(得分:0)

到目前为止,这是我能够提出的最佳算法:

def topo_sort(nodes):
    objects = {}           # maps node names back to node objects
    graph = OrderedDict()  # maps node names to arc names
    output = []
    for node in nodes:
        objects[node.name] = node
        graph[node.name] = node.arc
    arcs = graph.values()

    # optional
    missing = set(arcs) - set(graph) - {None}
    if missing:
        print('Invalid arcs: {}'.format(', '.join(missing)))

    def walk(arc):
        """Recurse down the tree from root to leaf nodes."""
        obj = objects.get(arc)
        if obj and obj not in output:
            follow_the_arcs(graph.get(arc))
            output.append(obj)

    # Find all root nodes
    for node in graph:
        if node not in arcs:
            walk(node)
    return ordered

我喜欢的是,只有2个循环(一个用于构建图形,一个用于查找根),输出仅使用list.append()构建,没有慢list.insert()个。任何人都可以想到对此有任何改进吗?我忽略了任何明显的低效率?

谢谢!