Say, chúng tôi có một số mặt hàng, và mỗi định nghĩa một số quy tắc phân loại từng phần, như thế này:Sắp xếp thứ tự một phần?
Tôi
A
và tôi muốn trở thành trướcB
Tôi
C
và tôi muốn trở thành sauA
nhưng trước khiD
Vì vậy, chúng tôi có các mục A,B,C,D
với những quy tắc:
A>B
C<A
,C>D
- không có gì khác! Vì vậy,
B
vàD
không có 'tùy chọn' theo thứ tự và được coi là bằng nhau.
Như bạn thấy, các quy tắc quan hệ chuyển tiếp không hoạt động ở đây. Tuy nhiên, nếu A>B
nó vẫn có nghĩa là B<A
. Vì vậy, có thể có nhiều kết quả có thể phân loại:
- A B C D
- A C D B
- A C B D
- A B C D
Làm thế nào tôi có thể thực hiện một thuật toán sắp xếp để xử lý một tình huống như vậy?
Lý do: có nhiều mô-đun có thể tải và một số phụ thuộc vào người khác theo cách. Mỗi module có thể tuyên bố quy tắc đơn giản, liên quan đến các module khác:
Tải tôi trước khi module A
Tải tôi sau khi mô-đun B
Tải tôi trước khi module A nhưng sau khi mô-đun B
bây giờ tôi cần phải thực hiện thứ tự này bằng cách nào đó .. :)
Trả lời: code bởi Paddy McCarthy (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 Spot-on với thuật ngữ. Có rất nhiều triển khai Python (ví dụ: [this one] (http://www.bitformation.com/art/python_toposort.html)) nếu OP cần. – marcog
Giúp đỡ rất nhiều, cảm ơn bạn! Tuy nhiên, điều này ít liên quan đến đồ thị trong việc thực hiện nó. Logic là: 0. tạo một danh sách rỗng 'sắp xếp'. 1. đi qua danh sách, chọn mục nhỏ nhất 'min' (so với tất cả những thứ khác). Có thể có nhiều cái nhỏ nhất, chọn bất kỳ cái nào. 2. Thêm 'min' vào' sắp xếp' 3. Nếu có nhiều mục hơn - lặp lại thành '1' – kolypto
@o_O Tync Sự khác biệt duy nhất là phiên bản của bạn là' O (n^2) ', trong đó cấu trúc liên kết 'thích hợp' phân loại hoạt động trong 'O (E)' (trong đó 'E' là số phụ thuộc cạnh). Đối với mối quan hệ với đồ thị, toàn bộ cấu trúc của bạn là biểu đồ, cho dù bạn có thích hay không :) –