Liste de contiguïté et représentation matricielle du graphique

⚡ Résumé intelligent

Les listes d'adjacence et les matrices d'adjacence permettent de stocker les sommets et les arêtes en mémoire, ce qui permet aux algorithmes de parcourir les réseaux. Une liste d'adjacence utilise une liste chaînée par sommet, tandis qu'une matrice d'adjacence utilise une grille carrée bidimensionnelle.

  • (I.e. Liste d'adjacence : Un tableau de V listes chaînées où chaque liste à l'index i stocke chaque sommet adjacent au sommet i, donnant O(V + E) mémoire.
  • ️ Matrice d'adjacence : Tableau bidimensionnel AV × V où matrix[i][j] contient le poids de l'arête ou 1 lorsqu'une arête existe entre le sommet i et le sommet j.
  • | Vitesse de recherche : La matrice d'adjacence répond à la question « existe-t-il une arête entre i et j ? » en temps O(1), tandis que la liste d'adjacence nécessite un temps O(degré) pour parcourir la liste des voisins.
  • (I.e. Mémoire: La matrice d'adjacence consomme toujours O(V²) de mémoire, même pour les graphes clairsemés, tandis qu'une liste d'adjacence s'adapte au nombre réel d'arêtes.
  • 🔍 Meilleur ajustement : Choisissez la matrice d'adjacence pour les graphes denses avec des requêtes d'arêtes fréquentes et la liste d'adjacence pour les graphes clairsemés et les charges de travail nécessitant de nombreux parcours.
  • ️ Applications : Ces deux représentations alimentent les pipelines BFS, DFS, Dijkstra, PageRank, le routage sur réseau routier et les réseaux neuronaux graphiques utilisés dans les systèmes d'IA.

Liste de contiguïté et représentation matricielle du graphique

Même s'ils semblent différents, tous types de graphiques peut être représenté de manière similaire. Il existe généralement deux types de représentation graphique :

  1. Matrice d'adjacence
  2. Liste de contiguïté

Liste de contiguïté

Une liste d'adjacence est composée de listes chaînées. Chaque sommet est considéré comme un indice de tableau, et chaque élément représente une liste chaînée. Ces listes chaînées contiennent les sommets qui partagent une arête avec le sommet d'indice.

Voici un exemple de liste d'adjacence :

Liste de contiguïté

Soit un graphe comportant V sommets et E arêtes. La complexité spatiale de la liste d'adjacence est O(V + E), qui évolue en fonction du nombre d'arêtes réelles plutôt que de chaque paire de sommets possibles.

La complexité spatiale dans le pire des cas devient O(V²) si le graphe donné est un graphe complet, puisque chaque sommet est alors connecté à tous les autres sommets.

Matrice d'adjacence

Une matrice d'adjacence est composée d'un tableau 2D. Pour un graphe à V sommets, la taille de la matrice sera de V × V.

nos élèves matrix[i][j] = 5Cela signifie qu'il existe une arête entre le nœud i et le nœud j dont le poids est de 5.

Examinons le graphe suivant et sa matrice d'adjacence :

Matrice d'adjacence

Nous avons construit le tableau 2D en utilisant ces étapes :

Étape 1) Le sommet A est directement relié à B par une arête de poids 5. Par conséquent, la case située à l'intersection de la ligne A et de la colonne B sera remplie avec la valeur 5. Les autres cases de la ligne A seront remplies avec la valeur 0.

Étape 2) Le sommet B possède une arête directe avec C, et le poids de cette arête est de 4. Par conséquent, la cellule située à l'intersection de la ligne B et de la colonne C sera remplie avec la valeur 4. Les cellules restantes de la ligne B seront remplies avec la valeur zéro, puisque B ne possède aucune arête sortante vers un autre nœud.

Étape 3) Le sommet C n'est relié directement à aucun autre sommet. Par conséquent, la ligne C sera remplie de zéros.

Étape 4) Le sommet D possède une arête orientée avec A et C.

  • La cellule située à l'intersection de la ligne D et de la colonne A aura la valeur 7. La cellule située à l'intersection de la ligne D et de la colonne C aura la valeur 2.
  • Le reste des cellules de la ligne D sera rempli de zéros.

Étape 5) Le sommet E est relié par une arête orientée à B et D. La cellule située à l'intersection de la ligne E et de la colonne B aura la valeur 6. La cellule située à l'intersection de la ligne E et de la colonne D aura la valeur 3. Les autres cellules de la ligne E seront remplies de zéros.

Voici quelques points à noter :

  • Le graphe ne comporte pas de boucles lorsque la diagonale principale de la matrice d'adjacence est égale à 0.
  • Un graphe est orienté si les cellules aux coordonnées (a, b) et (b, a) ne contiennent pas la même valeur. Sinon, il est non orienté.
  • Le graphique est un graphique pondéré si la valeur de n'importe quelle cellule est supérieure à 1.

Le principal problème de la matrice d'adjacence est qu'elle nécessite un espace mémoire au carré. Même les arêtes inexistantes occupent des cellules en mémoire.

Par exemple, si nous avons un graphe avec 100 nœuds, alors 10 000 cellules sont nécessaires pour le stocker. RAMAvec un nombre réduit d'arêtes dans le graphe, allouer une mémoire aussi importante peut s'avérer inutile. La complexité spatiale, calculée à l'aide de la matrice d'adjacence, est donc de : O(N²), où N est le nombre de nœuds dans le graphe.

Liste d'adjacence vs matrice d'adjacence

Avant de choisir une représentation, il est utile de comparer les deux modèles côte à côte sur les opérations qui dominent les charges de travail graphiques réelles :

OpérationMatrice d'adjacenceListe de contiguïté
Complexité spatialeO(V²)O(V + E)
Ajouter un sommetO(V²)O (1)
Ajouter un bordO (1)O (1)
Enlever un bordO (1)O(E)
Vérifier si l'arête (i, j) existeO (1)O(degré de i)
Parcourir les voisins de iO (V)O(degré de i)
Meilleur pourGraphes denses, requêtes fréquentes sur les arêtesGraphes clairsemés, tâches nécessitant de nombreux parcours

En résumé, la matrice d'adjacence l'emporte sur les recherches d'arêtes en temps constant, tandis que la liste d'adjacence l'emporte sur la mémoire et l'itération des voisins, ce qui explique pourquoi des algorithmes tels que BFS, DFS et Dijkstra sont généralement associés à des listes d'adjacence.

Avantages et inconvénients de la représentation graphique

Chaque représentation présente ses propres avantages et inconvénients. Connaître les forces et les faiblesses des deux modèles vous aide à choisir celui qui convient le mieux au problème que vous cherchez à résoudre.

Avantages de la matrice d'adjacence :

  • Requêtes d'existence d'arêtes en temps constant O(1) entre n'importe quelle paire de sommets.
  • L'indexation fixe facilite la mise en œuvre d'algorithmes matriciels tels que Floyd-Warshall et la fermeture transitive.
  • Les bords pondérés s'intègrent naturellement dans une seule cellule de la matrice.

Inconvénients de la matrice d'adjacence :

  • Gaspille O(V²) de mémoire lorsque le graphe est clairsemé.
  • L'ajout d'un nouveau sommet nécessite le redimensionnement de la matrice entière.
  • L'itération sur les voisins d'un seul sommet prend O(V) même lorsque le sommet n'a que quelques arêtes.

Avantages de la liste d'adjacence :

  • Utilise seulement O(V + E) mémoire, ce qui est proche du nombre réel d'arêtes dans les graphes creux.
  • L'ajout d'un nouveau sommet ou d'une nouvelle arête est O(1).
  • Les algorithmes de parcours tels que BFS et DFS itèrent les voisins en O(degré), donnant un temps d'exécution global de O(V + E).

Inconvénients de la liste d'adjacence :

  • Vérifier si une arête spécifique existe prend un temps O(degré) au lieu de O(1).
  • La localité du cache est plus faible car les listes chaînées sont dispersées dans la mémoire.
  • Les arêtes pondérées nécessitent un champ associé ou une liste de paires, ce qui complexifie légèrement la structure des données.

Quand utiliser une liste d'adjacence plutôt qu'une matrice d'adjacence ?

Le choix de la représentation dépend de la densité du graphe et des opérations les plus fréquentes. Utilisez ce guide rapide pour choisir la structure appropriée :

  • Privilégier la matrice d'adjacence lorsque le graphe est dense (E est proche de V²), lorsque les arêtes changent rarement et lorsque votre algorithme demande plusieurs fois « existe-t-il une arête entre i et j ? ».
  • Préférez la liste d'adjacence lorsque le graphe est creux (E est beaucoup plus petit que V²), lorsque l'ensemble des sommets ou des arêtes s'accroît pendant l'exécution, et lorsque vous parcourez le graphe avec BFS, DFS ou L'algorithme de Dijkstra pour trouver le plus court chemin.
  • Je préfère un modèle mixte (liste d'adjacence plus un ensemble de hachage d'arêtes) lorsque vous avez besoin à la fois d'une itération rapide des voisins et de requêtes d'arêtes O(1), au prix d'une mémoire supplémentaire.

Les bibliothèques graphiques modernes telles que NetworkX et igraph utilisent par défaut des listes d'adjacence car la plupart des graphes du monde réel (réseaux sociaux, cartes routières, pages Web, dépendances de packages) sont clairsemés et nécessitent de nombreux parcours.

FAQ

Une liste d'adjacence est un tableau de V listes chaînées où chaque liste à l'indice i stocke tous les sommets adjacents au sommet i. L'utilisation de la mémoire est O(V + E), ce qui convient aux graphes creux et aux algorithmes de parcours tels que BFS et DFS.

Une matrice d'adjacence est un tableau bidimensionnel V × V où matrix[i][j] contient le poids de l'arête ou 1 si une arête existe entre le sommet i et le sommet j. La recherche d'arête est O(1) mais la mémoire est toujours O(V²).

La matrice d'adjacence répond aux requêtes d'existence d'arêtes en O(1). La liste d'adjacence parcourt les voisins en O(degré), ce qui est plus rapide pour les algorithmes de parcours tels que BFS, DFS et Dijkstra. Le choix optimal dépend des opérations prédominantes dans votre charge de travail.

Utilisez une liste d'adjacence lorsque le graphe est creux, lorsque les sommets et les arêtes changent au cours de l'exécution, et lorsque l'algorithme parcourt fréquemment les voisins. Les réseaux sociaux, les cartes routières et les graphes de pages web correspondent à ce profil.

Utilisez une matrice d'adjacence lorsque le graphe est dense, que l'ensemble des sommets est fixe et que l'algorithme interroge la même arête de manière répétée. Les algorithmes de Floyd-Warshall et de fermeture transitive s'appliquent naturellement aux matrices d'adjacence.

Oui. Pour les graphes orientés, la matrice n'est pas symétrique et la liste ne contient que les voisins sortants. Pour les graphes pondérés, chaque cellule de la matrice contient le poids, tandis que la liste stocke les paires voisin-poids.

Les réseaux neuronaux graphiques alimentent les couches d'apprentissage automatique avec des matrices d'adjacence ou des tenseurs d'arêtes épars pour la détection de fraudes, la prédiction des propriétés moléculaires et les systèmes de recommandation. Les graphes de connaissances s'appuient également sur des encodages par liste d'adjacence pour l'IA à recherche augmentée.

Oui. GitHub Copilot et ChatGPT génèrent des modèles de listes d'adjacence et de matrices pour Python, C++ et JavaLes développeurs doivent encore vérifier les cas limites tels que les arêtes dupliquées, les boucles et la gestion correcte des graphes orientés ou pondérés.

Résumez cet article avec :