說,我們有一些項目,每個定義了一些局部的排序規則是這樣的:部分訂單排序?
我
A
,我想我C
前B
,我想成爲
A
之後,但在D
因此,我們必須與這些規則的項目A,B,C,D
:
A>B
C<A
,C>D
- 沒有別的!因此,
B
和D
在排序中沒有「偏好」,並且被認爲是相等的。
如您所見,傳遞關係規則在這裏不起作用。但是,如果A>B
仍然表示B<A
。因此,可以有排序的多種可能的結果:
- A B C d
- A C d乙
- A C B d
- A B C d
我如何能實現排序算法來處理這種情況呢?
原因:有多個可加載的模塊,其中一些以某種方式「依賴於」他人。每個模塊都可以聲明簡單的規則,相對於其它模塊:
裝入箱模塊之前甲
模塊B後裝入箱
模塊A之前,但模塊B後裝入箱
現在我需要以某種方式實現這個順序.. :)
答:code由帕迪·麥卡錫(MIT)
## {{{ 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/ }}}
+1用術語點亮。如果OP需要,有很多Python實現(例如[this one](http://www.bitformation.com/art/python_toposort.html))。 – marcog 2011-01-06 21:47:54