serve un algoritmo grafico simile a DFS
-
22-09-2019 - |
Domanda
Sono curioso di sapere se esiste un algoritmo grafico specifico che attraversa un grafo orientato aciclico non ponderata scegliendo un nodo di partenza e poi di procedere tramite DFS. Se viene riscontrato un nodo che ha predecessori unsearched allora dovrebbe sostenere traccia i percorsi in entrata fino a quando tutti i percorsi per iniziare sono stati esplorati.
Ho trovato un wikipedia categoria per gli algoritmi grafico ma c'è un piccolo mare di algoritmi qui e io non sono familiarità con la maggior parte di loro.
EDIT: Esempio: dato il grafico {AB, EB, BC, BD}, traverse come: {A, B, E, B, C, D} o {ordine unico come A, B, E, C, D}. Nota questo algoritmo a differenza BFS o DFS non ha bisogno di ricominciare a un nuovo nodo di partenza, se tutti i percorsi del primo nodo di partenza sono esauriti.
Soluzione
In DFS, di solito si sceglie il vertice da visitare dopo u in base ai margini a partire da u. Si desidera scegliere in base prima sui bordi che terminano a u. Per fare questo, si potrebbe avere un trasporre grafico informazioni, e cercare di ottenere il vertice da lì prima.
Sarebbe qualcosa di simile:
procedure dfs(vertex u)
mark u as visited
for each edge (v, u) //found in transpose graph
if v not visited
dfs(v)
for each edge (u, w)
if v not visited
dfs(w)
Altri suggerimenti
Quello che state cercando è il tipo topologico. Per quanto io sappia non c'è un modo semplice per attraversare un grafico nel suo ordine topologico ordinato senza alcun precomputation.
Il metodo standard per ottenere il topsort è quello di fare uno standard DFS, e quindi memorizzare i nodi visitati in ordine di loro orari di visita. Infine, invertire quei nodi e voilà, li avete nell'ordine desiderato.
Pseudocodice:
list topsort
procedure dfs(vertex u)
mark u as visited
for each edge (u, v)
if v not visited
dfs(v)
add u to the back of topsort
La lista topsort
conterrà quindi i vertici in ordine inverso che si desidera. Basta invertire gli elementi di topsort per correggere questo.
Se siete alla ricerca di topological sort
, si può anche fare questo, dato un (o un elenco di bordi (u,v)
quale è possibile pre-elaborare in tempo O(E)
):
list top_sort( graph in adjacency list )
parent = new list
queue = new queue
for each u in nodes
parent(u) = number of parents
if ( parent(u) is 0 ) // nothing points to node i
queue.enqueue( u )
while ( queue is not empty )
u = queue.pop
add u to visited
for each edge ( u, v )
decrement parent(v) // children all have one less parent
if ( parent(v) is 0 )
queue.enqueue( v )
Dato un adjacency list
(o una lista di bordi (u,v)
), questo è O( V + E )
, dal momento che ogni bordo viene toccato due volte - una volta per incrementare, una volta per decrementare, in tempo O(1)
ciascuna. Con una coda normale, ogni vertice sarà anche elaborato dalla coda al massimo due volte - che può essere fatto anche in O(1)
con una coda standard
Si noti che questo è diverso dal DFS (almeno un'implementazione straight-up) in cui il programma gestisce le foreste.
Un'altra nota interessante è che se si queue
sostituto con un priority_queue
imponendo una sorta di struttura / ordinamento, si può effettivamente restituire i risultati ordinati in un certo ordine.
Ad esempio, per un grafico di classe canonica dipendenza (si può solo prendere la classe X se si ha classe Y):
100:
101: 100
200: 100 101
201:
202: 201
si sarebbe probabilmente ottenere, come risultato:
100, 201, 101, 202, 200
, ma se si cambia in modo che si vuole sempre prendere lezioni di basso numerate prima, si può facilmente cambiare per tornare:
100, 101, 200, 201, 202