Dire, abbiamo alcuni elementi, e ciascuno definisce alcune regole di ordinamento parziali, in questo modo:Ordinamento parziale dell'ordine?
Sono
A
e voglio essere primaB
Sono
C
e voglio essere dopoA
ma primaD
Così abbiamo elementi A,B,C,D
con queste regole:
A>B
C<A
,C>D
- nient'altro! Quindi,
B
eD
non hanno 'preferenze' nell'ordinare e sono considerati uguali.
Come vedete, le regole di relazione transitiva non funzionano qui. Tuttavia, se A>B
significa ancora che B<A
. Quindi, ci possono essere molteplici possibili risultati di smistamento:
- A B C D
- A C D B
- A C B D
- A B C D
Come posso implementare un algoritmo di ordinamento che gestisce una situazione del genere?
Il motivo: ci sei più moduli caricabili, e alcuni di loro 'dipendono' su altri in un modo. Ciascun modulo può dichiarare semplici regole, rispetto ad altri moduli:
me carico prima di modulo A
mi carico dopo modulo B
me carico prima di modulo A ma dopo il modulo B
ora ho bisogno di implementare questo ordinamento in qualche modo .. :)
Risposta: code da 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 con la terminologia. Ci sono molte implementazioni Python (ad esempio [questo] (http://www.bitformation.com/art/python_toposort.html)) se OP ha bisogno. – marcog
Aiutato molto, grazie! Tuttavia, questo ha poco a che fare con i grafici nella sua implementazione. La logica è: 0. creare una lista vuota 'ordinata'. 1. attraversare la lista, selezionare l'oggetto più piccolo 'min' (rispetto a tutti gli altri). Ci possono essere più piccoli, sceglierne uno. 2. Aggiungi 'min' a' sorted' 3. Se ci sono più elementi - torna a '1' – kolypto
@o_O Tync L'unica differenza è che la tua versione è' O (n^2) ', dove 'corretta' topologica l'ordinamento funziona in 'O (E)' (dove 'E' è il numero di dipendenze dei bordi). Per quanto riguarda la relazione con i grafici, l'intera struttura è un grafico, che ti piaccia o no :) –