Adjacency List og Matrix Repræsentation af Graph

⚡ Smart opsummering

Adjacency-lister og matrixrepræsentation af grafer gemmer hjørner og kanter i hukommelsen, hvilket giver algoritmer mulighed for at krydse netværk. Adjacency-lister bruger sammenkædede lister pr. hjørne, mens adjacency-matrixer bruger et kvadratisk todimensionelt gitter.

  • 📐 Liste over tilstødende områder: En matrix af V sammenkædede lister, hvor hver liste ved indeks i gemmer hvert hjørne ved siden af ​​hjørne i, hvilket giver O(V + E) hukommelse.
  • 🗺️ Nærliggende matrix: AV × V todimensionelt array, hvor matrix[i][j] har kantvægten eller 1, når der findes en kant mellem hjørne i og hjørne j.
  • ⚡ Opslagshastighed: Adjacency-matricen svarer på "er der en kant mellem i og j?" i O(1) tid, mens adjacency-listen har brug for O(grader) tid til at scanne nabolisten.
  • 💾 Hukommelse: Adjacensmatrixen bruger altid O(V²) hukommelse, selv for sparse grafer, hvorimod en adjacensliste skalerer med det faktiske kantantal.
  • 🔍 Bedste Fit: Vælg adjacency-matricen til tætte grafer med hyppige kantforespørgsler og adjacency-listen til sparse grafer og traversal-tunge arbejdsbelastninger.
  • 🛠️ Applikationer: Begge repræsentationer driver BFS-, DFS-, Dijkstra-, PageRank-, vejnetværksrute- og Graph Neural Network-pipelines, der bruges på tværs af AI-systemer.

Adjacency List og Matrix Repræsentation af Graph

Selvom de ser anderledes ud, alle sammen typer af grafer kan repræsenteres på en lignende måde. Der er generelt to typer grafrepræsentation:

  1. Adjacency Matrix
  2. Tilstødelsesliste

Tilstødelsesliste

En adjacensliste består af sammenkædede lister. Hvert hjørne betragtes som et arrayindeks, og hvert element repræsenterer en sammenkædet liste. Disse sammenkædede lister indeholder de hjørner, der deler en kant med indekshjørnet.

Her er et eksempel på en liste over tilstødende områder:

Tilstødelsesliste

Lad en graf indeholde V antal hjørner og E antal kanter. Rumkompleksiteten af ​​adjacenslisten er O(V + E), som skalerer med antallet af reelle kanter i stedet for alle mulige par af hjørner.

Worst-case rumkompleksitet bliver O(V²) hvis den givne graf er en komplet graf, da hvert hjørne så er forbundet med ethvert andet hjørne.

Adjacency Matrix

En adjacensmatrix er sammensat af et 2D-array. For en graf med V hjørner vil matrixens størrelse være V × V.

Sige matrix[i][j] = 5Det betyder, at der er en kant mellem knudepunkt i og knudepunkt j, hvor vægten er 5.

Lad os se på følgende graf og dens adjacensmatrix:

Adjacency Matrix

Vi byggede 2D-array ved at bruge disse trin:

Trin 1) Hjørnet A har en lige kant med B, og vægten er 5. Så cellen i række A og kolonne B vil være fyldt med 5. Resten af ​​cellerne i række A vil være fyldt med nul.

Trin 2) Hjørnet B har en lige kant med C, og vægten er 4. Så cellen i række B og kolonne C vil være fyldt med 4. De resterende celler i række B vil være fyldt med nul, da B ikke har nogen udgående kant til nogen anden node.

Trin 3) Hjørnet C har ingen direkte kanter med andre hjørner. Så række C vil være fyldt med nuller.

Trin 4) Hjørnet D har en rettet kant med A og C.

  • Cellen i række D og kolonne A vil have en værdi på 7. Cellen i række D og kolonne C vil have en værdi på 2.
  • Resten af ​​cellerne i række D vil være fyldt med nuller.

Trin 5) Hjørnet E har en rettet kant med B og D. Cellen i række E og kolonne B vil have en værdi på 6. Cellen i række E og kolonne D vil have en værdi på 3. Resten af ​​cellerne i række E vil være udfyldt med nuller.

Her er nogle punkter at bemærke:

  • Grafen har ingen selv-løkker, når den primære diagonal af adjacensmatricen er 0.
  • Grafen er en rettet graf, hvis cellerne ved (a, b) og (b, a) ikke har den samme værdi. Ellers er grafen ikke-rettet.
  • Grafen er en vægtet graf, hvis værdien af ​​en celle er større end 1.

Hovedproblemet med adjacensmatricen er, at den kræver kvadratisk plads. Selv kanter, der ikke eksisterer, allokerer stadig celler i hukommelsen.

Hvis vi for eksempel har en graf med 100 noder, skal der bruges 10,000 celler til at gemme den. RAMMed færre kanter i grafen kan allokering af så stor hukommelse være spild af tid. Så rumkompleksiteten ved brug af adjacensmatricen er O(N²), hvor N er antallet af noder i grafen.

Tilstødningsliste vs. tilstødningsmatrix

Før man vælger en repræsentation, er det en god idé at sammenligne begge modeller side om side på tværs af de operationer, der dominerer i virkelige grafbelastninger:

ProduktionAdjacency MatrixTilstødelsesliste
RumkompleksitetO(V²)O(V + E)
Tilføj et hjørneO(V²)O (1)
Tilføj en kantO (1)O (1)
Fjern en kantO (1)O(E)
Tjek om kanten (i, j) eksistererO (1)O (grad af i)
Iterer over naboer til iO (V)O (grad af i)
Bedste forTætte grafer, hyppige kantforespørgslerSparsomme grafer, traversal-tunge opgaver

Kort sagt vinder adjacency-matricen ved kantopslag i konstant tid, mens adjacency-listen vinder ved hukommelses- og nabo-iteration, hvilket er grunden til, at algoritmer som BFS, DFS og Dijkstra normalt parres med adjacency-lister.

Fordele og ulemper ved grafrepræsentation

Hver repræsentation har sine egne afvejninger. Kendskab til styrkerne og svaghederne ved begge modeller hjælper dig med at vælge den rigtige til det problem, du løser.

Fordele ved tilstødningsmatrix:

  • Konstanttids O(1) kanteksistensforespørgsler mellem et hvilket som helst par af hjørner.
  • Fast indeksering gør matrixbaserede algoritmer som Floyd-Warshall og transitiv lukning nemme at implementere.
  • Vægtede kanter passer naturligt i en enkelt matrixcelle.

Ulemper ved adjacency matrix:

  • Spilder O(V²) hukommelse, når grafen er sparsom.
  • Tilføjelse af et nyt hjørne kræver ændring af størrelsen på hele matricen.
  • Iterering over naboer til et enkelt hjørne tager O(V), selv når hjørnet kun har få kanter.

Fordele ved tilstødningsliste:

  • Bruger kun O(V + E) hukommelse, som er tæt på det reelle kantantal i sparse grafer.
  • Tilføjelse af et nyt hjørne eller en ny kant er O(1).
  • Traversalalgoritmer som BFS og DFS itererer naboer i O(grad), hvilket giver den samlede O(V + E) køretid.

Ulemper ved tilstødende liste:

  • Det tager O(grader) tid at kontrollere, om en specifik kant eksisterer, i stedet for O(1).
  • Cache-lokalitet er svagere, fordi sammenkædede lister er spredt ud over hukommelsen.
  • Vægtede kanter kræver et ledsagende felt eller en liste af par, hvilket komplicerer datastrukturen en smule.

Hvornår skal man bruge en adjacency-liste vs. en adjacency-matrix

Valget af repræsentation afhænger af grafens tæthed og de operationer, du udfører oftest. Brug denne hurtigguide til at vælge den rigtige struktur:

  • Foretrækker adjacensmatricen når grafen er tæt (E er tæt på V²), når kanterne sjældent ændrer sig, og når din algoritme spørger "er der en kant mellem i og j?" mange gange.
  • Foretrækker tilstødningslisten når grafen er sparsom (E er meget mindre end V²), når hjørne- eller kantmængden vokser under udførelse, og når du gennemløber grafen med BFS, DFS eller Dijkstras korteste-vejsalgoritme.
  • Foretrækker en blandet model (tilstødningsliste plus et hashsæt af kanter) når du har brug for både hurtig nabo-iteration og O(1) kantforespørgsler, på bekostning af ekstra hukommelse.

Moderne grafbiblioteker som NetworkX og igraph bruger som standard tilstødende lister, fordi de fleste grafer i den virkelige verden - sociale netværk, vejkort, websider, pakkeafhængigheder - er sparsomme og kræver mange gennemgange.

Ofte Stillede Spørgsmål

En adjacency-liste er et array af V linkede lister, hvor hver liste ved indeks i gemmer hvert hjørne, der støder op til hjørne i. Hukommelsesforbruget er O(V + E), hvilket passer til sparse grafer og traversal-algoritmer såsom BFS og DFS.

En adjacensmatrix er et V × V todimensionelt array, hvor matrix[i][j] har kantvægten eller 1, hvis der findes en kant mellem hjørne i og hjørne j. Kantopslag er O(1), men hukommelsen er altid O(V²).

Adjacency-matrixen besvarer kanteksistensforespørgsler i O(1). Adjacency-listen itererer naboer i O(grad), hvilket er hurtigere for traversalalgoritmer som BFS, DFS og Dijkstra. Det bedste valg afhænger af de operationer, der dominerer din arbejdsbyrde.

Brug en liste over naboer, når grafen er sparsom, når hjørner og kanter ændrer sig under udførelsen, og når algoritmen ofte krydser naboer. Sociale netværk, vejkort og websidegrafer passer alle til denne profil.

Brug en adjacensmatrix, når grafen er tæt, når hjørnesættet er fast, og når algoritmen gentagne gange forespørger den samme kant. Floyd-Warshall og transitiv lukning fungerer begge naturligt på adjacensmatricer.

Ja. For rettede grafer er matricen ikke symmetrisk, og listen gemmer kun udgående naboer. For vægtede grafer indeholder matrixcellen vægten, mens listen gemmer par af nabo og vægt.

Grafiske neurale netværk føder adjacency-matricer eller sparse edge tensorer ind i maskinlæringslag til svindeldetektion, forudsigelse af molekylegenskaber og anbefalingssystemer. Vidensgrafer er også afhængige af adjacency-liste-kodninger til hentningsforøget AI.

Ja. GitHub Copilot og ChatGPT genererer tilstødende liste og matrix-standardtekst for Python, C++og JavaUdviklere skal stadig verificere kanttilfælde såsom duplikerede kanter, selvløkker og korrekt håndtering af rettede eller vægtede grafer.

Opsummer dette indlæg med: