¿Cuándo son las listas o matrices de adyacencia la mejor opción?

15

Me dijeron que usaríamos una lista si el gráfico es escaso y una matriz si el gráfico es denso . Para mí, es solo una definición cruda. No veo mucho más allá. ¿Puedes aclarar cuándo sería la elección natural hacer?

¡Gracias por adelantado!

usuario21312
fuente
Esa no es una definición, principalmente porque no existe una definición única de "escaso" y "denso". Además, hay otras consideraciones, por ejemplo, a qué aspectos del gráfico accede con qué frecuencia.
Raphael
@Raphael ¿Puedes entrar en más detalles sobre las otras consideraciones?
user21312
1
@ user21312, una gran diferencia es la iterabilidad frente al acceso a los bordes. Si a menudo necesita iterar sobre los bordes, entonces la lista de ajustes puede ser más útil. Si a menudo necesita determinar si existe un borde o acceder a su peso (u otra información), la matriz podría ser mejor.
Ryan
Para su propósito, probablemente podríamos descuidarnos sobre cuál es la definición de 'disperso' y 'denso'. Simplemente modele la complejidad temporal de la operación de matriz que desea usar para cada tipo de estructura de datos y vea dónde está el 'punto de ruptura de la densidad'. Creo que el segundo enlace de @ryan está tratando de hacer algo similar
Apiwat Chantawibul

Respuestas:

17

En primer lugar, tenga en cuenta que disperso significa que tiene muy pocos bordes, y denso significa muchos bordes, o un gráfico casi completo. En un gráfico completo tiene aristas, donde n es el número de nodos.n(n1)/2n

Ahora, cuando usamos representación matricial, asignamos matriz para almacenar información de conectividad de nodo, por ejemplo, M [ i ] [ j ] = 1norte×norteMETRO[yo][j]=1 si hay un borde entre los nodos y j , de lo contrario M [ i ] [ j ] = 0 . Pero si usamos la lista de adyacencia, entonces tenemos una matriz de nodos y cada nodo apunta a su lista de adyacencia que contiene SOLO sus nodos vecinos .yojMETRO[yo][j]=0 0

Ahora, si un gráfico es escaso y usamos representación matricial, la mayoría de las celdas de la matriz permanecen sin usar, lo que conduce al desperdicio de memoria. Por lo tanto, generalmente no usamos representación matricial para gráficos dispersos. Preferimos la lista de adyacencia.

Pero si el gráfico es denso, entonces el número de aristas está cerca de (el completo) , o n 2 si el gráfico está dirigido con bucles automáticos. Entonces no hay ninguna ventaja de usar la lista de adyacencia sobre la matriz.norte(norte-1)/ /2norte2

En términos de complejidad espacial
Matriz de adyacencia: Lista de adyacencia: O ( n + m ) donde n es el número de nodos, m es el número de aristas.O(norte2)
O(n+m)
nm

Cuando el gráfico es un árbol no dirigido,
matriz de adyacencia: Lista de adyacencia: OO(n2)
es O ( n ) (mejor que n 2 )O(n+n)O(n)n2

Cuando se dirige el gráfico, completo, con bucles automáticos y
matriz de adyacencia: Lista de adyacencia:O(n2)
es O ( n 2 ) (sin diferencia)O(n+n2)O(n2)

Y finalmente, cuando implementa utilizando matriz, verificar si hay un borde entre dos nodos toma veces, mientras que con una lista de adyacencia, puede tomar tiempo lineal en n .O(1)n

fade2black
fuente
"mientras que con una lista de adyacencia, puede llevar un tiempo lineal" - Dado que su lista de adyacencia (probablemente) carece de un orden natural, ¿por qué es una lista en lugar de un conjunto de hash?
Kevin
1
@Kevin Entonces se llamaría "hash de adyacencia" en lugar de "lista". También posible, ¿por qué no? Pero si simplemente hace DFS o BFS, o algún otro procedimiento que escanea sistemáticamente todos los nodos, ¿cuál es la ventaja de usar hash over list? En cualquier caso, inspeccionaría todos los nodos adyacentes.
fade2black
3
Agregaría que en el caso no ponderado no dirigido, para un gráfico casi completo , podría ser más factible almacenar su complemento, es decir, un gráfico escaso. Por lo tanto, una matriz es útil cuando aproximadamente la mitad de los bordes están presentes.
M. Winter
3

Para responder proporcionando una analogía simple. Si tuviera que almacenar 6 onzas de agua, ¿lo haría (generalmente hablando) con un recipiente de 5 galones o una taza de 8 onzas?

Ahora, volviendo a su pregunta ... Si la mayoría de su matriz está vacía, ¿por qué usarla? Simplemente enumere cada valor en su lugar. Sin embargo, si su lista es realmente larga, ¿por qué no usar una matriz para condensarla?

El razonamiento detrás de list vs matrix realmente es así de simple en este caso.

PD: ¡una lista es realmente una matriz de una sola columna! (tratando de mostrarle cuán arbitraria es una decisión / escenario)

Charles
fuente
2

Considere una gráfica con nodos y E bordes. Ignorando los términos de orden inferior, una matriz de bits para un gráfico usa N 2 bits sin importar cuántos bordes haya.NEN2

¿Cuántos bits necesitas realmente?

Suponiendo que los bordes son independientes, el número de gráficos con nodos y E bordes es ( N 2NE(N2E)log2(N2E) .

EN22 , es decir, que la mitad o menos de los bordes están presentes. Si este no es el caso, podemos almacenar el conjunto de "no bordes" en su lugar.

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

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

log2N2E identificadores de nodo , es decir, una matriz de pares de índices de nodo.

p=EN2log2p(1p). For p12, the entropy is 2 (i.e. two bits per edge in the optimal representation), and the graph is dense. If the entropy is significantly greater than 2, and in particular if it's close to the size of a pointer, the graph is sparse.

Pseudonym
fuente