Trovare una fonte di un grafico aciclico diretto in tempo lineare


10

Dato un grafico aciclico diretto , un vertice è una fonte se il suo indice è zero, il che significa che ha solo archi in uscita.D=(V,A)vV

Esiste un algoritmo temporale lineare per trovare una sorgente in un dato grafico aciclico diretto?

Domanda di follow-up: si può trovare in tempo lineare tutte le fonti?


2
Per radice, intendi un nodo che ha tutti i bordi in uscita e nessun bordo in entrata? In tal caso, potrebbero esserci più di una radice.
Paresh,

Si hai ragione. Ecco perché dico "una radice" ma non "la radice".
breezeintopl,

2
In tal caso, la definizione non è sufficiente per un algoritmo temporale lineare?
Paresh,

3
Qual è la struttura dei dati? Ti viene data una matrice di adiacenza, elenchi di quartiere, un elenco di adiacenza o cosa? Puoi controllare il vicinato (in arrivo) di un vertice in tempo proporzionale alla sua dimensione?
Pål GD,

5
Se intendi lineare nel numero di vertici, dovresti indicarlo. Inoltre, gli elenchi di adiacenza sono ambigui per i grafici diretti: stai elencando i bordi in entrata, i bordi in uscita, entrambi in elenchi separati o entrambi?
Yuval Filmus,

Risposte:


20

Come menziona Yuval, la struttura dei dati è importante qui. Proverò a fornire una soluzione per alcuni dei tipi di elenchi di adiacenza:

  1. Elenco dei bordi in entrata : per ciascun nodo, esiste un elenco di vertici da cui esiste un bordo in arrivo per questo nodo. Puoi semplicemente scansionare tutti i vertici e verificare se la dimensione del loro elenco di adiacenza è0 o no. Una taglia0elenco significa nessun fronte in arrivo, quindi il nodo è di origine o disconnesso. Supponendo un grafico collegato, questa scansione di ciascun vertice ti darà un elenco di tutte le fonti (o puoi fermarti dopo averne trovato uno) inO(|V|)tempo - lineare nel numero di vertici .
  2. Elenco dei bordi in uscita : per ciascun nodo, esiste un elenco di vertici verso i quali esiste un bordo diretto da questo nodo. Mantenere una stringa di bit con ogni bit che rappresenta un vertice, inizializzato su 0. A partire dal primo nodo, iniziare la scansione del suo elenco alla ricerca di vertici su cui esiste un bordo in uscita da questo. Ogni nodo (vicino) non può essere una sorgente, quindi continua a impostare il bit corrispondente nella stringa di bit. Alla fine, tutti i vertici i cui bit corrispondenti sono ancora non impostati, sono i vertici di origine. Puoi farlo in tempo lineare nella dimensione del grafico -O(|V|+|E|).
  3. Entrambi gli elenchi insieme : per ciascun vertice, esiste un elenco misto di vertici che hanno un bordo verso o da questo vertice, con qualche altro attributo che indica quale dei due è effettivamente il caso. L'approccio è simile a 2 sopra, con l'aggiunta che qualsiasi fronte in entrata esclude immediatamente il vertice corrente (e puoi contrassegnare il suo set di bit). A differenza del punto 2 in cui è necessario passare attraverso tutti i vertici, qui è possibile trovare prima una fonte. Se non ti fermi, avrai tutte le fonti. Per entrambi i casi, il tempo è di nuovo lineare nella dimensione del grafico -O(|V|+|E|).
  4. Entrambi gli elenchi separatamente : basta selezionare l'elenco dei bordi in entrata e seguire 1.

Come nota a margine, se la scelta della struttura dati è nelle tue mani, potresti voler analizzare quali operazioni intendi eseguire e con quale frequenza e scegliere una struttura dati appropriata.

Modifica: per il caso 1, se hai un dag in cui il numero di fonti è molto piccolo rispetto a|V|(ad esempio, in un albero con una sorgente) e in cui la distanza media da un vertice a una sorgente è ridotta rispetto a|V| e vuoi solo una fonte, puoi usare un algoritmo più veloce in media (anche se la complessità asintotica nel caso peggiore sarà la stessa). Seleziona qualsiasi vertice a caso, e vai a uno dei suoi genitori (dall'elenco dei bordi in entrata), e poi ai suoi genitori e così via, fino a raggiungere un nodo che non ha genitori - una fonte. Questo piccolo guadagno di efficienza è per tipi di grafici molto limitati con un algoritmo leggermente più complesso.


1
Per gli elenchi dei bordi in entrata, nel caso in cui sia necessario trovare un'unica fonte, non sarebbe più veloce seguire un limite arbitrario per ottenere il predecessore, fino a raggiungere una fonte? Soprattutto se il grafico è piatto, ovvero la distanza media da ogni sorgente di ogni vertice è molto più piccola di|V|.
Simon S,

@SimonS Anche se la complessità del caso peggiore è la stessa (ad es., Una catena lineare), potresti renderla più veloce se il grafico ha pochissime fonti (rispetto a |V|) e la distanza media da qualsiasi vertice a una sorgente è molto piccola, ad es. un grafico a stelle con il centro come sorgente. Avere solo la condizione menzionata non è sufficiente - ad es. 1-> 2, 1-> 3, 4-> 2, 4-> 3 - (è possibile avere un grafico con distanza media 0,5 e fonti | V | / 2) la distanza media è piccola, ma entrambi gli algoritmi daranno lo stesso / simile tempo previsto. Lo aggiungerò alla mia risposta però.
Paresh,

La ringrazio per la risposta! Penso che ciò che intendo sia il secondo caso, lista in uscita. A proposito, perché è O (| V | + | E |)? Conosco | E |, perché devi scansionare tutti i bordi, ma dove | V | a partire dal? Grazie!
breezeintopl,

@breezeintopl È un modo di rappresentare. Controlli ogni bordo una volta e ogni vertice anche un numero costante di volte. Per lo meno, alla fine devi scansionare tutti i vertici una volta per vedere quali bit non sono impostati. Un altro modo di osservarlo è che utilizza un elenco di adiacenzaΘ(|V|+|E|)spazio: memorizza un vertice e il suo elenco di bordi. E stai attraversando l'intero elenco. Certo, da allora|E| può variare da O(|V|) per O(|V|2), potresti semplicemente saltare il |V|parte. Vedi un esempio per BFS .
Paresh,

0

Consideriamo una domanda più semplice. Supponi di sapere che il tuo grafico è un albero. Quindi è possibile trovare il nodo di origine in tempo lineare. Basta selezionare un nodo casuale, se è la radice, allora hai la tua risposta, in caso contrario dovrebbe essere un figlio o un genitore, quindi tornare indietro fino a raggiungere la radice. Questo può essere fatto inO(|V|-1).


3
Se la struttura dei dati non include un elenco di in-edge per un nodo, la ricerca del genitore richiede già O (m) (negli alberi da qui il tempo O (n). Dal momento che il percorso alla radice dell'albero può essere lineare lunga, questa è solo una soluzione quadratica, ma se hai in-edge, trovare un nodo con 0 in
edge

-1

Supponendo di avere un grafico G = (V, E) indicato nel formato dell'elenco di adiacenza. (per essere chiari qui l'elenco contiene tutti i bordi in uscita dalla sorgente). È possibile costruire l'inverso del grafico G in tempo lineare. Quindi è possibile scorrere il grafico inverso e raccogliere tutti i vertici con un elenco di adiacenza vuoto. Questi vertici non hanno un bordo in uscita nel grafico inverso, il che significa che non hanno bordi in entrata nel grafico originale, quindi questi sono i vertici di origine.

Il tempo di esecuzione è lineare. La costruzione dell'inverso del grafico richiede un tempo massimo di O (| V | + | E |). L'iterazione sull'inverso del grafico richiede tempo O (| V |).


1
Onestamente, calcolare l'inverso del grafico suona come un problema più difficile che trovare le fonti. Dubito che qualcuno che non riesce a capire come ottenere le fonti possa capire come invertire tutti i bordi.
David Richerby,

@DavidRicherby hai detto che calcolare l'inverso del grafico è più difficile. Come si definisce più difficile? Se è la complessità temporale, può essere fatto in tempo lineare. puoi consultare la soluzione qui [link] ( stackoverflow.com/questions/40378152/… ). La domanda riguarda una soluzione temporale lineare che trova l'origine di un grafico e la mia soluzione proposta lo fa. Se pensi di no, puoi essere specifico e dirmi come il mio algoritmo non soddisfa il requisito di tempo lineare?
MGB,

Intendo concettualmente più difficile. Stai dicendo che, per risolvere questo esercizio, il richiedente deve solo risolvere qualche altro esercizio, ma quell'altro esercizio sembra più difficile del primo.
David Richerby,
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.