Ok questo è il mio primo post su Stack Overflow che sto leggendo da un po 'e ammiro davvero il sito. Spero che questo sia qualcosa che sarà accettabile da chiedere. Quindi ho letto gli Intro to Algorithms (Cormen. MIT Press) fino in fondo e sono all'altezza degli algoritmi del grafico. Ho studiato gli algoritmi formali predisposti per l'ampiezza e la profondità per la prima ricerca con dettagli molto precisi.Depth-First Search (DFS) non ricorsivo utilizzando uno stack
Ecco il pseudo-codice dato per la ricerca in profondità:
DFS(G)
-----------------------------------------------------------------------------------
1 for each vertex u ∈ G.V
2 u.color ← WHITE // paint all vertices white; undiscovered
3 u.π ← NIL
4 time ← 0 // global variable, timestamps
5 for each vertex u ∈ G.V
6 if u.color = WHITE
7 DFS-VISIT(G,u)
DFS-VISIT(G, u)
-----------------------------------------------------------------------------------
1 u.color ← GRAY // grey u; it is discovered
2 time ← time + 1
3 u.d ← time
4 for each v ∈ G.Adj[u] // explore edge (u,v)
5 if v.color == WHITE
6 v.π ← u
7 DFS-VISIT(G,v)
8 u.color ← BLACK // blacken u; it is finished
9 time ← time + 1
10 u.f ← time
Questo algoritmo è ricorsiva e procede da più fonti (si scoperto ogni vertice nel grafico non collegato). Ha diverse proprietà che la maggior parte delle implementazioni linguistiche potrebbero tralasciare. Distingue tra 3 diversi "colori" di vertici. Dipinge inizialmente tutti di bianco, poi quando vengono "scoperti" (visitati in DFS-VISIT) vengono poi dipinti in grigio. L'algoritmo DFS-VISIT esegue un ciclo ricorsivamente chiamandosi nell'elenco di adiacenza del vertice corrente e dipinge solo un vertice nero quando non ha più bordi su alcun nodo bianco.
Anche due altri attributi di ciascun vertice vengono mantenuti u.d e u.f sono i timestamp di quando il vertice è stato scoperto (verniciato grigio) o quando un vertice è finito (verniciato nero). La prima volta che viene dipinto un nodo ha un timestamp di uno e viene incrementato al successivo valore intero per ogni volta che viene dipinto un altro (sia esso grigio o nero). viene mantenuto anche u.π che è solo un puntatore al nodo da cui è stato scoperto.
Algorithm Non-Recursive-DFS(G)
-----------------------------------------------------------------------------------
1 for each vertex u ∈ G.V
2 u.color ← WHITE
3 u.π ← NIL
4 time = 0
5 for each vertex u ∈ G.V
6 if u.color = WHITE
7 u.color ← GRAY
8 time ← time + 1
9 u.d ← time
7 push(u, S)
8 while stack S not empty
9 u ← pop(S)
10 for each vertex v ∈ G.Adj[u]
11 if v.color = WHITE
12 v.color = GRAY
13 time ← time + 1
14 v.d ← time
15 v.π ← u
16 push(v, S)
17 u.color ← BLACK
18 time ← time + 1
19 u.f ← time
* EDIT * 10/31/12 Questo è imbarazzante che il mio algoritmo è stato corretto per così tanto tempo, che avrebbe funzionato nella maggior parte dei casi, ma non tutti. Ho appena ricevuto un distintivo di domanda popolare per la domanda e ho visto dove Irfy aveva individuato il problema nella sua risposta qui sotto, quindi è qui che va il merito. Sto solo aggiustandolo qui per chiunque ne abbia bisogno in futuro.
Qualcuno vede un difetto con l'algoritmo di cui sopra? Non sono un esperto di teoria dei grafi, ma penso di avere una buona conoscenza della ricorsione e dell'iterazione e credo che questo dovrebbe funzionare allo stesso modo. Sto cercando di renderlo funzionalmente equivalente all'algoritmo ricorsivo. Dovrebbe mantenere tutti gli attributi del primo algoritmo anche se non sono necessari.
Quando ho iniziato a scrivere, non pensavo che avrei avuto un triplo loop, ma è andata così. Ho visto altri algoritmi iterativi quando ho cercato su Google che aveva solo un ciclo doppiamente annidato, tuttavia, non sembra provenire da più fonti. (cioè non scopriranno ogni vertice del grafico non connesso)
Si prega di correggere il rientro dopo l'istruzione 'if' nel secondo ciclo nel secondo algoritmo. Idealmente anche il rientro dopo il primo ciclo 'for' – Irfy
Fatto il montaggio proprio ora, questo è quello che avevo originariamente. –
I tempi di finitura calcolati dalla versione non ricorsiva saranno errati. u.f <-time può essere impostato solo dopo che tutti i discendenti hanno impostato il tempo di fine. Se si prende lo stesso esempio in CLRS, allora il nodo u avrebbe un tempo di fine = 3, mentre il valore effettivo avrebbe dovuto essere 8. –