Wann sind Adjazenzlisten oder Matrizen die bessere Wahl?


14

Mir wurde gesagt, dass wir eine Liste verwenden würden, wenn der Graph dünn ist, und eine Matrix, wenn der Graph dicht ist . Für mich ist es nur eine grobe Definition. Ich sehe nicht viel darüber hinaus. Können Sie klarstellen, wann dies die natürliche Wahl wäre?

Danke im Voraus!



Das ist keine Definition, vor allem, weil es keine einheitliche Definition von "dünn" und "dicht" gibt. Es gibt auch andere Überlegungen, z. B. welche Aspekte des Diagramms Sie wie oft zugreifen.
Raphael

@Raphael Können Sie weitere Einzelheiten zu den anderen Überlegungen erläutern?
user21312

1
@ user21312, ein großer Unterschied ist die Iterierbarkeit gegenüber dem Zugriff auf Kanten. Wenn Sie häufig über Kanten iterieren müssen, ist die Adj-Liste möglicherweise nützlicher. Wenn Sie häufig feststellen müssen, ob eine Kante vorhanden ist, oder auf deren Gewicht (oder andere Informationen) zugreifen müssen, ist die Matrix möglicherweise besser.
Ryan

Für Ihren Zweck könnten wir wahrscheinlich sorglos darüber nachdenken, was die Definition von "spärlich" und "dicht" ist. Modellieren Sie einfach die zeitliche Komplexität der Matrixoperation, die Sie für jede Art von Datenstruktur verwenden möchten, und sehen Sie, wo sich der "Knickpunkt der Dichte" befindet. Ich denke, der zweite Link von @ryan versucht, etwas Ähnliches zu tun
Apiwat Chantawibul

Antworten:


16

Zuallererst bedeutet " dünn" , dass Sie nur sehr wenige Kanten haben, und " dicht" bedeutet "viele Kanten" oder "fast vollständiges Diagramm". In einem vollständigen Diagramm haben Sie Kanten, wobei n die Anzahl der Knoten ist.n(n1)/2n

Wenn wir nun eine Matrixdarstellung verwenden , weisen wir eine Matrix zu, um Knotenverbindungsinformationen zu speichern, z. B. M [ i ] [ j ] = 1, wenn es eine Kante zwischen den Knoten i und j gibt , andernfallsn×nM[i][j]=1ij . Wenn wir jedoch die Adjazenzliste verwenden, haben wir ein Array von Knoten, und jeder Knoten zeigt auf seine Adjazenzliste,die NUR seine Nachbarknoten enthält.M[i][j]=0

Wenn ein Graph spärlich ist und wir eine Matrixdarstellung verwenden, bleiben die meisten Matrixzellen ungenutzt, was zur Verschwendung von Speicher führt. Daher verwenden wir normalerweise keine Matrixdarstellung für spärliche Diagramme. Wir bevorzugen die Nachbarschaftsliste.

Wenn der Graph jedoch dicht ist, liegt die Anzahl der Kanten nahe an (dem vollständigen) oder nahe an n 2, wenn der Graph mit Selbstschleifen ausgerichtet ist. In diesem Fall bietet die Verwendung der Adjazenzliste keinen Vorteil gegenüber der Matrix.n(n1)/2n2

In Bezug auf die Raumkomplexität
Adjazenzmatrix: Adjazenzliste: O ( n + m ) wobei n die Anzahl der Knoten und m die Anzahl der Kanten ist.O(n2)
O(n+m)
nm

Wenn der Graph ein ungerichteter Baum ist, dann
Adjazenzmatrix: Adjazenzliste: O ( n + n ) ist O ( n ) (besser als n 2 )O(n2)
O(n+n)O(n)n2

Wenn der Graph gerichtet ist, vollständig mit Selbstschleifen, dann
Adjazenzmatrix: Adjazenzliste: O ( n + n 2 ) ist O ( n 2 ) (kein Unterschied)O(n2)
O(n+n2)O(n2)

Wenn Sie schließlich die Verwendung einer Matrix implementieren, dauert die Überprüfung, ob eine Kante zwischen zwei Knoten vorhanden ist, Mal, während es bei einer Adjazenzliste in n möglicherweise eine lineare Zeit dauert .O(1)n


"Während bei einer Adjazenzliste möglicherweise eine lineare Zeit verstrichen ist" - Wenn Ihre Adjazenzliste (wahrscheinlich) keine natürliche Reihenfolge aufweist, warum handelt es sich dann um eine Liste anstelle eines Hash-Satzes?
Kevin

1
@ Kevin Dann würde es "Adjazenz-Hash" anstelle von "Liste" heißen. Auch möglich, warum nicht? Aber wenn Sie einfach DFS oder BFS oder eine andere Prozedur ausführen, die systematisch alle Knoten durchsucht, was ist dann der Vorteil der Verwendung von Hash-über-Liste? In jedem Fall würden Sie alle benachbarten Knoten untersuchen.
Fade2Black

3
Ich würde hinzufügen, dass es im ungewichteten ungerichteten Fall für ein fast vollständiges Diagramm praktikabler sein könnte, sein Komplement, dh ein spärliches Diagramm, zu speichern. Eine Matrix ist also nützlich, wenn ungefähr die Hälfte der Kanten vorhanden ist.
M. Winter

3

Um mit einer einfachen Analogie zu antworten: Wenn Sie 6 Unzen Wasser aufbewahren müssten, würden Sie dies (im Allgemeinen) mit einem 5-Gallonen-Behälter oder einer 8-Unzen-Tasse tun?

Kommen wir nun zu Ihrer Frage zurück. Wenn der Großteil Ihrer Matrix leer ist, warum sollten Sie sie dann verwenden? Listen Sie stattdessen jeden Wert auf. Wenn Ihre Liste jedoch sehr lang ist, warum nicht einfach eine Matrix verwenden, um sie zu verdichten?

Die Argumentation hinter list vs matrix ist in diesem Fall wirklich so einfach.

PS eine Liste ist wirklich nur eine einzelne Spaltenmatrix !!! (Ich versuche dir zu zeigen, wie willkürlich eine Entscheidung / ein Szenario ist)


2

Betrachten Sie einen Graphen mit Knoten und E Kanten. Ohne Berücksichtigung von Termen niedriger Ordnung verwendet eine Bitmatrix für einen Graphen N 2 Bits, unabhängig von der Anzahl der Kanten.NEN2

Wie viele Bits brauchst du eigentlich?

Unter der Annahme, dass Kanten unabhängig sind, beträgt die Anzahl der Graphen mit Knoten und E Kanten ( N 2NE . Die minimale Anzahl von Bits, die erforderlich sind, um diese Teilmenge zu speichern, istlog2 ( N2(N2E) .log2(N2E)

Wir gehen ohne Einschränkung der Allgemeinheit davon aus, dass , das heißt, dass die Hälfte oder weniger der Kanten vorhanden sind. Ist dies nicht der Fall, können wir stattdessen die Menge der "Nichtkanten" speichern.EN22

Wenn ,log2 ( N 2E=N22log2(N2E)=N2+o(N2), so the matrix representation is asymptotically optimal. If EN2, using Stirling's approximation and a little arithmetic, we find:

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

If you consider that log2N is the size of an integer which can represent a node index, the optimal representation is an array of 2E node ids, that is, an array of pairs of node indexes.

Having said that, a good measure of sparsity is the entropy, which is also the number of bits per edge of the optimal representation. If p=EN2 is the probability that an edge is present, the entropy is log2p(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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.