Terminale · Algorithmique

Parcourir un graphe en largeur : BFS

Pour trouver un itinéraire avec le moins de correspondances, on peut explorer d’abord tous les lieux accessibles en une étape, puis en deux, puis en trois. Le parcours en largeur réalise cette progression grâce à une file. La première découverte d’un sommet fixe alors sa distance minimale en nombre d’arêtes.

SofienAvec SofienIngénieur et enseignant en informatique
Dans ce chapitre

Un cap pour ce chapitre

Ce que vous saurez faire

  • Tracer la file d’un BFS.
  • Calculer des distances depuis un sommet.
  • Reconstruire un chemin par prédécesseurs.
Les bases utiles pour commencer

Explorer des couches de distance

Le sommet de départ a distance zéro. Ses voisins ont distance un s’ils ne sont pas déjà connus. Les voisins encore inconnus de ces derniers ont distance deux, et ainsi de suite. Cette progression par couches explique le nom parcours en largeur.

Prenons les liaisons A-B, A-C, B-D, B-E et C-E, ainsi qu’un sommet isolé F. Depuis A, B et C sont à distance un ; D et E sont à distance deux. F n’a pas de distance finie depuis A. Une distance de zéro ne doit donc pas être utilisée pour signifier « inaccessible », puisque zéro décrit déjà le départ.

La file conserve le bon ordre

On place le départ dans une file et on le marque découvert. Tant que la file n’est pas vide, on retire son premier sommet u. Pour chaque voisin v encore inconnu, on fixe distance[v]=distance[u]+1, on enregistre son prédécesseur u et on ajoute v en fin de file.

Le marquage se fait lors de l’ajout, pas seulement lors du retrait. Sinon un même sommet voisin de plusieurs sommets en attente pourrait être ajouté plusieurs fois. Dans l’exemple, E est voisin de B et C : une seule découverte doit suffire, avec un prédécesseur défini par l’ordre des voisins.

La frontière est la file des sommets découverts mais pas encore traités. Elle ne contient pas tout l’historique du parcours. L’ensemble des découvertes, lui, conserve aussi les sommets déjà sortis. Un sommet absent de la file peut donc être encore inconnu ou avoir été complètement traité : il faut distinguer ces situations.

Cette implémentation renvoie les distances et les parents pour les sommets atteints. Le dictionnaire des distances sert aussi de mémoire des découvertes. Le graphe doit contenir une entrée pour chaque sommet, même isolé.

from collections import deque

def largeur(graphe, depart):
    file = deque([depart])
    distance = {depart: 0}
    parent = {depart: None}
    while file:
        u = file.popleft()
        for v in graphe[u]:
            if v not in distance:
                distance[v] = distance[u] + 1
                parent[v] = u
                file.append(v)
    return distance, parent

Retrouver un chemin sans conserver tous les chemins

Pour reconstruire un chemin de A à E, on suit les prédécesseurs en sens inverse. Si E a été découvert depuis B et B depuis A, la remontée donne E,B,A. Il suffit ensuite d’inverser cette liste pour obtenir A,B,E.

Un autre ordre de voisins peut découvrir E depuis C et produire A,C,E. Les deux chemins ont la même longueur minimale. L’arbre des prédécesseurs est une sélection parmi les possibilités, pas une liste de toutes les routes du graphe. Pour le départ, le prédécesseur peut être marqué absent afin d’arrêter la remontée.

Comprendre la garantie et sa limite

La file traite les sommets par distances non décroissantes. Lorsqu’un sommet est découvert pour la première fois à distance d, aucun chemin plus court n’a été oublié : ses couches précédentes ont déjà été explorées. C’est cette propriété qui justifie le minimum du nombre d’arêtes.

La garantie ne porte pas automatiquement sur des coûts pondérés. Deux arêtes coûteuses peuvent être moins intéressantes que trois arêtes peu coûteuses. Il faut alors un algorithme adapté aux poids. Avec des listes d’adjacence, BFS examine chaque sommet atteint et ses voisins, pour un coût de l’ordre du nombre de sommets plus celui des arêtes examinées.

Exemple suivi : le moment où une distance devient connue

Au départ A est découvert à distance zéro et la file contient A. Après traitement de A, B et C sont découverts à distance un : file [B,C]. Après traitement de B, D et E reçoivent distance deux et parent B : file [C,D,E]. E est déjà connu alors qu’il n’a pas encore été traité. Le traitement de C ne doit pas le remettre dans la file ni remplacer son parent dans cette variante.

Pourquoi cette distance deux est-elle minimale ? Si E avait été voisin du départ, il aurait été découvert pendant la première étape. Il ne l’a pas été. Il possède maintenant un chemin de deux arêtes via B ; aucun chemin de longueur inférieure ne reste à examiner. L’ordre des voisins peut choisir B ou C comme parent de E, mais tous ces parents possibles donnent une distance identique. La distance minimale peut être unique alors que le chemin ne l’est pas.

Exemple suivi : reconstruire et traiter les absences

Avec les parents E←B←A, partez de E et ajoutez successivement E, B, A dans une liste. A possède un marqueur sans parent, qui arrête la remontée. Inversez ensuite cette liste pour afficher A-B-E. Sa longueur en sommets vaut trois ; sa distance en arêtes vaut deux. Pour une destination égale au départ, la liste contient seulement A et la distance vaut zéro.

Pour F, aucun parent n’a été défini. Tant que le parcours n’est pas terminé, cela signifie seulement « pas encore découvert ». Une fois la file vide après exploration de la composante de A, on peut conclure que F est inaccessible depuis A. Ne remontez pas des parents absents et n’attribuez pas zéro à cette impossibilité. L’atelier conserve le terme « inconnue » pendant la progression ; votre justification d’inaccessibilité doit s’appuyer sur la fin effective de l’exploration.

À vous de faire varier les choses

Suivez la vague de découverte

Choisissez le départ puis le nombre de sommets traités. Le tableau conserve distances et prédécesseurs ; F permet de tester un départ isolé.

Lire le résultat de l’expérience initiale

File : B → C.

Un sommet est découvert dès son ajout dans la file. Les distances inconnues restent distinctes de zéro.

SommetDistance connuePrédécesseurÉtat
A0AucunTraité
B1AEn file
C1AEn file
DInconnueAucunNon découvert
EInconnueAucunNon découvert
FInconnueAucunNon découvert

La frontière en attente permet de voir pourquoi les distances augmentent couche après couche.

De la compréhension à l’autonomie

À vous de résoudre

Cherchez d’abord par vous-même. Vérifiez les résultats demandés, utilisez les indices si nécessaire, puis comparez votre méthode à la correction.

Exercice 1 · Comprendre#

Construire la première couche

Dans le graphe du cours, quelles distances attribue-t-on à A, B et C en partant de A ?

Indice 1

Le départ ne nécessite aucun déplacement.

Indice 2

B et C sont des voisins directs.

Comprendre la correction

A reçoit zéro ; B et C reçoivent un. La distance compte les arêtes parcourues, pas les sommets du chemin. Le chemin A-B contient deux sommets mais une seule arête.

Exercice 2 · Appliquer#

Suivre la file

Les voisins sont alphabétiques. Après traitement de A, la file contient B,C. Après traitement de B, quel est son contenu ?

Indice 1

Retirez B avant d’ajouter ses nouveaux voisins.

Indice 2

A est déjà connu ; D et E sont nouveaux.

Comprendre la correction

La file devient C,D,E. C était déjà en attente et reste devant les nouveaux sommets. D et E sont ajoutés dans cet ordre. La structure FIFO garantit que le niveau un finit avant le traitement du niveau deux.

Exercice 3 · Analyser#

Éviter une double découverte

Quand C est traité, E figure déjà dans la file après sa découverte depuis B. Faut-il l’ajouter une seconde fois ?

Indice 1

Être dans la file signifie avoir été découvert.

Indice 2

La distance et le prédécesseur ont déjà été fixés.

Comprendre la correction

Non. E est déjà marqué depuis son ajout par B. L’ajouter de nouveau produit du travail inutile et peut compliquer le suivi des prédécesseurs. Le marquage dès l’enfilage évite ce doublon.

Exercice 4 · Justifier#

Identifier la bonne métrique

A-B-D comporte deux arêtes de coût dix ; A-C-E-D trois arêtes de coût un. Quel chemin BFS peut-il privilégier et que ne garantit-il pas ?

Indice 1

BFS compare les couches en nombre d’arêtes.

Indice 2

Calculez séparément le coût pondéré.

Comprendre la correction

BFS privilégie A-B-D pour ses deux arêtes. Son coût vaut vingt, alors que l’autre trajet coûte trois. Il garantit un minimum de sauts dans le graphe non pondéré, pas un minimum de la somme des coûts.

Exercice 5 · Problème de synthèse#

Problème : compter les découvertes et les traitements

Depuis A dans le graphe du cours, donnez la file, les sommets traités et le nombre de sommets découverts après deux traitements. Quelle distance connaît-on déjà pour E ? F est-il forcément inaccessible parce qu’il n’a pas encore été découvert à cet instant ?

Indice 1

A puis B sont retirés de la file.

Indice 2

Une conclusion d’absence exige d’avoir épuisé la frontière.

Comprendre la correction

La file vaut [C,D,E], les traités sont A et B, et cinq sommets sont découverts : A,B,C,D,E. E est déjà à distance deux. La seule observation « non découvert après deux traitements » ne suffit pas pour conclure à l’inaccessibilité ; ici le dessin montre F isolé, mais un raisonnement fondé sur l’exécution attendrait la file vide.

Exercice 6 · Problème de synthèse#

Problème : un BFS depuis E

Avec voisins alphabétiques, partez de E. Écrivez les deux premières évolutions de file, puis les distances de A, B, C et D. Donnez un chemin minimal vers D et expliquez pourquoi E reste à distance zéro malgré le cycle du graphe.

Indice 1

E découvre B puis C.

Indice 2

B découvre A et D avant le traitement de C.

Comprendre la correction

Après E la file est [B,C] ; après B elle est [C,A,D]. Les distances sont A=2, B=1, C=1, D=2. Le chemin E-B-D est minimal. E a été marqué dès le départ avec distance zéro ; le retour d’une liaison vers E ne le redécouvre pas et ne remplace pas cette distance.

Exercice 7 · Problème de synthèse#

Problème : comparer deux objectifs de trajet

Un réseau contient A-B-D, avec coûts 9 et 9, et A-C-E-D, avec coûts 2,2,2. Donnez la distance BFS vers D et le coût de son chemin. Identifiez le trajet de coût minimal. Si les poids sont tous remplacés par 1, les objectifs coïncident-ils ?

Indice 1

BFS ignore les coûts de liaison.

Indice 2

Additionnez ensuite les poids de chaque chemin.

Comprendre la correction

BFS trouve D à distance deux via B, pour un coût 18. Le trajet via C et E coûte 6 malgré trois arêtes. Si tous les poids valent un, le coût devient exactement le nombre d’arêtes et BFS minimise alors les deux grandeurs. L’usage d’une file suffit pour la distance uniforme, mais ne constitue pas un algorithme général de coût pondéré.

Les erreurs qui méritent un détour

Marquer seulement après le retrait.
Un sommet peut être ajouté plusieurs fois avant ce retrait.
Confondre plus court en sauts et plus faible coût.
BFS ignore les poids dans cette version.

La fiche à garder

L’essentiel à retenir

  • La file fait progresser l’exploration par couches.
  • Le premier marquage fixe une distance minimale en arêtes.
  • Les prédécesseurs permettent de reconstruire un chemin.

Cette notion au bac

Retrouvez ces idées dans un sujet complet, avec des indices, une correction expliquée et des ateliers.

Le prochain pas

Retrouver le catalogue de Terminale

Ce chapitre s’appuie sur le programme officiel de Terminale (PDF, nouvel onglet). Les explications et exercices sont proposés pour l’apprentissage.