Quando sono gli elenchi di adiacenza o le matrici la scelta migliore?


15

Mi è stato detto che avremmo usato un elenco se il grafico fosse sparso e una matrice se il grafico fosse denso . Per me, è solo una definizione grezza. Non vedo molto oltre. Puoi chiarire quando sarebbe la scelta naturale da fare?

Grazie in anticipo!



Questa non è una definizione, soprattutto perché non esiste un'unica definizione di "rado" e "denso". Inoltre, ci sono altre considerazioni, ad esempio a quali aspetti del grafico si accede con che frequenza.
Raffaello

@Raphael Puoi approfondire le altre considerazioni?
user21312

1
@utente21312, una grande differenza è l'iterabilità rispetto all'accesso dei bordi. Se hai spesso bisogno di iterare sui bordi, l'elenco adj potrebbe essere più utile. Se è spesso necessario determinare se esiste un bordo o accedere al suo peso (o altre informazioni), la matrice potrebbe essere migliore.
Ryan,

Per il tuo scopo, probabilmente potremmo trascurarci qual è la definizione di "rado" e "denso". Modella semplicemente la complessità temporale dell'operazione di matrice che desideri utilizzare per ogni tipo di struttura di dati e vedi dove si trova il "punto di rottura della densità". Penso che il secondo link di @ryan stia cercando di fare qualcosa di simile
Apiwat Chantawibul,

Risposte:


17

Prima di tutto nota che sparso significa che hai pochissimi spigoli e denso significa molti spigoli o grafico quasi completo. In un grafico completo hai bordi, dove n è il numero di nodi.n(n1)/2n

Ora, quando utilizziamo la rappresentazione matrice, allochiamo la matrice per memorizzare le informazioni sulla connettività del nodo, ad esempio M [ i ] [ j ] = 1 se c'è un bordo tra i nodi i e j , altrimenti M [ i ] [ j ] = 0 . Ma se utilizziamo l'elenco di adiacenza allora abbiamo una matrice di nodi e ogni nodo punta al suo elenco di adiacenza contenente SOLO i suoi nodi vicini .n×nM[i][j]=1ijM[i][j]=0

Ora se un grafico è scarso e utilizziamo la rappresentazione matrice, la maggior parte delle celle della matrice rimane inutilizzata, il che porta allo spreco di memoria. Pertanto, di solito non utilizziamo la rappresentazione matriciale per grafici sparsi. Preferiamo l'elenco di adiacenza.

Ma se il grafico è denso, il numero di spigoli è vicino a (il completo) , oppure a n 2 se il grafico è diretto con auto-loop. Quindi non vi è alcun vantaggio nell'utilizzare l'elenco di adiacenza su matrice.n(n1)/2n2

In termini di complessità dello spazio
Matrice di adiacenza: Elenco di adiacenza: O ( n + m ) dove n è il numero di nodi, m è il numero di spigoli.O(n2)
O(n+m)
nm

Quando il grafico è un albero non
orientato, allora Matrice di adiacenza: Elenco di adiacenza: O ( n + n ) è O ( n ) (migliore di n 2 )O(n2)
O(n+n)O(n)n2

Quando il grafico è diretto, completo, con auto-loop quindi
matrice di adiacenza: Elenco di adiacenza: O ( n + n 2 ) è O ( n 2 ) (nessuna differenza)O(n2)
O(n+n2)O(n2)

Infine, quando si implementa utilizzando la matrice, il controllo della presenza di uno spigolo tra due nodi richiede volte, mentre con un elenco di adiacenza, potrebbe essere necessario un tempo lineare in n .O(1)n


"mentre con un elenco di adiacenza, potrebbe essere necessario un tempo lineare" - Dato che il tuo elenco di adiacenza (probabilmente) manca di un ordine naturale, perché è un elenco anziché un set di hash?
Kevin,

1
@Kevin Quindi si chiamerebbe "hash di adiacenza" anziché "elenco". Anche possibile, perché no? Ma se fai semplicemente DFS o BFS, o qualche altra procedura che scansiona sistematicamente tutti i nodi, qual è il vantaggio dell'uso dell'hash over list? In ogni caso ispezioneresti tutti i nodi adiacenti.
fade2black,

3
Aggiungo che nel caso non ponderato non orientato , per un grafico quasi completo potrebbe essere più fattibile memorizzare il suo complemento, cioè un grafico rado. Quindi una matrice è utile quando è presente circa la metà dei bordi.
M. Winter,

3

Per rispondere fornendo una semplice analogia. Se dovessi conservare 6 once di acqua, (in generale) lo faresti con un contenitore da 5 galloni o una tazza da 8 once?

Ora, tornando alla tua domanda .. Se la maggior parte della tua matrice è vuota, perché usarla? Elenca invece ciascun valore. Tuttavia, se la tua lista è davvero lunga, perché non usare semplicemente una matrice per condensarla?

Il ragionamento dietro list vs matrix è davvero così semplice in questo caso.

PS un elenco è davvero solo una matrice a colonna singola !!! (cercando di mostrarti quanto sia arbitraria una decisione / uno scenario)


2

NEN2

Di quanti pezzi hai effettivamente bisogno, però?

NE(N2E)log2(N2E)

EN22

E=N22log2(N2E)=N2+o(N2)EN2

log2(N2E)
=log2(N2)!E!(N2E)!
=2Elog2N+O(low order terms)

log2N2E

p=EN2log2p(1p)p12

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.