Ricerca grafica: larghezza prima e profondità prima


79

Durante la ricerca di grafici, esistono due semplici algoritmi: breadth-first e depth-first (solitamente eseguito aggiungendo tutti i nodi grafici adiacenti a una coda (breadth-first) o stack (depth-first)).

Ora, ci sono dei vantaggi l'uno rispetto all'altro?

Quelli a cui potrei pensare:

  • Se ti aspetti che i tuoi dati siano abbastanza lontani all'interno del grafico, la profondità potrebbe trovarli prima, dato che stai andando molto velocemente nelle parti più profonde del grafico.
  • Viceversa, se ti aspetti che i tuoi dati siano piuttosto lontani nel grafico, l' ampiezza prima potrebbe dare il risultato prima.

C'è qualcosa che mi è sfuggito o dipende principalmente dalle preferenze personali?

Risposte:


43

Vorrei citare una risposta da Stack Overflow di hstoerr che copre bene il problema:

Ciò dipende fortemente dalla struttura dell'albero di ricerca e dal numero e dalla posizione delle soluzioni .
Se sai che una soluzione non è lontana dalla radice dell'albero, una prima ricerca della larghezza (BFS) potrebbe essere migliore. Se l'albero è molto profondo e le soluzioni sono rare, la prima ricerca di profondità (DFS) potrebbe essere utilizzata per sempre, ma BFS potrebbe essere più veloce. Se l'albero è molto largo, un BFS potrebbe aver bisogno di troppa memoria, quindi potrebbe essere completamente poco pratico. Se le soluzioni sono frequenti ma situate in profondità nell'albero, la BFS potrebbe non essere pratica. Se l'albero di ricerca è molto profondo, è necessario limitare la profondità di ricerca per la prima ricerca di profondità (DFS), comunque (ad esempio con approfondimento iterativo).

Ma queste sono solo regole empiriche; probabilmente dovrai sperimentare.

Rafał Dowgird osserva inoltre:

Alcuni algoritmi dipendono da particolari proprietà di DFS (o BFS) per funzionare. Ad esempio, l'algoritmo Hopcroft e Tarjan per la ricerca di componenti a 2 connessioni sfrutta il fatto che ogni nodo già visitato incontrato da DFS si trova sul percorso dalla radice al nodo attualmente esplorato.


5
Non riesco a capire perché questa risposta abbia 27 voti ed è esattamente la fusione di altre 2 risposte, che tra l'altro sono semplicemente pensieri generali su ...
nbro

37

Un punto importante nel nostro mondo multicore: BFS è molto più facile da parallelizzare. Questo è intuitivamente ragionevole (invia i thread per ogni bambino) e può essere dimostrato che lo è anche. Quindi, se hai uno scenario in cui puoi usare il parallelismo, allora BFS è la strada da percorrere.


8
Se DFS è altrimenti vantaggioso nell'impostazione fornita, è possibile applicare BFS fino a quando non sono stati generati abbastanza thread e si continua con DFS. Più specificamente, puoi fare DFS e ogni volta che scendi e non ci sono abbastanza thread, generane uno per il prossimo fratello.
Raffaello

Questa risposta non merita 20 voti. La domanda riguarda l'uso generale dei 2 algoritmi e non un uso particolare.
nbro,

31

(L'ho trasformato in un wiki della community. Non esitate a modificare.)

Se

  • B
  • d
  • hdh

Poi

  • O(Bh)O(h)
  • O(Bd)O(Bd)
  • O(Bd)O(d)

Motivi per scegliere

  • DFS
    • deve comunque vedere l'intero albero
    • d
    • non importa se la risposta è la più vicina alla radice
  • BFS
    • la risposta è vicina alla radice
    • vuoi la risposta più vicina alla radice
    • hanno più core / processori
  • IDDFS
    • vuoi BFS, non hai abbastanza memoria, ma un po 'più lento è accettabile

IDDFS = approfondimento iterativo approfondimento prima ricerca


1
Questa è una risposta eccellente Noto però che mentre la domanda fa domande sui grafici, questa risposta si riferisce agli alberi. Un albero è un grafico ovviamente, e può essere la parola può essere sostituita ... ma che ne dici h, "altezza dell'albero". Ciò si traduce direttamente in "altezza del grafico"?
user2023370,

Un altro motivo per utilizzare IDDFS è che, a seconda di come lo si desidera, dopo ogni iterazione è possibile avere una possibile risposta (se si sta cercando, diciamo, un massimo o un minimo). Ciò significa che puoi uscire presto dall'algoritmo se la tua risposta è "abbastanza buona" o puoi uscire dall'input dell'utente (come un motore di scacchi che utilizza IDDFS per trovare una soluzione ottimale ma essere interrotto da un giocatore che muove un pezzo).
jedd.ahyoung,

Un altro punto da aggiungere è che il DFS usa lo stack mentre il BFS usa la coda.
Karthik Balaguru,

17

Uno scenario (oltre a trovare il percorso più breve, che è già stato menzionato) in cui potresti dover scegliere uno sopra l'altro per ottenere un programma corretto sarebbe infiniti grafici:

Se consideriamo ad esempio un albero in cui ogni nodo ha un numero finito di figli, ma l'altezza dell'albero è infinita, DFS potrebbe non trovare mai il nodo che stai cercando - continuerà a visitare il primo figlio di ogni nodo vede, quindi se quello che stai cercando non è il primo figlio del suo genitore, non ci arriverà mai. BFS è comunque garantito per trovarlo a tempo finito.

Allo stesso modo se consideriamo un albero in cui ogni nodo ha un numero infinito di figli, ma l'albero ha un'altezza finita, BFS potrebbe non terminare. Visiterà solo i figli del nodo radice e se il nodo che stai cercando è figlio di un altro nodo, non verrà raggiunto. In questo caso DFS è garantito per trovarlo a tempo finito.


7
È interessante notare che entrambi producono solo algoritmi di semi-decisione per infiniti grafici; non puoi decidere a tempo finito che un elemento non è nell'albero (ovviamente). Per quanto riguarda le applicazioni pratiche, si noti che è possibile definire ( concettualmente) infinite strutture di dati (vedere paragrafo 3.4)!
Raffaello

15

L'ampiezza prima e la profondità prima hanno certamente lo stesso comportamento nel caso peggiore (il nodo desiderato è l'ultimo trovato). Ho il sospetto che ciò sia vero anche nel caso averave se non hai informazioni sui tuoi grafici.

Un bel vantaggio della ricerca in ampiezza è che trova percorsi più brevi (nel senso del minor numero di fronti) che possono essere o meno interessanti.

Se il grado medio dei nodi (numero di vicini) è elevato rispetto al numero di nodi (ovvero il grafico è denso), breadth-first avrà code enormi, mentre depth-first avrà stack piccoli. Nei grafici sparsi, la situazione è invertita. Pertanto, se la memoria è un fattore limitante, la forma del grafico a portata di mano potrebbe dover informare la scelta della strategia di ricerca.


La lunghezza della coda in bfs e l'altezza dello stack in dfs dipende molto dall'implementazione. Se nel caso di dfs si espande sempre tutto il vicino nello stack, allora cresce molto, specialmente quando il grafico è denso. Spingendo solo il riferimento che dice dove continuare quando dfs ritorna dalla ricorsione si risparmia molto spazio.
uli

3

Tutto quanto sopra è corretto, ma è degno di nota che BFS e DFS creano i propri alberi, in base all'ordine che usano per attraversare l'albero. Ognuno di questi alberi ha una propria proprietà che può essere utile in una sorta di problemi.

Ad esempio, tutti i bordi nel grafico originale che non si trovano nell'albero BFS sono bordi trasversali; bordi che si trovano tra due rami dell'albero BFS. Tutti i bordi nel grafico originale che non si trovano nell'albero DFS sono bordi posteriori; bordi che collegano due vertici in un ramo dell'albero DFS. Tali proprietà possono essere utili per problemi come coloranti speciali, ecc.


1

L'albero DFS e BFS hanno entrambe le loro proprietà uniche che possono darti informazioni più utili sul grafico. Ad esempio con un singolo DFS è possibile effettuare le seguenti operazioni:

  • Trova ponti e punti di articolazione (per grafici non indirizzati)
  • Rilevazione del ciclo
  • Trova componenti fortemente connessi (algoritmo di Tarjan)

Con BFS, puoi trovare i percorsi più brevi tra il nodo di origine e qualsiasi altro nodo nel grafico.

Il capitolo Algoritmi grafici in CLRS riassume molto bene queste proprietà di DFS e BFS.


-2

Penso che sarebbe interessante scrivere entrambi in un modo che solo cambiando alcune righe di codice ti darebbe un algoritmo o l'altro, in modo che vedrai che il tuo dillema non è così forte come sembra all'inizio .

Personalmente mi piace l'interpretazione di BFS come inondazione di un paesaggio: le aree a bassa quota saranno inondate per prime, e solo dopo le aree ad alta quota seguiranno. Se immagini le altitudini del paesaggio come isoline come vediamo nei libri di geografia, è facile vedere che BFS riempie tutta l'area sotto lo stesso isoline allo stesso tempo, proprio come questo sarebbe con la fisica. Pertanto, interpretare le altitudini come distanza o costo in scala dà un'idea abbastanza intuitiva dell'algoritmo.

Con questo in mente, puoi facilmente adattare l'idea alla base della prima ricerca per trovare facilmente l'albero di spanning minimo, il percorso più breve e anche molti altri algoritmi di minimizzazione.

Non ho ancora visto alcuna interpretazione intuitiva di DFS (solo quella standard sul labirinto, ma non è potente come quella BFS e inondazioni), quindi per me sembra che BFS sembra correlare meglio con i fenomeni fisici come descritto sopra, mentre Il DFS si correla meglio con le scelte dillema sui sistemi razionali (cioè persone o computer che decidono quale mossa fare in una partita a scacchi o uscire da un labirinto).

Quindi, per me la differenza tra bugie su quale fenomeno naturale si adatta meglio al loro modello di propagazione (trasversale) nella vita reale.


2
Benvenuti nel sito! Tuttavia, non vedo davvero come questo risponda alla domanda. Sembra che siano i tuoi sentimenti e le tue intuizioni generali su BFS e DFS, ma la domanda non si pone su sentimenti e intuizioni: si tratta di vantaggi e svantaggi. La tua risposta non sembra risolverla affatto.
David Richerby,

La parte più legata alla domanda riguarda l'adattamento dell'algoritmo per trovare alberi spanning minimi, percorso più breve e così via, e dire che alcuni fenomeni naturali sono riproducibili da BFS, mentre alberi decisionali da DFS
user5193682

1
La domanda non sta ponendo ciò che è legato a BFS e DFS. Non si sta chiedendo di trovare alberi che si estendono o percorsi più brevi o come "riprodurre fenomeni naturali".
David Richerby,

Sta chiedendo vantaggi. Se uno può modellare un fenomeno fisico mentre l'altro non può, è un vantaggio se è necessario modellare questo fenomeno. Penso che tu stia rispettando i concetti standard del manuale degli algoritmi quando interpreti la parola "vantaggio", mentre io non lo sono
user5193682
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.