Algorithmique — L3
TD 7 : Parcours de Graphes
1 2
3
4
5
6
Fig. 1 – Un graphe oriene
Exercice 1 : Appliquer `a ce graphe l’algorithme de parcours en largeur (le sommet origine est
indiqu´e par une simple fl`eche entrante). L’arbre de parcours en largeur r´esultant sera pr´esent´e par
un scema dans lequel les sommets de profondeur ´egale seront mis `a la mˆeme hauteur, le sommet
origine ´etant mis en haut.
Exercice 2 : Soit un graphe oriene G= (V, A) et soit sV. Soit une arborescence T=
(VT, AT) telle que ATAet VTest l’ensemble des sommets de Gaccessibles depuis s(y compris
slui-mˆeme), et telle que pour tout sommet vVT, le chemin de s`a vdans Tsoit un plus court
chemin de s`a vdans G. Est-il toujours possible d’obtenir Tpar un certain parcours en largeur de
Gdepuis s?
Exercice 3 : Donnez un algorithme calculant l’ensemble des composantes connexes d’un graphe
non oriene et calculez en la complexit´e.
Exercice 4 : Comment calculer l’ensemble des sommets accessibles `a partir d’un sommet donn´e
dans un graphe oriene ? Donnez un algorithme permettant de calculer la composante fortement
connexe d’un sommet v. Quel est sa complexit´e ?
Exercice 5 : Appliquer au graphe de la figure 1 l’algorithme de parcours en profondeur. Le
r´esultat sera pr´esene sous la forme d’une arborescence en profondeur, en distinguant les arcs de
liaisons des autres types d’arcs.
Exercice 6 : Modifier l’algorithme de parcours en profondeur donn´e en cours de telle sorte
qu’il affiche pour chaque arc du graphe son type (arc de l’arbre de parcours, arc de retour, arc
transversal, arc en avant).
Exercice 7 :
1. Quel type de parcours est-il pr´ef´erable d’utiliser (une seule fois) pour les probl`emes suivants :
(a) trouver et afficher un circuit s’il en existe,
(b) trouver et afficher un circuit de longueur minimale contenant un sommet donn´e,
2. Le programme suivant se veut ˆetre une solution de a). Malheureusement, il ne trouve pas
toujours un circuit et parfois il trouve un circuit qui n’en est pas un. Expliquer pourquoi et
corriger l’algorithme pour r´esoudre le probl`eme
Variables Globales:
booleen marquage[V] initialis´e `a faux
sommet p`ere[V] initialis´e `a null
Variable locale sommet v
Prendre un sommet v
si( !cherche_circuit(v) )
afficher ‘‘pas de circuit’’
*****************************************
//retourne vrai si un circuit trouv´e
boolean cherche_circuit(sommet v){
Variable locale sommet x,y
marquage[v] = vrai
pour chaque sommet x tel que (v,x) est un arc de G faire{
si( marquage[x] == faux) faire{
p`ere[x] = v
si( cherche_circuit(x) ) \\ si trouv´e alors terminer
retourner vrai
}
sinon{
\\afficher le circuit trouv´e
afficher x
y = p`ere[x]
tant que (y != x) faire{
afficher(y)
y = p`ere[y]
}
returner vrai
}
}//fin pour
retourner faux
}
3. ´
Ecrivez une solution pour l’autre probl`eme et montrer :
qu’elle termine ;
que, si on calcule un chemin, celui-ci correspond bien `a ce que l’on cherche ;
que, si le chemin recherce existe, l’algorithme le trouve.
4. Les trois points pr´ec´edents sont-ils suffisants pour assurer que l’algorithme est correct ?
Exercice 8 : Donner un algorithme qui v´erifie si un graphe non orient´e poss`ede un cycle.
Correction 1 : Un pseudo-code possible du parcours en largeur :
Procedure PL(sommet v)
Variables :
booleen marquage[V] initialise a faux
sommet x
File Afaire
Debut :
marquage[v]=vrai
enfiler (v,Afaire)
tant que (Afaire non vide) faire
v=defiler(Afaire)
pour chaque voisin x de v faire
si marquage[x]==faux faire
enfiler[x]
marquage[x]=vrai
Fin
`
A appliquer sur le graphe...
Correction 2 : : non ! Par exemple, le graphe de sommets {a, b, c, d, e}et d’arˆetes {(ab),(ac),
(bd),(be),(cd),(ce)}. L’arbre d’arˆetes {(ab),(ac),(bd),(ce)}ne peut ˆetre obtenu par parcours en
largeur, mais est bien un arbre de plus courts chemins partants de a.
Correction 3 : On fait un parcours avec relance. Pour chaque relance, une composante :
Variables globales:
booleen marquage[V] initialise a faux
sommet x,y
entier i
File Afaire
Debut :
Pour x de 1 a n
Si marquage[x] = faux
Afficher ‘‘Composante’’ i++ ‘‘:’’
PL(x)
Fin
Procedure PL(sommet v)
marquage[v]=vrai
enfiler (v,Afaire)
tant que (Afaire non vide) faire
v=defiler(Afaire)
Afficher v
pour chaque voisin y de v faire
si marquage[y]==faux faire
enfiler[y]
marquage[y]=vrai
Complexit´e : lin´eaire. C’est `a dire O(n+m) sur les graphes coes en listes d’adjacence, et en
O(n2) s’ils sont coes en matrices d’adjacence.
Correction 4 : Il n’y a rien a changer si le graphe est orient´e : on fait PL(v) avec l’algo
pr´ec´edent pour avoir les sommets accessibles depuis v. La composante fortemement connexe de v
est form´ee des sommets accessibles et co-accessibles depuis v. Donc
On calcule (par parcours en profondeur) les sommets accessibles depuis v: liste A
On fait la transpos´ee de G: chaque arc (ab) est replac´e par (ba)
On calcule les sommets accessibles depuis vdans le transpos´e : liste C(co-accessibles dans
G!)
La composante fortement connexe est AC.
Les trois premi`eres ´etapes se font en O(n+m) sur les graphes cod´es en listes d’adjacence, et
en O(n2) s’ils sont coes en matrices d’adjacence. La derni`ere est en O(n).
Correction 5 : On applique l’algo (cf exercice suivant) sur le graphe...
Correction 6 : Un pseudo-code possible du parcours en profondeur avec relance. On n’utilise
pas de marques : les dates remplacent. Un d´ebut `a -1 signifie un sommet non encore atteint, un
d´ebut 0 mais une fin de -1 signifie un sommet en cours de visite.
Variables globales:
sommet x,y
entier temps = 0, debut[V], fin[V] tableaux initialises `a -1
Debut :
Pour x de 1 a n
Si marquage[x] = faux
PP(x)
Fin
Procedure PP(sommet v)
debut[v] = temps++
pour chaque voisin y de v faire
si debut[y] == -1
Afficher (v,y) est un arc de parcours
PP(y)
sinon si fin[v] == -1
Afficher (v,y) est un arc de retour (aussi appel´e en arri`ere)
sinon si fin[y] < debut [v]
Afficher (v,y) est un arc transversal
sinon
Afficher (v,y) est un arc en avant
fin[v] = temps++
Correction 7 :
1a) Un parcours en profondeur
1b) Un parcours en largeur
2 C’est un parcours en profondeur, donc a priori c’est une solution au a).
Le premier probl`eme c’est que s’il y a plusieurs composantes connexes dans le graphe, on
risque de prendre un sommet dans une mauvaise composante et passer `a cˆot´e d’un circuit.
Pour prendre ¸ca en compte, il suffit de v´erifier s’il reste des sommets non trait´es avant de
conclure qu’il n’y a pas de circuit.
Un probl`eme plus s´erieux est illustr´e en faisant tourner l’algo sur le graphe de la figure . Si
on a que deux marquages l’arc transversale peut ˆetre pris pour un arc de retour donnant un
faux circuit.
Solutions :
Une solution vient du th´eor`eme suivant :
Th´eor`eme 1 Dans un graphe orient´e il existe un circuit si et seulement si dans chaque
parcours en profondeur il existe un arc de retour.
Donc la solution consiste `a faire un parcours en profondeur et afficher un circuit et terminer
d`es qu’on trouve un arc de retour. Si pas d’arc de retour alors pas de circuit. Cela donne
l’algorithme suivant :
Variables Globales:
bool´een couleur[V] initialise `a blanc
sommets p`ere[V] initialise `a null
Variables locales sommet v
bool´een trouver = faux
pour tout sommet v faire{
si( couleur[v] == blanc && ( trouver = cherche_circuit(v) )
break //sortir de la boucle pour si trouv´e
}
si( !trouver )
afficher ‘‘pas de circuit’’
*****************************************
bool´een cherche_circuit(sommet v){
sommet x,y
couleur[v] = gris
pour chaque sommet x tel que (v,x) un arc de G faire{
si( couleur[x] == blanc){
p`ere[x] = v
si( cherche_circuit(x) )
retourner vrai //circuit trouv´e et affich´e
//dans l’appel r´ecursif
}
sinon si( couleur[x] == gris){
//afficher le circuit
y = v
tant que (y != x) faire{
afficher y
y = p`ere[y]
}
afficher x
retourner vrai
}
}//fin pour
couleur[v] = noir
retourner faux
}
L’algorithme se termine pour les mˆeme raison que l’algorithme de parcours en profondeur
avec la mˆeme complexit´e.
Preuve du th´eor`eme. S’il y a un arc de retour (x, y) alors le chemin de yvers xdans
l’arbre de parcours et l’arc (x, y) forment le circuit.
Dans le sens inverse supposons qu’il existe un circuit dans G et que vest le premier sommet
du circuit visit´e pendant le parcours. Cela implique que
ebut[v] < d´ebut[x]
pour chaque sommet xdu circuit diff´erent de v(rappel : ebut et fin donnent les dates du
d´ebut et de la fin de traitement des sommets). Par la propri´et´e des intervalles de traitement
cela implique que
1. soit ebut[v] < d´ebut[x] < fin[x] < fin[v]
1 / 7 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !