Kiedy listy lub macierze sąsiedztwa są lepszym wyborem?


15

Powiedziano mi, że użyjemy listy, jeśli wykres jest rzadki, a macierzy, jeśli wykres jest gęsty . Dla mnie to tylko surowa definicja. Nie widzę wiele poza tym. Czy możesz wyjaśnić, kiedy byłby to naturalny wybór?

Z góry dziękuję!



To nie jest definicja, głównie dlatego, że nie ma jednej definicji „rzadkich” i „gęstych”. Istnieją również inne uwagi, np. Do których aspektów wykresu można uzyskać dostęp, jak często.
Raphael

@Raphael Czy możesz uzyskać więcej informacji na temat innych rozważań?
user21312,

1
@ user21312, dużą różnicą jest iteracyjność vs dostęp do krawędzi. Jeśli często trzeba wykonywać iteracje po krawędziach, lista przylegania może być bardziej przydatna. Jeśli często musisz ustalić, czy krawędź istnieje lub uzyskać dostęp do jej ciężaru (lub innych informacji), macierz może być lepsza.
ryan

W twoim przypadku prawdopodobnie moglibyśmy nieostrożnie myśleć o definicji „rzadkich” i „gęstych”. Po prostu modeluj złożoność czasową operacji macierzy, której chcesz użyć dla każdego typu struktury danych, i zobacz, gdzie jest „punkt przerwania gęstości”. Myślę, że drugi link @ryan próbuje zrobić coś podobnego
Apiwat Chantawibul

Odpowiedzi:


17

Przede wszystkim zauważ, że rzadki oznacza, że ​​masz bardzo mało krawędzi, a gęsty oznacza wiele krawędzi lub prawie pełny wykres. Na pełnym wykresie masz krawędzi, gdzie jest liczbą węzłów.nn(n1)/2n

Teraz, gdy używamy reprezentacji macierzowej, alokujemy macierzy do przechowywania informacji o połączeniach węzłów, np. jeśli istnieje krawędź między węzłami i , w przeciwnym razie . Ale jeśli użyjemy listy przyległości, mamy tablicę węzłów i każdy węzeł wskazuje na swoją listę przyległości zawierającą TYLKO sąsiednie węzły .M [ i ] [ j ] = 1 i j M [ i ] [ j ] = 0n×nM[i][j]=1ijM[i][j]=0

Teraz, jeśli wykres jest rzadki i korzystamy z reprezentacji macierzy, wówczas większość komórek macierzy pozostaje nieużywana, co prowadzi do marnowania pamięci. Dlatego zwykle nie używamy reprezentacji macierzowej dla rzadkich wykresów. Wolimy listę sąsiadów.

Ale jeśli wykres jest gęsty, liczba krawędzi jest zbliżona do (pełnego) lub do jeśli wykres jest skierowany za pomocą pętli własnych. Wówczas nie ma przewagi, aby używać listy sąsiedztwa nad macierzą.n 2n(n1)/2n2

Pod względem złożoności przestrzeni
Macierz adiakencji: Lista adjacencji: gdzie jest liczbą węzłów, jest liczbą krawędzi.O ( n + m ) n mO(n2)
O(n+m)
nm

Gdy wykres jest drzewem bezkierunkowym, wówczas
macierz adiakencji: Lista adjacencji: to (lepiej niż )O ( n + n ) O ( n ) n 2O(n2)
O(n+n)O(n)n2

Gdy wykres jest skierowany, kompletny, z pętlami własnymi, to
macierz adiakencji: Lista adjacencji: to (bez różnicy)O ( n + n 2 ) O ( n 2 )O(n2)
O(n+n2)O(n2)

I na koniec, kiedy implementujesz za pomocą macierzy, sprawdzenie, czy istnieje krawędź między dwoma węzłami, zajmuje razy, natomiast w przypadku listy przyległości może zająć czas liniowy w .nO(1)n


„chociaż lista przylegania może zająć trochę czasu” - biorąc pod uwagę, że lista przylegania (prawdopodobnie) nie ma żadnego naturalnego porządku, dlaczego jest to lista zamiast zestawu skrótów?
Kevin

1
@Kevin Wtedy nazwano by to „hash sąsiedztwa” zamiast „list”. Możliwe też, dlaczego nie? Ale jeśli po prostu wykonujesz DFS lub BFS lub jakąś inną procedurę, która skanuje systematycznie wszystkie węzły, to jaka jest zaleta używania skrótu nad listą? W każdym razie sprawdziłbyś wszystkie sąsiednie węzły.
fade2black

3
Dodałbym, że w przypadku nieważonego, niekierowanego przypadku, dla prawie pełnego wykresu bardziej prawdopodobne może być przechowywanie jego dopełnienia, tj. Rzadkiego wykresu. Tak więc matryca jest przydatna, gdy obecna jest w przybliżeniu połowa krawędzi.
M. Winter

3

Aby odpowiedzieć, podając prostą analogię. Gdybyś musiał przechowywać 6 uncji wody, czy (ogólnie rzecz biorąc) zrobiłbyś to z pojemnikiem o pojemności 5 galonów lub kubkiem o pojemności 8 uncji?

Wracając do pytania… Jeśli większość macierzy jest pusta, to po co z niej korzystać? Zamiast tego wystarczy wymienić każdą wartość. Jeśli jednak twoja lista jest naprawdę długa, dlaczego nie użyć matrycy, aby ją skondensować?

W tym przypadku uzasadnienie listy vs macierzy jest naprawdę takie proste.

PS lista to tak naprawdę tylko macierz jednokolumnowa !!! (próbuje pokazać, jak arbitralna jest decyzja / scenariusz)


2

Rozważ wykres z węzłami i krawędziamiIgnorując warunki niskiego rzędu, matryca bitowa dla wykresu używa bitów bez względu na liczbę krawędzi.E N 2NEN2

Ile bitów tak naprawdę potrzebujesz?

Zakładając, że krawędzie są niezależne, liczba wykresów z węzłami i krawędziami wynosi . Minimalna liczba bitów wymagana do przechowywania tego podzbioru wynosi .E ( N 2NE(N2E)log2(N2E)

Przyjmiemy bez utraty ogólności, że , to znaczy, że połowa lub mniej krawędzi jest obecnych. Jeśli tak nie jest, możemy zamiast tego zapisać zestaw „bez krawędzi”.EN22

Jeśli , , więc reprezentacja macierzy jest asymptotycznie optymalna. Jeśli , stosując przybliżenie Stirlinga i trochę arytmetyki, znajdziemy:E=N22log2(N2E)=N2+o(N2)EN2

log2(N2E)
=2Elog2N+O(warunkiniskiego rzędu)
=log2(N2)!E!(N2E)!
=2Elog2N+O(low order terms)

Jeśli weźmiesz pod uwagę, że jest rozmiarem liczby całkowitej, która może reprezentować indeks węzła, optymalną reprezentacją jest tablica identyfikatorów węzłów , czyli tablica par indeksów węzłów.2 Elog2N2E

To powiedziawszy, dobrą miarą rzadkości jest entropia, która jest również liczbą bitów na krawędź optymalnej reprezentacji. Jeśli jest prawdopodobieństwem obecności krawędzi, entropia to . Dla entropia wynosi 2 (tj. Dwa bity na krawędź w optymalnej reprezentacji), a wykres jest gęsty. Jeśli entropia jest znacznie większa niż 2, a zwłaszcza jeśli jest zbliżona do wielkości wskaźnika, wykres jest rzadki. -log2p(1-p)p1p=EN2log2p(1p)p12

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.