【问题标题】:What's the most efficient algorithm for topologically sorting a (special case of a) directed acyclic graph?对有向无环图(a的特殊情况)进行拓扑排序的最有效算法是什么?
【发布时间】:2016-09-11 18:33:38
【问题描述】:

我有一个数据集,它是有向无环图 (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')]

【问题讨论】:

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


    【解决方案1】:

    到目前为止,这是我能想到的最好的算法:

    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()s。有人能想到对此有何改进吗?我忽略了哪些明显的低效率?

    谢谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-24
      • 2010-11-07
      相关资源
      最近更新 更多