Notes de cours IFT 2125 Fouilles des graphes (rappel) version 0.75 le 10 décembre 2013 NB. Les versions inférieures à 1.0 sont préliminaires et il faut les lire soigneusement. Des erreurs rapportées donnent des points supplémentaires au rapporteur. Soit G = (V, E) un graphe. Pour l’explorer, on cherche des algorithmes qui visitent tous les sommets. Les principaux, qui sont à la base d’autres algorithmes, sont la FEP, fouille en profondeur, et la F EL, fouille en largeur (depth-first search, DFS, et breadth-first search, BFS). Il y a plusieurs manières de les décrire. Par exemple, la FEP peut-être récursive : Algorithme 1 FEP(G) Marquer tout sommet de V non-visité Pour tout sommet v de V non-visité faire DFS(v) DFS(v) Marquer v visité Pour tout u ∈ N (v) non-visité faire DFS(u) Mais les deux approches se ressemblent beaucoup et on peut les réunir dans un seul algorithme non-récursif comprennat une structure de donnée SD indéterminée - elle sera soit pile, soit queue, suivant si on veut la FEP ou la FEL. L’autre différence est le moment où on marque les sommets comme visités : dans la FEP, on les marque au moment de la sortie de la pile, dans la FEL c’est au moment de l’ajout à la queue. Soit donc SD une des deux structures de données et soit AJOU T (v, SD) et RET (SD) les procédures qui ajoutent le sommet v à la structure et en retirent le sommet suivant. Rappelons que dans une queue, on ajoute les sommets à la fin et on les retire au début (premier entré - premier sorti) tandis que dans une pile, on ajoute les sommets devant et on les retire devant (dernier entré - premier sorti). On peut alors écrire u ←− RET (SD) pour indiquer que c’est le sommet u qui est retiré de la SD. Les implémentations de ces structures sont étudées en IFT 2015, par exemple. On obtient quelque chose comme (NB. les commandes qui commencent par (FEX) sont executées si et seulement si on fait FEX, X ∈ {P, L}): Algorithme 2 FEX(G) Marquer tout sommet de V non-visité Pour tout sommet v de V non-visité faire SD vide (FEL) Marquer v visité 1 AJOUT(v,SD) tant que SD n’est pas vide faire u ←− RET(SD) (FEP) Marquer u visité Pour tout x ∈ N (u) non-visité faire (FEL) Marquer x visité AJOUT(x, SD) Dans les exercices suivant, vous pouvez parfois modifier l’agorithme générique FEX, parfois il vaut mieux faire la FEP et la FEL séparement. Exercice 1 On peut numéroter les sommets dans l’ordre dans lequel on les visite. Modifiez l’algorithme pour qu’il le fasse. Exercice 2 La FEP et la FEL crée chacune une arborescence (si le graphe est connexe) avec comme racine le premier sommet choisi. Modifier l’algorithme pour qu’il retourne cette arborescence. Exercice 3 Si le graphe est orienté, on peut suivre les arcs dans le bon sens. Modifier l’algorihme pour le faire. Exercice 4 Pour trouver un ordre topologique d’un graphe orienté D = (V, A), on numérote les sommets par une FEP, mais au moment où la procédure fait demi-tour, i.e. au moment ou un sommet n’a plus de voisin non-visités (comme on a vu en classe, pour obtenir l’ordre topologique, on inverse cette numérotation). Modifier l’algorithme pour qu’il soit retourne un ordre topologique de D, soit rentourne un circuit en disant qu’un tel ordre n’existe pas parce que le graphe contient un circuit. Considérons la FEP. On commence par un sommet que l’on prend comme racine d’une arborescence. Quand on visite un sommet u pour la première fois (comme enfant du sommet v que l’on vient de visiter), on lui attribue un numéro f ep(u) (le suivant, dans l’ordre, la racine ayant le numéro 1) et on “mets” (implicitement, mème si l’exercice 2 vous demande de rendre l’opération explicite) l’arête uv dans l’arborescence. Si xy est une arête du graphe qui n’est dans l’abroberescence crée par la FEP, elle relie forcément deux sommets d’une même branche de l’arborescence, i.e., l’un des deux sommets est descendant de l’autre. Exercice 5 Pourquoi? Dans ce cas tous les sommets entre x et y sur la branche sont dans un cycle et on ne peut pas les déconnecter entre eux par l’enlèvemen d’un seul sommet. Ceci suggère une procédure pour trouver les points d’articulation et des blocs d’un graphe (voir les définitions). En faisant une FEP, étiqueter chaque sommet u lors de la premiẽre visite par une couple (f ep(u), up(u)); cette première fois up(u) = f ep(u). A chaque visite ultérieure de u – i.e. en 2 y remontant d’un de ces enfants v – mettre à jour up(u) ←− min{up(v), up(u)}. Chaque fois que l’on considère un voisin z de u déjà visité, mettre à jour up(u) ←− min{f ep(z), up(u)}. Chaque fois que la mise-à-jour laisse up(u) ≥ up(v), u est un point d’articulation. La racine est exceptionnelle - elle est point d’articulation si et seulement si elle a plus qu’un enfant. Exercice 6 Pourquoi? Exercice 7 Ecrivez un algorithme (pas un programme, un algorithme en pseudo-code, avec du français ou de l’anglais) qui prend en entrée un graphe G et sort les points d’articulation de G ainsi que les blocs de G. Notons qu’un points d’articulation peut-être dans plusiuers blocs et que les blocs sont en fait des composantes 2-connnexe sauf s’il sont des arêtes. 3