说,我们有一些项目,每个项目都定义了一些部分排序规则,如下所示:
我
之前A
我希望在B
我
C
我希望在A
之后D
之前
所以我们有A,B,C,D
项符合这些规则:
A>B
C<A
,C>D
B
和D
在订购时没有“偏好”,并且被视为相同。如您所见,传递关系规则在这里不起作用。但是,如果A>B
仍然表示B<A
。因此,可能有多种可能的排序结果:
如何实现处理这种情况的排序算法?
原因:有多个可加载模块,其中一些模块在某种程度上“依赖”其他模块。相对于其他模块,每个模块都可以声明简单的规则:
在模块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/ }}}
答案 0 :(得分:19)
您需要构建一个dependency graph(这只是一种有向图的风格),然后按照topologically sorted排序。自从我参加组合学课程以来已经有一段时间了,因此维基百科的文章可能比拓扑排序算法更有帮助。我希望给你合适的术语是有帮助的。 :)
就构建图形而言,基本上只需要让每个模块都包含该模块依赖项的列表。
你只需要稍微改写你的规则......“我是C而我想要在A之后,但在D之前”将表示为“C取决于A”以及“D取决于C“,这样一切都在标准方向流动。
答案 1 :(得分:0)
state.newValue='new value'