Bonjour ! Et bienvenue dans cette leçon sur le parcours de graphe.

Trouver la sortie d'un labyrinthe nécessite de parcourir une partie du labyrinthe.
Le parcours de graphe est le domaine de la théorie des graphes qui décrit comment explorer un graphe, un sommet à la fois, en partant d'un sommet initial.
Dans de nombreux cas, nous nous intéressons à l’accessibilité.
L’accessibilité consiste à trouver comment atteindre un sommet cible depuis un sommet initial, en suivant un chemin dans le graphe.
Pour obtenir les chemins du sommet initial à tous les sommets accessibles, je vais vous montrer comment construire un arbre, obtenu à partir du graphe initial, qui transmettra juste assez d’informations pour nous guider vers n’importe quel sommet accessible depuis le sommet initial.
Voisins et arbres couvrants
Rappelons qu’un graphe est un couple $G$ composé d’un ensemble de sommets $V$ et d’un ensemble d’arêtes $E$.
Nous devons maintenant définir quelques notions supplémentaires.

Nous définissons les voisins de $u$ dans $G$ comme l'ensemble des sommets $v$ tels que $\{u,v\}$ appartient à $E$.
Comme nous l’avons vu dans la leçon précédente, un arbre est un graphe connexe sans cycles.

Par exemple, à gauche se trouve un dessin d'un arbre. Cependant, le graphe à droite n'est pas un arbre, car il contient un cycle.

Maintenant, un arbre couvrant d'un graphe $G$ est un arbre obtenu à partir de $G$ en supprimant certaines arêtes.
Pour illustrer, considérons le graphe suivant. Nous pouvons obtenir un arbre couvrant en ne conservant que les arêtes suivantes.

Notez que pour un graphe donné, d'autres arbres couvrants peuvent être définis, comme celui-ci.

Trouver des arbres couvrants peut avoir de nombreuses applications.
En particulier, trouver un arbre couvrant est très utile lorsque vous voulez éviter les boucles, comme dans les algorithmes de routage en réseau.

Un autre exemple de son utilité est lors de l'évaluation de la connexité d'un graphe.
Imaginez que vous souhaitez isoler une portion d'autoroute pour des travaux de maintenance.
D'abord, vous devez vous assurer que le graphe des rues reste connecté pendant les travaux.
Dans cette leçon, nous allons voir comment trouver un chemin entre deux sommets d’un graphe connexe, afin de pouvoir naviguer entre n’importe quels deux points.
Par définition, un arbre couvrant inclura exactement un chemin entre ces deux points.
Nous comparerons deux approches : la recherche en profondeur et la recherche en largeur.
Recherche en profondeur
L’idée principale d’une recherche en profondeur est de continuer à explorer le graphe, en sautant d’un sommet donné à l’un de ses voisins non explorés.
Parfois, tous les voisins du sommet où nous sommes ont déjà été explorés, auquel cas nous revenons en arrière, suivant la trace dans la direction opposée jusqu’à trouver un sommet non exploré vers lequel sauter.

Prenons l'exemple suivant.
Une recherche en profondeur, ou DFS, peut être réalisée de la manière suivante.
Commençons depuis $v_1$.

D'abord, nous montons.
Notez que nous aurions pu choisir d'aller à droite.

Nous continuons à explorer le graphe, nous montons encore.

Ensuite, nous n'avons qu'un seul voisin non exploré, qui est à droite.
Nous allons donc à droite.

Maintenant, nous descendons.
Alternativement, nous aurions pu continuer à droite.

À partir d'ici, il y a quatre voisins, dont deux sont non explorés.
Nous choisissons d'aller à droite.

Ensuite, nous montons.

À ce stade, nous ne pouvons pas aller plus loin, car tous les voisins actuels ont déjà été explorés.
Nous revenons au dernier sommet pour lequel il y avait un voisin non exploré, qui est le précédent.

Et nous descendons.

Depuis ce sommet, il ne reste qu'un seul voisin non exploré, qui est celui à gauche.
C'est le dernier sommet non exploré dans le graphe.

Le graphe en rouge est un arbre couvrant obtenu à partir du graphe en utilisant un DFS.
DFS est une stratégie simple mais efficace pour s’assurer que tous les sommets accessibles sont explorés.

C'est un moyen facile de trouver la sortie d'un labyrinthe, ou de s'assurer que les rues restent connectées pendant les travaux.

Cependant, cela ne donne pas nécessairement les chemins les plus courts entre les paires de sommets dans le graphe.
Dans cet exemple, il faut 7 sauts pour aller de $v_1$ à $v_2$, alors qu'ils pourraient être reliés en un seul saut.
Recherche en largeur
L’autre approche que je vais décrire ici est la recherche en largeur.
Lorsqu’on utilise une recherche en largeur, ou BFS, on explore le graphe en augmentant progressivement le nombre de sauts depuis le sommet initial.

Considérons le même exemple, où nous commençons en $v_1$.

Nous commençons par explorer tous les sommets à un saut de $v_1$ : nous connectons donc $v_2$ et $v_4$ à $v_1$.

Puis nous explorons tous les sommets à deux sauts de $v_1$.
Un sommet à deux sauts de $v_1$ est à un saut d'un sommet qui est à un saut de $v_1$.
Nous regardons donc les voisins de $v_2$ et $v_4$ et les connectons à $v_2$ ou $v_4$.
Nous obtenons $v_3$, $v_5$ et $v_7$.

Ensuite, nous explorons les sommets à trois sauts du sommet $v_1$.
Nous regardons donc les sommets à deux sauts, qui sont $v_3$, $v_5$ et $v_7$, et leurs voisins non explorés.
Nous obtenons $v_8$ et $v_6$.

Enfin, le sommet orange est à un saut de $v_8$, qui est à trois sauts du sommet $v_1$.
Nous les connectons.

Le graphe résultant en rouge est un arbre couvrant obtenu à partir du BFS, qui est composé exclusivement de chemins les plus courts du sommet $v_1$ aux autres sommets du graphe.
Un BFS est une stratégie prudente dans laquelle on essaie de garder les distances au sommet initial aussi petites que possible pendant l’exploration.

Ceci est particulièrement utile lorsque le sommet initial contient des ressources spécifiques dont nous pourrions avoir besoin à tout moment.
Cependant, cela nécessite plus d'organisation que son homologue DFS plus simple.
Comparaison entre BFS et DFS
Dans l’exemple précédent, les arbres couvrants obtenus par un BFS et un DFS sont très différents.
Voici un autre exemple utilisant le graphe que nous avons considéré plus tôt dans cette leçon.

Ceci est un arbre couvrant obtenu à partir d'un DFS démarrant de $v_1$.

Tandis que ceci est un arbre couvrant obtenu à partir d'un BFS démarrant de $v_1$.
Parce qu’un BFS est réalisé en augmentant progressivement les sauts depuis $v_1$, un arbre couvrant obtenu par BFS fournira toujours le chemin le plus court de $v_1$ à n’importe quel autre sommet du graphe, à condition que le graphe soit non pondéré.
Cela est clairement visible dans cet exemple.
Mots de conclusion
Dans la prochaine leçon, nous verrons comment la différence entre un BFS et un DFS est directement liée au type de structure mémoire qui peut être utilisée pour implémenter ces deux algorithmes.