Bonjour,
Bienvenue dans ce nouveau module dédié à l'une des structures les plus fondamentales et universelles en informatique : les graphes. Dans les modules précédents, nous avons exploré en profondeur les arbres, des arbres binaires de recherche aux arbres AVL auto-équilibrants. Il est essentiel de comprendre qu'un arbre n'est qu'un cas particulier de graphe : un graphe connexe et sans cycle. Nous allons maintenant généraliser notre étude pour aborder des structures de relations beaucoup plus riches et complexes.
L'objectif de cette première leçon est de poser des fondations solides. Nous allons formellement définir ce qu'est un graphe, distinguer ses différentes catégories (orienté, non orienté, pondéré) et, surtout, étudier les deux manières canoniques de le représenter en machine : la matrice d'adjacence et les listes d'adjacence. La maîtrise de ces représentations et la compréhension de leurs compromis respectifs sont des prérequis indispensables pour aborder tout algorithme sur les graphes.
1. Qu'est-ce qu'un graphe ? Définitions et typologie
Un graphe est un modèle mathématique permettant de représenter des relations entre des objets. De manière informelle, un graphe est un ensemble de points (les sommets) reliés par des lignes (les arêtes).
Pour une introduction visuelle rapide aux différents types de graphes, je vous propose de visionner cette courte vidéo.
représentation d'un graphe (matrice d'adjacence et liste d'adjacence) , graph representation
Cette vidéo de la chaîne Artificial Intelligence (H.A BOUARARA) présente de manière concise les types de graphes que nous allons étudier.
Regardez le segment de 00:43 à 02:51. Concentrez-vous sur la distinction visuelle entre un graphe non dirigé (non orienté), un graphe dirigé (orienté), et un graphe avec des poids (pondéré).
Maintenant que vous avez une intuition visuelle, formalisons ces concepts. En théorie des graphes, la rigueur est primordiale.
Un graphe est un couple où :
- est un ensemble fini de sommets (ou nœuds, vertices en anglais). Le nombre de sommets, , est appelé l'ordre du graphe.
- est un ensemble de paires de sommets, appelées arêtes (edges) ou arcs.
La nature de ces paires définit le type de graphe :
- Graphe non orienté : Les arêtes sont des paires non ordonnées . Si une arête relie et , on dit que et sont adjacents. Le degré d'un sommet est le nombre d'arêtes qui lui sont incidentes.
- Graphe orienté (ou digraphe) : Les arêtes, appelées arcs, sont des couples ordonnés , signifiant qu'il existe une liaison de vers .
- On dit que est un successeur de , et un prédécesseur de .
- Le degré sortant d'un sommet () est le nombre d'arcs qui partent de .
- Le degré entrant d'un sommet () est le nombre d'arcs qui arrivent à .
L'image ci-dessous illustre bien ces notions pour un graphe orienté.

Enfin, on distingue :
- Graphe non pondéré : Toutes les arêtes ont une importance égale.
- Graphe pondéré : Une valeur (un poids) est associée à chaque arête ou arc. Ce poids peut représenter une distance, un coût, une capacité, etc.
Pour une définition formelle et complète de cette terminologie, je vous invite à lire la section suivante du polycopié de Christine Solnon (CNRS).
Théorie des graphes et optimisation dans les graphes - CNRS
Ce document fournit des définitions rigoureuses qui sont la base de la théorie des graphes.
Lisez la section 2, "Définitions" (pages 4 à 6). Portez une attention particulière aux termes : graphe orienté/non orienté, ordre, boucle, graphe simple, adjacence, degré, degré entrant/sortant.
2. Représentations d'un graphe en machine
Comment traduire cette structure abstraite en une structure de données concrète ? Il existe deux approches classiques, chacune avec ses avantages et ses inconvénients.
La vidéo suivante, bien qu'en anglais, offre une explication particulièrement claire et détaillée de ces deux représentations et de leurs compromis.
La chaîne "Algorithms with Attitude" explique de manière très pédagogique la matrice et la liste d'adjacence, ainsi que leur analyse comparative.
Regardez la vidéo du début jusqu'à 04:16. La vidéo couvre successivement l'introduction (jusqu'à 00:44), la matrice d'adjacence (jusqu'à 02:24), et la liste d'adjacence (jusqu'à 04:16). Notez comment chaque structure est construite et comment elle gère les graphes orientés, non orientés et pondérés.
Synthétisons et formalisons ce que vous venez de voir.
a) Matrice d'adjacence
Pour un graphe d'ordre (avec des sommets numérotés de 0 à ), on utilise une matrice de taille .
- Graphe non pondéré : s'il existe une arête entre et , et 0 sinon. Pour un graphe non orienté, la matrice est symétrique.
- Graphe pondéré : contient le poids de l'arête . S'il n'y a pas d'arête, on utilise une valeur spéciale : pour un problème de plus court chemin, 0 ou une autre valeur sentinelle selon le contexte.
Avantages :
- Vérifier l'existence d'une arête se fait en temps constant .
Inconvénients :
- L'espace mémoire requis est toujours en , même si le graphe a très peu d'arêtes.
- Lister tous les voisins d'un sommet requiert de parcourir toute la ligne , soit un coût en .
b) Listes d'adjacence
On utilise un tableau (ou une liste) de taille , où l'entrée pointe vers une liste chaînée contenant tous les voisins du sommet .
- Graphe non pondéré : La liste pour le sommet contient les identifiants de ses voisins.
- Graphe pondéré : La liste contient des paires
(voisin, poids). - Graphe non orienté : Chaque arête apparaît deux fois : est dans la liste de , et dans la liste de .
Avantages :
- L'espace mémoire est en , ce qui est très efficace pour les graphes creux (où ).
- Lister tous les voisins d'un sommet est optimal : le coût est proportionnel à son degré, .
Inconvénients :
- Vérifier l'existence d'une arête requiert de parcourir la liste d'adjacence de , soit un coût en dans le pire cas.
3. Analyse comparative et choix de la représentation
Le choix entre matrice et listes d'adjacence est un arbitrage classique en algorithmique. Il dépend de la densité du graphe et des opérations que l'on souhaite effectuer.
- Un graphe est dit dense si est proche de .
- Un graphe est dit creux (ou épars) si est beaucoup plus petit que .
La plupart des graphes rencontrés en pratique (réseaux sociaux, web, réseaux routiers) sont creux.
Regardons la fin de la vidéo précédente pour une excellente synthèse de cette comparaison.
Cette dernière partie de la vidéo "Graphs: Representation" analyse les compromis en termes de complexité spatiale et temporelle.
Regardez la section de 06:12 à 08:53. L'auteur y compare l'efficacité des deux représentations pour différentes opérations et conclut sur le choix par défaut dans la plupart des contextes algorithmiques.
Pour renforcer ces notions avec une lecture en français et des exemples concrets, consultez la section suivante.
Théorie des graphes et optimisation dans les graphes - CNRS
Ce document formalise la comparaison et donne des exemples pratiques d'implémentation.
Lisez la section 3, "Représentation des graphes" (pages 7 et 8). Cette lecture vous permettra de consolider votre compréhension des deux méthodes, de leurs besoins en mémoire et de la complexité de leurs opérations.
En résumé, pour la préparation à l'Agrégation, retenez la règle générale : sauf indication contraire, privilégiez les listes d'adjacence. C'est la représentation la plus polyvalente et la plus performante pour la majorité des problèmes algorithmiques sur les graphes, qui sont souvent creux.
4. Exercice d'application
Pour vous assurer d'avoir bien assimilé ces concepts, réalisez l'exercice suivant.
Énoncé :
Soit le graphe non orienté suivant :
- Donnez sa représentation par matrice d'adjacence.
- Donnez sa représentation par listes d'adjacence.
Prenez le temps de construire ces deux représentations sur papier. Une fois terminé, vous pouvez vérifier votre travail avec la correction fournie dans le document ci-dessous.
Théorie des graphes et optimisation dans les graphes - CNRS
Le document du CNRS contient des exercices corrigés qui sont parfaits pour s'entraîner.
L'exercice demandé correspond au premier exercice de la page 9. La correction est juste en dessous de l'énoncé. Comparez-la à votre solution.
Conclusion
Aujourd'hui, nous avons jeté les bases indispensables à l'étude des graphes. Nous avons vu qu'au-delà de la diversité de leurs apparences, les graphes peuvent être décrits et manipulés de manière rigoureuse.
Points clés à retenir :
- Un graphe est un couple . Sa nature dépend de si les arêtes/arcs dans sont des paires ordonnées ou non, et si elles portent un poids.
- Les deux représentations fondamentales sont la matrice d'adjacence et les listes d'adjacence.
- La matrice d'adjacence est efficace pour les graphes denses et pour tester rapidement l'existence d'une arête (), mais son coût en mémoire () est souvent prohibitif.
- Les listes d'adjacence sont la norme pour les graphes creux. Elles optimisent l'espace () et le parcours des voisins d'un sommet ().
- Le choix de la représentation est un arbitrage crucial qui dépend de la structure du graphe et des algorithmes à implémenter.
Prochaine étape :
Maintenant que nous savons représenter un graphe, comment l'explorer ? Dans notre prochaine leçon, nous aborderons notre premier algorithme de parcours : le parcours en largeur (BFS - Breadth-First Search). Nous verrons comment l'implémenter et comment il nous permet de résoudre un problème fondamental : trouver le plus court chemin en nombre d'arêtes.