偏序排序?

时间:2011-01-06 21:32:19

标签: python algorithm topological-sort

说,我们有一些项目,每个项目都定义了一些部分排序规则,如下所示:

  

A我希望在B

之前      

C我希望在A之后D之前

所以我们有A,B,C,D项符合这些规则:

  • A>B
  • C<AC>D
  • 别的!因此,BD在订购时没有“偏好”,并且被视为相同。

如您所见,传递关系规则在这里不起作用。但是,如果A>B仍然表示B<A。因此,可能有多种可能的排序结果:

  1. A B C D
  2. A C D B
  3. A C B D
  4. A B C D
  5. 如何实现处理这种情况的排序算法?


    原因:有多个可加载模块,其中一些模块在某种程度上“依赖”其他模块。相对于其他模块,每个模块都可以声明简单的规则:

      

    在模块A之前加载我

         

    在模块B之后加载我

         

    在模块A之前但在模块B之后加载我

    现在我需要以某种方式实现这个排序.. :)


    答案:code由Paddy McCarthy(麻省理工学院)

    ## {{{ http://code.activestate.com/recipes/577413/ (r1)
    try:
        from functools import reduce
    except:
        pass
    
    data = {
        'des_system_lib':   set('std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee'.split()),
        'dw01':             set('ieee dw01 dware gtech'.split()),
        'dw02':             set('ieee dw02 dware'.split()),
        'dw03':             set('std synopsys dware dw03 dw02 dw01 ieee gtech'.split()),
        'dw04':             set('dw04 ieee dw01 dware gtech'.split()),
        'dw05':             set('dw05 ieee dware'.split()),
        'dw06':             set('dw06 ieee dware'.split()),
        'dw07':             set('ieee dware'.split()),
        'dware':            set('ieee dware'.split()),
        'gtech':            set('ieee gtech'.split()),
        'ramlib':           set('std ieee'.split()),
        'std_cell_lib':     set('ieee std_cell_lib'.split()),
        'synopsys':         set(),
        }
    
    def toposort2(data):
        for k, v in data.items():
            v.discard(k) # Ignore self dependencies
        extra_items_in_deps = reduce(set.union, data.values()) - set(data.keys())
        data.update({item:set() for item in extra_items_in_deps})
        while True:
            ordered = set(item for item,dep in data.items() if not dep)
            if not ordered:
                break
            yield ' '.join(sorted(ordered))
            data = {item: (dep - ordered) for item,dep in data.items()
                    if item not in ordered}
        assert not data, "A cyclic dependency exists amongst %r" % data
    
    print ('\n'.join( toposort2(data) ))
    ## end of http://code.activestate.com/recipes/577413/ }}}
    

2 个答案:

答案 0 :(得分:19)

您需要构建一个dependency graph(这只是一种有向图的风格),然后按照topologically sorted排序。自从我参加组合学课程以来已经有一段时间了,因此维基百科的文章可能比拓扑排序算法更有帮助。我希望给你合适的术语是有帮助的。 :)

就构建图形而言,基本上只需要让每个模块都包含该模块依赖项的列表。

你只需要稍微改写你的规则......“我是C而我想要在A之后,但在D之前”将表示为“C取决于A”以及“D取决于C“,这样一切都在标准方向流动。

答案 1 :(得分:0)

以下操作将为数字返回字典,其数字为变量的值:

以降序列出它们以获得所需的输出

state.newValue='new value'