Quando as listas ou matrizes de adjacência são a melhor escolha?

15

Disseram-me que usaríamos uma lista se o gráfico for escasso e uma matriz se o gráfico for denso . Para mim, é apenas uma definição bruta. Não vejo muito além disso. Você pode esclarecer quando seria a escolha natural a fazer?

Desde já, obrigado!

user21312
fonte
Essa não é uma definição, principalmente porque não existe uma definição única de "esparsa" e "densa". Além disso, existem outras considerações, por exemplo, quais aspectos do gráfico você acessa com que frequência.
Raphael
@Raphael Você pode entrar em mais detalhes sobre as outras considerações?
user21312
1
@ user21312, uma grande diferença é a iterabilidade versus o acesso às arestas. Se você muitas vezes precisar percorrer as arestas, a lista de adj pode ser mais útil. Se você frequentemente precisa determinar se existe uma aresta ou acessar seu peso (ou outras informações), a matriz pode ser melhor.
Ryan
Para seu propósito, provavelmente poderíamos descuidar do que é a definição de 'esparso' e 'denso'. Apenas modele a complexidade de tempo da operação da matriz que você deseja usar para cada tipo de estrutura de dados e veja onde está o 'ponto de ruptura da densidade'. Eu acho que a segunda ligação por @ Ryan está tentando fazer algo semelhante
apiwat Chantawibul

Respostas:

16

Antes de tudo, observe que esparso significa que você tem muito poucas arestas e denso significa muitas arestas, ou gráfico quase completo. Em um gráfico completo, você tem arestas, em que n é o número de nós.n(n1)/2n

Agora, quando usamos representação matricial que alocar matriz de armazenamento de informações nó-conectividade, por exemplo, M [ i ] [ j ] = 1 se houver borda entre os nós i e j , caso contrário, M [ i ] [ j ] = 0 . Mas se usarmos a lista de adjacência, teremos uma matriz de nós e cada nó apontará para sua lista de adjacência contendo SOMENTE os nós vizinhos .n×nM[i][j]=1ijM[i][j]=0

Agora, se um gráfico é escasso e usamos a representação matricial, a maioria das células da matriz permanece sem uso, o que leva ao desperdício de memória. Portanto, geralmente não usamos representação matricial para gráficos esparsos. Preferimos lista de adjacência.

Mas se o gráfico é densa, em seguida, o número de arestas é perto de (a completa) , ou para n 2 , se o gráfico está dirigida com auto-loops. Então não há vantagem em usar a lista de adjacência sobre a matriz.n(n1)/2n2

Em termos de complexidade do espaço
Matriz de adjacência: Lista de adjacências: O ( n + m ) onde n é o número de nós, m é o número de arestas.O(n2)
O(n+m)
nm

Quando o gráfico é uma árvore não direcionada,
matriz de adjacência: Lista de adjacências: O ( n + n ) é O ( n ) (melhor que n 2 )O(n2)
O(n+n)O(n)n2

Quando o gráfico é direcionado, completo, com auto-loops,
matriz de adjacência: Lista de adjacências: O ( n + n 2 ) é O ( n 2 ) (sem diferença)O(n2)
O(n+n2)O(n2)

E, finalmente, quando você implementa usando matriz, verificar se existe uma aresta entre dois nós leva vezes, enquanto que com uma lista de adjacências, pode levar tempo linear em n .O(1)n

fade2black
fonte
"enquanto estiver com uma lista de adjacências, pode levar um tempo linear" - Como sua lista de adjacências (provavelmente) não possui ordem natural, por que é uma lista em vez de um conjunto de hash?
26417 Kevin
1
@ Kevin Em seguida, seria chamado "hash adjacência" em vez de "lista". Também é possível, por que não? Mas se você simplesmente faz DFS ou BFS, ou algum outro procedimento que varre sistematicamente todos os nós, qual é a vantagem de usar hash over list? De qualquer forma, você inspecionaria todos os nós adjacentes.
Fade2black
3
Eu acrescentaria que, no caso não direcionado não ponderado, para um gráfico quase completo , pode ser mais viável armazenar seu complemento, ou seja, um gráfico esparso. Portanto, uma matriz é útil quando aproximadamente metade das bordas estão presentes.
M. Winter
3

Para responder, fornecendo uma analogia simples. Se você tivesse que armazenar 6 onças de água, você (em geral) faria isso com um contêiner de 5 galões ou um copo de 8 onças?

Agora, voltando à sua pergunta. Se a maioria da sua matriz está vazia, por que usá-la? Apenas liste cada valor. No entanto, se sua lista é realmente longa, por que não usar apenas uma matriz para condensá-la?

O raciocínio por trás da lista versus matriz é realmente simples neste caso.

PS uma lista é realmente apenas uma matriz de coluna única !!! (tentando mostrar o quão arbitrária é uma decisão / cenário)

Charles
fonte
2

Considere um gráfico com nós e arestas E. Ignorando termos de ordem inferior, uma matriz de bits para um gráfico usa N 2 bits, não importando quantas arestas existem.NEN2

Quantos bits você realmente precisa?

Supondo que as arestas sejam independentes, o número de gráficos com nós e E arestas é ( N 2NE . O número mínimo de bits necessário para armazenar este subconjunto élog2(N2E)log2(N2E)

Assumiremos sem perda de generalidade que EN22

Se ,log2 (E=N22, portanto a representação da matriz é assintoticamente ideal. SeElog2(N2E)=N2+o(N2)EN2

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

log2N2E

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
fonte