ALGO1 – Parcours en profondeur
Fran¸cois Schwarzentruber February 7, 2021
1 Parcours en profondeur g´ en´ erique dans un arbre
pre : un sommetsd’un arbre proc´edureexplorer(s)
pr´evisite(s)
pour tsuccesseur desfaire explorer(t)
postvisite(s) explorer(racine)
+
1 × 42
2 3
2 Repr´ esentations d’un graphe explicite
A
B
C
D
E
F
Matrice d’adjacence
A→ B→ C→ D→ E→ F →
A B C D E F
↓ ↓ ↓ ↓ ↓ ↓
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
Listes d’adjacence A→
B→ C→ D→ E→ F →
3 Algorithme g´ en´ erique
pre : un graphe orient´eG
proc´edureparcoursProfondeur(G) pour s∈S faire
vu[s] :=faux pour s∈S faire
sivu[s] =fauxalors explorer(s)
pre : un grapheGet un sommetsnon visit´e proc´edure explorer(G,s)
vu[s] :=vrai pr´evisite(s)
pour t successeur desfaire si vu[t] =fauxalors
explorer(G, t) postvisite(s)
pre : un sommets proc´edure pr´evisite(s)
pre[s] :=temps temps:=temps+1 pre : un sommets proc´edure postvisite(s)
post[s] :=temps temps:=temps+1
D´efinition 1 On appelle parcours en profondeur de G l’un des parcours de parcoursProfondeur(G).
A
B
C
D
E
F
A
B
C
D
E
F Th´eor`eme 2 SoitG= (S, A) un graphe. Un parcours en profondeur surGtermine.
Th´eor`eme 3
• SiGest repr´esent´e par une matrice d’adjacence, un parcours en profondeur surGcoˆuteO(|S|2) op´erations.
• SiGest repr´esent´e par des listes d’adjacence. un parcours en profondeur surGcoˆuteO(|S|+|A|) op´erations.
D´emonstration. Regardons la complexit´e lorsqueGest repr´esent´e par des listes d’adjacence. La boucle principale du parcours s’ex´ecuteO(|S|) fois. Pour tout sommet s, l’appelexplorer(s) n’est effectivement ex´ecut´e qu’une fois. Un appelexplorer(s) requiert| {t∈S, s→t}
| {z }
Es
|op´erations, propre `a l’appel. On a donc une complexit´e deO(Ps∈S|Es|) =O(|A|) pour tout le calcul dans les appels explorer(...).
D’o`u une complexit´e totale enO(|S|+|A|).
4 Classification des arcs
Notation 4 Pour tout sommets, on note[s]sl’intervalle [pre[s], post[s]].
Proposition 5 (th´eor`eme des parenth`eses)
Soientsett deux sommets. Les intervalles[s]set [t]tsont soit disjoints, ou alors l’un est inclus dans l’autre.
D´emonstration. Soits6=ttel quepre[s]< pre[t]. L’appel explorer(G, s) se fait donc avant explorer(G, t) :
• Soit l’appel de explorer(G, t) se fait lors de l’appel de explorer(G, s) : [s[t]t]s
• Soit l’appel de explorer (G, t) se fait apr`es la fin de l’appel de explorer(G, s) : [s]s[t]t
D´efinition 6 Consid´erons un parcours en profondeur d’un grapheG.
Un arcs→t deGest... quand dans la forˆet d’un parcours en profondeur... intervalles appelant explorer(s) appelle directementexplorer(t) [s[t]t]s
avant test un ancˆetre non p`ere des [s[t]t]s
arri`ere sest un descendant det [t[s]s]t
transverse tous les autres cas [t]t[s]s
Lemme 7 Soitu6=v deux sommets.
explorer(v) est appel´e alors que l’appel de explorer(u) est en cours ssi, au moment o`u u est d´ecouvert, il existe un chemin deu`a v compos´e uniquement de sommets non vus.
D´emonstration.
(⇒) explorer(u) appelleexplorer(u1) qui appelle . . . qui appelleexplorer(v) donc pour tout i,vu[ui] =faux et le cheminu→u1→ · · · →v convient.
(⇐) Supposons qu’il existe un chemin u → u1 → · · · → v compos´e de sommets non vus au moment o`u u est d´ecouvert.
Soitile plus petit indice tel queexplorer(ui) soit non appel´e. Pendant l’appelexplorer(ui−1),vu[ui] =faux etui−1→ui existe doncexplorer(ui) est appel´e. Contradiction.
5 D´ etection de cycles
D´efinition 8 Un cycle est un chemin de longueur non nullev0→v1→. . . vk →v0, aveck≥1.
D´efinition 9 (Probl`eme de d´etection de cycles)
• Entr´ee : un grapheG;
• Sortie : oui, ssi le grapheGposs`ede un cycle.
Proposition 10 Un graphe orient´e contient un cycle ssi un parcours en profondeur poss`ede un arc arri`ere.
D´emonstration.
(⇐) Si u → v est un arc arri`ere, alors explorer(G, v) appelle explorer(G, v1), qui appelle explorer(G, v2), . . . qui a appel´e explorer(G, u), qui a test´e vu[v] = true car u→ v. Donc le graphe contient le cycle suivant v→v1→v2→ · · · →u→v.
(⇒) R´eciproquement, supposons qu’il y a un cyclev0→ · · · →vk →v0. Consid´erons un parcours en profondeur et montrons qu’il y a un arc arri`ere. Soitil’indice tel quevi soit le premier sommet explor´e parmi les sommets du cycle. Il existe un chemin devi `a vi−1compos´e de sommets non vus.
D’apr`es le lemme 7, explorer(vi−1) est appel´e alors que l’appelexplorer(vi) est encore en cours. Quand vi−1 est explor´e, on avu[vi] =vrai doncvi−1→vi est un arc arri`ere.
6 Tri topologique
Exemple 11 Le savant cosinus.
D´efinition 12 (probl`eme du tri topologique)
• Entr´ee : un grapheGacyclique ;
• Sortie : une extension lin´eaire6`, i.e. 6` est un ordre total tel que six→y dansGimpliquex6`y.
Supposons (s→t). Dans un parcours, il n’y a pas d’arcs arri`eres, carGacyclique, voici les possibilit´es :
• s→test un arc appelant/avant : [s[t]t]s
• s→test un arc transverse : [t]t[s]s
Dans tous les cas, post[s]> post[t].
v s
w
q t
x
y r
u
valeurs post[.] ´elev´ees valeurs post[.] faibles Algorithme du tri topologique
• r´ealiser un parcours en profondeur.
• lire l’extension lin´eaire6` comme l’ordre d´ecroissant des valeurs depost[s] : x6`y ssipost[x]≥post[y]
Th´eor`eme 13 L’algorithme du tri topologique est correct.
D´emonstration. Car il n’y a pas d’arcs arri`ere.
7 Composantes fortement connexes
7.1 D´ efinitions
SoitG= (S, A) un graphe orient´e (pas forc´ement acyclique). On d´efinit la relationsurSpar pour toutu, v∈S, uv ssi il existe un chemin deu`a vet de v `au.
Proposition 14 est une relation d’´equivalence.
D´efinition 15 (composante fortement connexe) Une composante fortement connexe est une classe d’´equivalence de.
Exemple 16
v s
w
q t
x z
y r
u
D´efinition 17 (graphe quotient) On appelle graphe quotient deGle grapheG|= (S0, A0) o`u
• S0 est l’ensemble des composantes fortement connexes deGet
• A0 l’ensemble des arˆetes (C, D) tel queC6=D et il existex, y∈CDavecx→G y.
Proposition 18 G| est acyclique.
D´emonstration. Absurde.
Exemple 1 Le graphe quotient du graphe ci-dessus est : {s, v, w} {q, t, y}
{x, z}
{r}
{u}
Morale : un graphe est un graphe acyclique de ses composantes fortement connexes.
7.2 Algorithme de Kosaraju
D´efinition 19 (Probl`eme du calcul des composantes fortement connexes)
• Entr´ee : un graphe orient´eG= (S, A);
• Sortie : l’ensemble des composantes fortement connexes deG.
D´efinition 20 (graphe inverse) Soit G= (S, A) un graphe. On appelle graphe inverse de G, le graphe Gt = (St, At) d´efini parSt=S etAt={(y, x),(x, y)∈A}.
Exemple 21
v s
w
q t
x z
y r
u v
s w
q t
x z
y r
u Algorithme de Kosaraju
1. r´ealiser un premier parcours en profondeur surG
⇒obtenir la listeL les sommets deGtri´ee par ordre d´ecroissant des valeurspost1[.] ;
2. r´ealiser un second parcours en profondeur surGt avec la boucle principal parcourant les sommets dans l’ordre donn´e parL.
Th´eor`eme 22 On peut impl´ementer l’algorithme de Kosaraju en O(|S|+|A|) .
Th´eor`eme 23 Les conposantes fortement connexes sont les arbres du deuxi`eme parcours de l’algorithme de Kosaraju.
D´emonstration.
Etape 1: le´ 1er parcours ressemble `a un tri topologique sur le graphe quotient de G.
SoitU ⊆S non vide. On pose :
• post1(U) = max
s∈U post1[s], ie l’instant `a partir duquel on a fini l’exploration deU. Lemme 24 SoitC etC0 deux composantes fortement connexes.
C→G|C0 implique post1(C)> post1(C0).
D´emonstration.
Soitule premier sommet visit´e deC∪C0.
• Siu∈C, alorspost1(C) =post1[u].
x y
u
C C0
En effet :
– post1(C)≥post1[u] par d´efinition;
– Pour toutv∈C, il existe un chemin deu`avet lors de l’exploration deu, tous les sommets du chemins sont non vus. Doncexplorer(G, v) a lieu lors de l’appel deexplorer(G, u). Doncpost1(v)≤post1[u]. En pas-
sant au maximum,
post1(C) ≤ post1[u].
Pour touts∈C0,post1[s]< post1[u] car de la mˆeme fa¸con, il existe un chemin deu`asavec des sommets non vus, et doncexplorer(G, s) a lieu lors de l’appel de explorer(G, u). Doncpost1(C0)< post1[u] =post1(C).
• Si par contreu∈C0, alors on apost1(C0) =post1[u].
x y u
C C0
un’appelle pas de sommets deC car il n’y a pas d’arcs qui relieC0 `a C. Ainsi pour tout s∈C, post1[s]>
post1[u]. Doncpost1(C)> post1(C0).
Etape 2: les arbres du second parcours sont les CFC.´ Montrons par r´ecurrence que pour toutk, la propri´et´ePk qui dit
leskpremiers arbres obtenus pas le 2`eme parcours
sont des composantes fortement connexes deG.
• P0 est vraie : il n’y a pas d’arbres !
• Soitkstrictement plus petit que le nombre de composantes fortement connexes. SupposonsPk et montrons Pk+1. Le second parcours choisit le sommetxnon vus avec post1[x] maximal. NotonsCx la CFC contenant xet Axl’arbre issu dexdans le second parcours.
– Cx⊆Ax Quand l’exploration de xcommence, aucun sommet de Cx n’est vu (sinon, parPk, la CFC Cx aurait d´ej`a ´et´e trait´e).
Ainsi, siy ∈Cx, il y a un chemin de sommets non vus dex`a y. La fonction explorer(x) appelle tous lesexplorer(y) doncy∈Ax.
Cx
Ax
– Ax⊆Cx Par l’absurde, supposons qu’il existey ∈Ax\Cx. Alors explorer(x) appelle indirectement explorer(y) donc il existe un chemin dex`a y dansGt. Dans ce chemin, on notes le premier sommet qui sort deCx. Soitv∈Cx le pr´ed´ecesseur desdans ce chemin.
Cx
Ax
x ...
v
s . . . y Cs
Dans G, on a s → v donc post1(Cs) > post1(Cx) avec Cs la CFC de s. Comme s est non vu, par Pk, la classe Cs est int´egralement non vu. Soit z le nœud (non vu) tel quepost1(z) = post1(Cs). On a,post1(z)> post1(Cx) = post1(x). Contradiction avec le fait que xest non vu tel que post1(x) soit maximal. DoncAx⊆Cx.
DoncAx=Cxet Pk+1 est vraie.
Par r´ecurrence, on a montr´e Pk pour tout k entre 0 et le nombre de composantes fortement connexes. En particulier, sikest ´egal au nombre de composantes fortement connexes, on aPk.
8 Backtracking : force brute
8.1 Recherche d’une solution
pre : une s´equence de choixsdans un arbre de d´ecision post : une solution qui ´etendss’il en existe une,
ou impossible proc´eduresolution(s)
sisest une solutionretourner s pour tout choixc pour ´etendresfaire
s0 := solution(s.c)
sis0 6= impossiblealorss0 retourner impossible
solution()
Th´eor`eme 25 Soitaest l’arit´e ethla hauteur de l’arbre de d´ecision.
• La complexit´e temporelle est enO(ah) .
• La complexit´e spatiale est enO(h) .
8.2 Jeu ` a deux joueurs
pre : une positionsd’un arbre de jeu, un joueuri
post : vrai si le joueuriqui joue en sa une strat´egie gagnante proc´edurestrategieGagnante?(s,i)
sisest une position gagnante pour le joueuriretourner vrai sisest une position perdante pour le joueuriretourner faux pour tout coup des→tfaire
sistrategieGagnante?(t,¬i) est fauxalors retourner vrai
retourner faux strategieGagnante?( ,×)
Notes bibliographiques
Selon [CLRS09], on utilise le parcours en profondeur depuis 1950 en intelligence artificielle. C’est dans [HT73]
que Hopcroft et Tarjan font l’´eloge du parcours en profondeur et l’utilisation de la repr´esentation d’un graphe avec des listes d’adjacence. Knuth est le premier `a donner un algorithme lin´eaire pour le tri topologique [Knu68].
Tarjan [Tar72] donne un algorithme en temps lin´eaire pour le calcul des composantes fortement connexe, mais son algorithme est difficile `a expliquer. Une l´egende raconte que Kosaraju a invent´e son algorithme pr´esent´e ici, car plus simple `a expliquer et enseigner, tout en ayant une impl´ementation en temps lin´eaire. L’algorithme de Kosaraju est pr´esent´e dans [CLRS09] et [DPV08].
References
[CLRS09] Thomas H Cormen, Charles E Leiserson, Ronald L Rivest, and Clifford Stein.Introduction to algorithms.
MIT press, 2009.
[DPV08] Sanjoy Dasgupta, Christos H. Papadimitriou, and Umesh V. Vazirani. Algorithms. McGraw-Hill, 2008.
[HT73] John E. Hopcroft and Robert Endre Tarjan. Efficient algorithms for graph manipulation [H] (algorithm 447). Commun. ACM, 16(6):372–378, 1973.
[Knu68] Donald Ervin Knuth.The art of computer programming, Volume I: Fundamental Algorithms, 3rd Edition.
Addison-Wesley, 1997 (first edition in 1968).
[Tar72] Robert Endre Tarjan. Depth-first search and linear graph algorithms. SIAM J. Comput., 1(2):146–160, 1972.