Aangrenzende lijst en matrixweergave van grafiek

⚡ Slimme samenvatting

Een aangrenzingslijst en een aangrenzingsmatrix representeren een graaf door knooppunten en verbindingen in het geheugen op te slaan, waardoor algoritmen netwerken kunnen doorlopen. Een aangrenzingslijst gebruikt gekoppelde lijsten per knooppunt, terwijl een aangrenzingsmatrix een vierkant tweedimensionaal raster gebruikt.

  • 📐 Aangrenzende lijst: Een array van V gekoppelde lijsten, waarbij elke lijst op index i alle aangrenzende knooppunten van knooppunt i opslaat, wat O(V + E) geheugen vereist.
  • 🗺️ Aangrenzingsmatrix: Een AV × V tweedimensionale matrix waarin matrix[i][j] het gewicht van de rand bevat, of 1 wanneer er een rand bestaat tussen knooppunt i en knooppunt j.
  • Zoeksnelheid: Een adjacentiematrix beantwoordt de vraag "bestaat er een verbinding tussen i en j?" in O(1) tijd, terwijl een adjacentielijst O(graad) tijd nodig heeft om de buurlijst te doorlopen.
  • 💾 Geheugen: Een adjacentiematrix verbruikt altijd O(V²) geheugen, zelfs voor dunne grafieken, terwijl een adjacentielijst schaalt met het werkelijke aantal randen.
  • 🔍 Beste pasvorm: Kies de adjacentiematrix voor dichte grafieken met frequente randquery's en de adjacentielijst voor dunne grafieken en workloads die veel doorloop vereisen.
  • toepassingen: Beide representaties vormen de basis voor BFS, DFS, Dijkstra, PageRank, routeplanning voor wegennetwerken en grafische neurale netwerken die in diverse AI-systemen worden gebruikt.

Aangrenzende lijst en matrixweergave van grafiek

Ook al zien ze er allemaal anders uit soorten grafieken kan op een vergelijkbare manier worden weergegeven. Er zijn over het algemeen twee soorten grafische weergaven:

  1. Nabijheid Matrix
  2. Nabijheidslijst

Nabijheidslijst

Een aangrenzingslijst bestaat uit gekoppelde lijsten. Elk knooppunt wordt beschouwd als een array-index en elk element vertegenwoordigt een gekoppelde lijst. Deze gekoppelde lijsten bevatten de knooppunten die een gemeenschappelijke rand delen met het indexknooppunt.

Hier volgt een voorbeeld van een aangrenzingslijst:

Nabijheidslijst

Stel dat een graaf V knooppunten en E randen bevat. De ruimtecomplexiteit van de aangrenzingslijst is O(V + E), wat schaalt met het aantal werkelijke randen in plaats van elk mogelijk paar hoekpunten.

De ruimtecomplexiteit in het slechtste geval wordt O(V²) Als de gegeven graaf een complete graaf is, omdat elk knooppunt dan met elk ander knooppunt verbonden is.

Nabijheid Matrix

Een adjacentiematrix bestaat uit een tweedimensionale array. Voor een graaf met V knooppunten zal de grootte van de matrix zijn: V × V.

Zeg matrix[i][j] = 5Dit betekent dat er een verbinding is tussen knooppunt i en knooppunt j met een gewicht van 5.

Laten we de volgende graaf en de bijbehorende adjacentiematrix eens bekijken:

Nabijheid Matrix

We hebben de 2D-reeks met behulp van deze stappen:

Stap 1) Knooppunt A heeft een directe verbinding met B, en het gewicht is 5. Dus de cel in rij A en kolom B wordt gevuld met 5. De overige cellen in rij A worden gevuld met nullen.

Stap 2) Knooppunt B heeft een directe verbinding met C, en het gewicht is 4. De cel in rij B en kolom C wordt dus gevuld met 4. De overige cellen in rij B worden gevuld met nullen, omdat B geen uitgaande verbinding heeft met een ander knooppunt.

Stap 3) Hoekpunt C heeft geen directe verbindingen met andere hoekpunten. Rij C zal dus gevuld worden met nullen.

Stap 4) Hoekpunt D heeft een gerichte verbinding met A en C.

  • De cel in rij D en kolom A zal de waarde 7 hebben. De cel in rij D en kolom C zal de waarde 2 hebben.
  • De rest van de cellen in rij D worden gevuld met nullen.

Stap 5) Hoekpunt E heeft een gerichte verbinding met B en D. De cel in rij E en kolom B krijgt de waarde 6. De cel in rij E en kolom D krijgt de waarde 3. De overige cellen in rij E worden gevuld met nullen.

Hier zijn enkele aandachtspunten:

  • De graaf bevat geen zelflussen wanneer de primaire diagonaal van de adjacentiematrix 0 is.
  • Een graaf is een gerichte graaf als de cellen op de posities (a, b) en (b, a) niet dezelfde waarde hebben. Anders is de graaf ongericht.
  • Een grafiek is een gewogen grafiek als de waarde in een willekeurige cel groter is dan 1.

Het grootste probleem met de adjacentiematrix is ​​dat deze vierkante geheugenruimte vereist. Zelfs randen die niet bestaan, nemen geheugencellen in beslag.

Als we bijvoorbeeld een grafiek hebben met 100 knooppunten, dan zijn er 10,000 cellen nodig om deze op te slaan. RAMMet minder randen in de graaf kan het toewijzen van zo'n groot geheugen verspilling zijn. De ruimtecomplexiteit bij gebruik van de adjacentiematrix is ​​daarom... O(N²), waarbij N het aantal knooppunten in de graaf is.

Aangrenzingslijst versus aangrenzingsmatrix

Voordat je een representatie kiest, is het nuttig om beide modellen naast elkaar te vergelijken aan de hand van de bewerkingen die in de praktijk vaak voorkomen bij grafiekworkloads:

WerkingNabijheid MatrixNabijheidslijst
RuimtecomplexiteitO(V²)O(V + E)
Voeg een hoekpunt toeO(V²)O (1)
Voeg een rand toeO (1)O (1)
Verwijder een randO (1)O(E)
Controleer of de verbinding (i, j) bestaat.O (1)O(graad van i)
Doorloop de buren van i.O (V)O(graad van i)
Best voorDichte grafieken, frequente randquery'sDunne grafieken, taken die veel doorloop vereisen

Kortom, een adjacentiematrix is ​​beter in het vinden van randen in constante tijd, terwijl een adjacentielijst beter presteert op het gebied van geheugen en het aantal iteraties naar buren. Daarom worden algoritmen zoals BFS, DFS en Dijkstra meestal gecombineerd met adjacentielijsten.

Voordelen en nadelen van grafische weergave

Elke weergave kent zijn eigen voor- en nadelen. Door de sterke en zwakke punten van beide modellen te kennen, kun je het juiste model kiezen voor het probleem dat je probeert op te lossen.

Voordelen van de aangrenzingsmatrix:

  • Constante-tijd O(1) zoekopdrachten naar het bestaan ​​van randen tussen elk willekeurig paar knooppunten.
  • Vaste indexering maakt matrixgebaseerde algoritmen zoals Floyd-Warshall en transitieve sluiting eenvoudig te implementeren.
  • Gewogen randen passen van nature in één matrixcel.

Nadelen van de aangrenzingsmatrix:

  • Verspilt O(V²) geheugen wanneer de grafiek dunbevolkt is.
  • Het toevoegen van een nieuw hoekpunt vereist dat de gehele matrix wordt aangepast.
  • Het doorlopen van de buren van een enkel knooppunt kost O(V), zelfs als het knooppunt maar een paar randen heeft.

Voordelen van een aangrenzingslijst:

  • Gebruikt slechts O(V + E) geheugen, wat dicht in de buurt komt van het werkelijke aantal randen in dunne grafieken.
  • Het toevoegen van een nieuw knooppunt of een nieuwe rand is O(1).
  • Doorloopalgoritmen zoals BFS en DFS doorlopen buren in O(graad), wat resulteert in een totale looptijd van O(V + E).

Nadelen van een aangrenzingslijst:

  • Controleren of een specifieke rand bestaat, kost O(graad) tijd in plaats van O(1).
  • De cachelocaliteit is zwakker omdat gekoppelde lijsten verspreid over het geheugen staan.
  • Gewogen randen vereisen een begeleidend veld of een lijst met paren, wat de datastructuur enigszins compliceert.

Wanneer gebruik je een aangrenzingslijst versus een aangrenzingsmatrix?

De keuze van de representatie hangt af van de dichtheid van de grafiek en de bewerkingen die u het vaakst uitvoert. Gebruik deze korte handleiding om de juiste structuur te kiezen:

  • Geef de voorkeur aan de aangrenzingsmatrix. wanneer de graaf dicht is (E ligt dicht bij V²), wanneer randen zelden veranderen en wanneer je algoritme vaak de vraag stelt: "Is er een rand tussen i en j?".
  • Geef de voorkeur aan de aangrenzingslijst. wanneer de graaf dunbevolkt is (E is veel kleiner dan V²), wanneer de verzameling knooppunten of randen groeit tijdens de uitvoering, en wanneer je de graaf doorloopt met BFS, DFS of Dijkstra's kortste-pad-algoritme.
  • Geef de voorkeur aan een gemengd model. (aangrenzingslijst plus een hashset van randen) wanneer je zowel snelle buuriteratie als O(1) randquery's nodig hebt, ten koste van extra geheugen.

Moderne grafiekbibliotheken zoals NetworkX en igraph gebruiken standaard aangrenzingslijsten, omdat de meeste grafieken in de praktijk — sociale netwerken, wegenkaarten, webpagina's, pakketafhankelijkheden — dunbevolkt zijn en veel doorloopbewerkingen vereisen.

Veelgestelde vragen

Een aangrenzingslijst is een array van V gekoppelde lijsten, waarbij elke lijst op index i alle aangrenzende knooppunten van knooppunt i bevat. Het geheugenverbruik is O(V + E), wat geschikt is voor dunne grafieken en traverseringsalgoritmen zoals BFS en DFS.

Een adjacentiematrix is ​​een tweedimensionale V × V-matrix waarin matrix[i][j] het gewicht van de rand bevat, of 1 als er een rand bestaat tussen knooppunt i en knooppunt j. Het opzoeken van randen is O(1), maar het geheugengebruik is altijd O(V²).

Een adjacentiematrix beantwoordt vragen over het bestaan ​​van randen in O(1). Een adjacentielijst doorloopt buren in O(graad), wat sneller is voor traverseringsalgoritmen zoals BFS, DFS en Dijkstra. De beste keuze hangt af van de bewerkingen die het meest voorkomen in uw werklast.

Gebruik een aangrenzingslijst wanneer de graaf dunbevolkt is, wanneer knooppunten en randen tijdens de uitvoering veranderen en wanneer het algoritme vaak buren passeert. Sociale netwerken, wegenkaarten en webpagina-grafieken voldoen allemaal aan dit profiel.

Gebruik een adjacentiematrix wanneer de graaf dicht is, de verzameling knooppunten vastligt en het algoritme herhaaldelijk dezelfde kant opvraagt. Zowel Floyd-Warshall als transitieve sluiting werken van nature met adjacentiematrices.

Ja. Voor gerichte grafen is de matrix niet symmetrisch en slaat de lijst alleen uitgaande buren op. Voor gewogen grafen bevat de matrixcel het gewicht, terwijl de lijst paren van buren en gewicht opslaat.

Grafische neurale netwerken gebruiken adjacentiematrices of schaarse randtensoren als input voor machine learning-lagen voor fraudedetectie, voorspelling van molecuuleigenschappen en aanbevelingssystemen. Kennisgrafieken maken ook gebruik van adjacentielijstcoderingen voor AI die is geoptimaliseerd voor het ophalen van informatie.

Ja. GitHub Copilot en ChatGPT genereren standaard aangrenzingslijsten en matrices voor Python, C++en JavaOntwikkelaars moeten nog steeds randgevallen controleren, zoals dubbele verbindingen, zelflussen en de correcte afhandeling van gerichte of gewogen grafieken.

Vat dit bericht samen met: