2010-01-14 9 views
5

Dato un elenco di classi che ereditano da questa base:Un algoritmo pulito per l'ordinamento di oggetti in base a dipendenze definite?

class Plugin(object): 
    run_after_plugins =() 
    run_before_plugins =() 

... e le seguenti regole:

  • plugin possono fornire una lista di plugin che devono correre dopo.
  • I plug-in possono fornire un elenco di plug-in che devono essere eseguiti prima.
  • L'elenco di plug-in può contenere o meno tutti i plug-in che sono stati specificati nei vincoli di ordinamento.

Qualcuno può fornire un buon algoritmo pulito per ordinare un elenco di plug-in? Sarà necessario rilevare le dipendenze circolari così ....

def order_plugins(plugins): 
     pass 

mi è venuta in mente un paio di versioni, ma nulla particuarlly pulito: sono sicuro che alcuni di voi Art of Computer Programming tipi sarà assaporare la sfida :)

[Nota: domanda dato in Python, ma è chiaro che non è solo una questione di Python: pseudocodice in qualsiasi lingua farebbe]

risposta

8

questo è chiamato topological sorting.

L'applicazione canonica di ordinamento topologico (topologico ordine) è in pianificazione di una sequenza di posti di lavoro o attività; Gli ordinamenti topologici degli algoritmi sono stati studiati per la prima volta negli anni '60 nel contesto della tecnica PERT per la pianificazione nella gestione del progetto (Jarnagin 1960). I lavori sono rappresentati da vertici, e non vi è un vantaggio da X a Y se lavoro x deve essere completata prima di lavoro Y può essere avviato (ad esempio, quando si lava i vestiti, la lavatrice deve finitura prima di mettere i vestiti a secco). Quindi, un ordinamento topologico fornisce a un ordine in cui eseguire i lavori.

+0

@Eli: ho trovato questa domanda (http://stackoverflow.com/questions/952302/how-to-sort-based-on-dependencies) che ha menzionato questo tipo di ordinamento proprio ora ma l'esempio fornito non avere due tipi distinti di dipendenze da ordinare: può anche questo trattare con questo caso? – jkp

+2

@jkp: può essere convertito in quella rappresentazione. Ad esempio, A dice che B deve correre prima di esso, ma C dopo di esso. Quindi, con i soli vincoli "dopo", diciamo che A è dopo B e C è dopo A. –

+0

@Eli: haha! sì, immagino che quando lo accendi è come se fosse applicato in modo pulito. Un vincolo precedente su un plug-in è solo un vincolo successivo per un altro :) – jkp

1

Questo è chiamato topological sorting.

Fare questo comporta diversi passaggi:

prima costruire un grafico di tutti i plugin scelti come i vertici e le loro dipendenze come bordi. Esegui prima/dopo le deps riducono allo stesso tipo di bordi.

Avanti costruisci uno scafo di transito: guarda tutti i plugin e aggiungi tutte le dipendenze mancanti. Ripeti fino a quando l'insieme non cambia più.

Ultimo passaggio: scegliere una vertice senza bordi in entrata e fare una ricerca DFS (o BFS). Questo algoritmo può essere arricchito con il rilevamento del ciclo.

0

Se si definisce il __lt__ ei metodi associati sul plug-in in base al fatto che debbano essere eseguiti prima o dopo, è possibile trovare un ordinamento sano con sorted(). I cicli sarebbero comunque un problema.

2

Here è un codice Python che esegue l'ordinamento topologico.

+0

@ ΤΖΩΤΖΙΟΥ: Sì, l'ho trovato anche io. È stato un po 'lungo per quello che volevo: la mia versione corrispondeva perfettamente all'esempio dato nel post che ho collegato nei commenti di Eli. Ho comunque imparato un nuovo trucco che è la cosa principale :) – jkp

Problemi correlati