PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t...

30
Graphes ? IFT2015 H2019 ? UdeM ? Mikl´ os Cs˝ ur¨ os G RAPHES : REPR ´ ESENTATION ET PARCOURS

Transcript of PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t...

Page 1: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros

GRAPHES : REPRESENTATION ET

PARCOURS

Page 2: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Graphes non-orientes

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros ii

Def. Un graphe non-oriente est represente par un couple (V, E) ou E ⊆(V2

)(paires non-ordonnees).V est l’ensemble des sommets et E est l’ensemble des aretes.

Barabasi & Oltvai Nature Rev Genet 5 :101, 2004

Page 3: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Graphes orientes

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros iii

Def. Un graphe oriente est represente par un couple (V, E) ou E ⊆ V × V

(paires ordonnees).V est l’ensemble des nœuds ou sommets, et E est l’ensemble des arcs.

Page 4: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Terminologie

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros iv

Graphe non-oriente

L’arete {u, v} est denotee par uv.Si uv ∈ E, alors v est adjacent a u.L’arete uv ∈ E est incidente aux sommets u et v.Le degre de u ∈ V est le nombre d’aretes qui y sont incidentes.

Graphe oriente

L’arc (u, v) est denotee par uv : l’arc part de u et arrive a v.Si uv ∈ E, alors v est adjacent a u.Le degre sortant de u ∈ V est le nombre d’arcs qui y partent ; le degre rentrant estle nombre d’arcs qui y arrivent.

Page 5: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Chemins

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros v

Un chemin de longueur ` est une sequence v0, v1, . . . , v` ou vi−1vi ∈ E pourtout i = 1, . . . , `.

(` = 0 est OK : chemin sans aretes.)

Si v0 = v`, alors le chemin forme un cycle.

(Plus precisement, les sommets initial et final ne sont pas distingues dans le cycle.)

Le chemin v0 · · · v` est elementaire ssi v1, . . . , v` sont distincts. Si v0 = v`,alors le chemin forme un cycle elementaire.

Un graphe sans cycle est dit acyclique.

Un graphe non-oriente est connexe si chaque paire de sommets est relie par unchemin.

Un graphe non-oriente connexe acyclique est un arbre.

Page 6: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Sous-graphes

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros vi

Le graphe G′ = (V ′, E′) est un sous-graphe de G = (V, E) ssi V ′ ⊆ V etE′ ⊆ E.

Etant donne un sous-ensemble de sommets V ′ ⊆ V , le sous-graphe de G en-

gendre par V ′ est le graphe G′ = (V ′, E′) avec E′ ={uv ∈ E : u, v ∈ V ′

}.

Page 7: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Ponderation

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros vii

Graphe pondere : chaque arc (ou arete) possede un poids ou cout associe, definipar la fonction de ponderation c : E 7→ R.

Poids d’un sous-graphe : somme de poids des arcs dans le sous-graphe

Poids d’un chemin : somme de poids des arcs dans le chemin

Page 8: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Questions interessantes

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros viii

Stocker les graphes dans le memoire d’un ordinateur

Parcours d’un graphe

Verifier si le graphe est connexe

Plus court chemins

Page 9: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Comment stocker le graphe ?

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros ix

Matrice d’adjacence : matrice V ×V , A[u, v] donne le poids de uv (±∞ ou NaN

pour arcs non-existants), ou valeurs booleennes pour noter juste presence

Listes d’adjacence : liste Adj[u] pour chaque sommet u qui stocke l’ensemble{v : uv ∈ E

}ou l’ensemble des couples

{〈v, c(u, v)〉 : uv ∈ E

}.

Usage de memoire : depend de la densite du graphe |E||V |2 .

Determiner si uv ∈ E ou c(u, v) : rapide avec la matrice mais plus lente avec leslistes d’adjacence

Page 10: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Listes d’adjacence

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros x

[Wayne & Sedgewick]

Page 11: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Sommets nommes

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xi

graphe de symboles : sommets identifies par cles uniques ∈ U

? table de symboles pour indexage de sommets : U → {0, 1 . . . , n− 1} (tableaude hachage ou ABR)

? index inverse : {0, 1 . . . , n− 1} → U (tableau de taille n)? tableau de listes d’adjacence� facile a elargir en stockant de l’information associee avec les sommets dans un tableau de taille n

Page 12: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Graphe de symboles

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xii

[Sedgewick & Wayne]

Page 13: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Rappel : parcours d’un arbre

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xiii

Un parcours visite tous les nœuds de l’arbre.? parcours prefixe (preorder traversal ) : chaque nœud est visite avant que ses

enfants soient visites.? parcours postfixe (postorder traversal ) : chaque nœud est visite apres que ses

enfants sont visites.? avec un arbre binaire, on a aussi le parcours infixe (inorder traversal ) : chaque

nœud est visite apres son enfant gauche mais avant son enfant droit.

Page 14: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Parcours avec pile

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xiv

Algo PARCOURS-PILE

1 initialiser la pile P

2 P.push(root)

3 while P 6= ∅4 x← P.pop()

5 if x 6= null then

6 «visiter» x

7 for y ∈ x.children do P.push(y)

� cela donne un parcours prefixe

Page 15: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Parcours avec queue = par niveau

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xv

Algo PARCOURS-NIVEAU

1 initialiser la queue Q

2 Q.enqueue(root)

3 while Q 6= ∅4 x← Q.dequeue()

5 if x 6= null then

6 «visiter» x

7 for y ∈ x.children do Q.enqueue(y)

� PARCOURS-NIVEAU(root) visite tous les nœuds dans l’arbre dans l’ordre de niveaux

Page 16: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Parcours de graphe

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xvi

Idee generale : suivre toujours une arete qui mene a partir d’un sommet visite a unsommet non-visite

Parcours par profondeur : choisir l’arete/arc uv ou u est visite le plus recemment(pile)

Parcours par largeur : choisir l’arete/arc uv ou u est visite le moindre recemment(queue)

Page 17: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Parcours en profondeur — DFS

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xvii

depth-first search

Technique essentielle : marquage/coloriageverte=«jamais vu», jaune=«en visite», rouge=«deja vu»

(init) parent[s]← s ; for u← 0, 1, . . . , n− 1 do couleur[u]← verteDFS(s) // parcours en profondeur a partir de sommet s

D1 couleur[s]← jaune // previsite de s

D2 for st ∈ Adj[s] do // pour tout sommet t adjacent a s

D3 if couleur[t] = verte then DFS(t) ; parent[t]← s // visite du voisin t

D4 couleur[s]← rouge // post-visite de s

� c’est generalisation du parcours prefixe ou postfixe sur les arbres

� noter qu’on colorie ici en rouge juste pour une raison didactique. Dans l’algorithme, il suffit de

marquer les sommets «visite» : vert ou jaune/rouge

Page 18: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

DFS 2

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xviii

J V

J J J

R

prochaine arête à explorer

départR

R

arêteretour

arête de liaison

sommet actif (s)

1

2 3

4

5

68

7

t

toute arete est visite deux fois (car elle est sur deux listes d’adjacence)quand on visite une arete st pour la premiere fois, la couleur du sommet t peut etreverte : si arete st et sommet t decouverts pour la premiere fois� c’est une arete de liaison

jaune : si arete st decouverte pour la premiere fois, mais t est connu� c’est une arete retour

rouge : impossible, car on a du visiter toutes les aretes adjacentes, incluant ts,avant de rougir t.

Page 19: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

DFS 3

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xix

On explore le graphe entier en lancant DFS a partir de tout sommet qui reste vert :

for s← 0, 1, . . . n− 1 do if couleur[s] = verte then DFS(s)

Theoreme. Le parcours en profondeur d’un graphe avec n sommets et m aretesfinit en temps O(n + m).

Preuve. On considere chaque arete exactement deux fois (quand on la trouve sur les deux listes

d’adjacence), et on colorie chaque sommet exactement trois fois. �

foret en profondeur : formee par les aretes de liaison parenten suivant les liaisons parent, on trouve un chemin entre un sommet quelconque vet le sommet de depart : c’est le chemin forme par les sommets jaunes quand v aete decouvert

pathTo(x) // chemin a sommet x a partir du sommet de source apres l’appel DFS(s)P1 initialiser pile vide P ; if couleur[x] = verte then return P // aucun cheminP2 y ← parent[x] ; while x 6= y do P.push(x); x← y; y ← parent[x]P3 P.push(x)P4 return P

Page 20: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Foret en profondeur

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xx

!"# $%&'(&)* +, #%-"#( *%$# of this page, which show the progress of DFS and BFS for our sample graph mediumG.txt, make plain the differ-ences between the paths that are dis-covered by the two approaches.DFS wends its way through the graph, stor-ing on the stack the points where other paths branch off; BFS sweeps through the graph, using a queue to remember the frontier of visited places. DFS ex-plores the graph by looking for new vertices far away from the start point, taking closer vertices only when dead ends are encountered; BFS completely covers the area close to the starting point, moving farther away only when everything nearby has been examined. DFS paths tend to be long and wind-ing; BFS paths are short and direct. Depending upon the application, one property or the other may be desirable (or properties of paths may be imma-terial). In .#/-%+, 0.0, we will be con-sidering other implementations of the Paths API that find paths having other specified properties.

BFS for shortest paths (250 vertices)

20%

40%

60%

80%

100%

DFS for paths (250 vertices)

20%

40%

60%

80%

100%

542 CHAPTER 4 Q Graphs

[Sedgewick & Wayne]

Page 21: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Composantes connexes

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xxi

identifier les composantes connexes dans un graphe :on veut une operation de test s’il existe un chemin entre u et v

C1 for u← 0, 1, . . . , n− 1 do marked[u]← false; id[u]← u

C2 c← 0 // compteur de composantes connexesC3 for u← 0, 1, . . . , n− 1 doC4 if (¬marked[u]) then c← c + 1; DFSCC(u, c) // une autre composante

DFSCC(s, c) // parcours en profondeur a partir de sommet s

D1 marked[s]← true; id[s]← c // previsite de s

D2 for st ∈ Adj[s] do if(¬marked[t]

)then DFSCC(t, c)

maintenant, id[u] = id[v] si et seulement si u et v appartiennent a la memecomposante (↔ il existe un chemin entre eux)

�union-find peut aussi implanter cette operation, mais au lieu d’un ordre quelconque, DFS etablit

un ordre specifique de tracer les liaisons

Page 22: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

DFS : cycles

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xxii

detection de cycles :

B1 for u← 0, 1, . . . , n− 1 do marked[u]← false

B2 cycles← false

B3 for u← 0, 1, . . . , n− 1 do

B4 if (¬marked[u]) then DFSCYC(u, u)

DFSCYC(v, u) // arete de liaison uv

D1 marked[v]← true

D2 for vw ∈ Adj[v] do

D3 if (¬marked[w]) then DFSCYC(w, v)

D4 else if w 6= u then cycles← true // on a trouve un cycle

Page 23: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

DFS : graphe biparti

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xxiii

biparti : ssi sommets coloriable par deux couleurs et aucune arete entre sommets dememe couleur

B1 for u← 0, 1, . . . , n− 1 do marked[u]← false

B2 biparti← true

B3 for u← 0, 1, . . . , n− 1 do

B4 if (¬marked[u]) then partition[u]← +1; DFSBIP(u)

DFSBIP(s) // tester si la composante connexe de s est biparti

D1 marked[s]← true

D2 for st ∈ Adj[s] do

D3 if (¬marked[t]) then // arete de liaison

D4 partition[t] = −partition[s] ; DFSBIP(t) // +1↔ −1

D5 else if partition[s] = partition[t] then biparti← false

Page 24: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Parcours en largeur - BFS

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xxiv

breadth-first search : utiliser une file FIFO (queue) Q

(init) for u← 0, 1, . . . , n− 1 do marked[u]← falseBFS(s) // parcours en largeur a partir de sommet s

B1 d[s]← 0; parent[s]← s

B2 marked[s]← true; Q.enqueue(s) ;B3 while (Q 6= ∅) doB4 u← Q.dequeue()B5 for uv ∈ Adj[u] do if (¬marked[v]) thenB6 d[v]← d[u] + 1; parent[v]← u

B7 marked[v]← true; Q.enqueue(v)

Theoreme. Le parcours en largeur prend O(n + m) temps sur un graphe de n

sommets et m aretes s’il est stocke par listes d’adjacence.

Page 25: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Plus courts chemins

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xxv

Theoreme. A la fin du parcours, d[u] est la longueur minimale d’un cheminentre s et u pour tout sommet u. On peut retracer ce plus court chemin en suivantles liaisons parent.

0 1

1 1 2

3départ

4

3

Page 26: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

DFS et BFS

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xxvi

!"# $%&'(&)* +, #%-"#( *%$# of this page, which show the progress of DFS and BFS for our sample graph mediumG.txt, make plain the differ-ences between the paths that are dis-covered by the two approaches.DFS wends its way through the graph, stor-ing on the stack the points where other paths branch off; BFS sweeps through the graph, using a queue to remember the frontier of visited places. DFS ex-plores the graph by looking for new vertices far away from the start point, taking closer vertices only when dead ends are encountered; BFS completely covers the area close to the starting point, moving farther away only when everything nearby has been examined. DFS paths tend to be long and wind-ing; BFS paths are short and direct. Depending upon the application, one property or the other may be desirable (or properties of paths may be imma-terial). In .#/-%+, 0.0, we will be con-sidering other implementations of the Paths API that find paths having other specified properties.

BFS for shortest paths (250 vertices)

20%

40%

60%

80%

100%

DFS for paths (250 vertices)

20%

40%

60%

80%

100%

542 CHAPTER 4 Q Graphs

!"# $%&'(&)* +, #%-"#( *%$# of this page, which show the progress of DFS and BFS for our sample graph mediumG.txt, make plain the differ-ences between the paths that are dis-covered by the two approaches.DFS wends its way through the graph, stor-ing on the stack the points where other paths branch off; BFS sweeps through the graph, using a queue to remember the frontier of visited places. DFS ex-plores the graph by looking for new vertices far away from the start point, taking closer vertices only when dead ends are encountered; BFS completely covers the area close to the starting point, moving farther away only when everything nearby has been examined. DFS paths tend to be long and wind-ing; BFS paths are short and direct. Depending upon the application, one property or the other may be desirable (or properties of paths may be imma-terial). In .#/-%+, 0.0, we will be con-sidering other implementations of the Paths API that find paths having other specified properties.

BFS for shortest paths (250 vertices)

20%

40%

60%

80%

100%

DFS for paths (250 vertices)

20%

40%

60%

80%

100%

542 CHAPTER 4 Q Graphs

Page 27: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Parcours de graphe oriente

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xxvii

Liste d’adjacence = liste d’arcs sortants

Memes techniques algorithmiques : DFS et BFS sans changement

exemple : DFS trouve les sommets accessibles→ ramasse-miette

because DFS is fundamentally a digraph-processing algorithm, with one representation of each edge. Following this trace is a worthwhile way to help cement your understand-ing of depth-first search in digraphs.

Mark-and-sweep garbage collection. An im-portant application of multiple-source reach-ability is found in typical memory-management systems, including many implementations of Java. A digraph where each vertex represents an object and each edge represents a reference to an object is an appropriate model for the memory usage of a running Java program. At any point in the execution of a program, certain objects are known to be directly accessible, and any object not reachable from that set of objects can be returned to available memory. A mark-and-sweep garbage collection strategy reserves one bit per object for the purpose of garbage collection, then periodically marks the set of potentially accessible objects by running a di-graph reachability algorithm like DirectedDFSand sweeps through all objects, collecting the unmarked ones for use for new objects.

Finding paths in digraphs. DepthFirstPaths (Algorithm 4.1 on page 536) and BreadthFirstPaths (Algorithm 4.2 on page 540) are also fundamentally digraph-processing algorithms. Again, the identical APIs and code (with Graph changed to Digraph) effectively solve the following problems:

Single-source directed paths. Given a digraph and a source vertex s, support queries of the form Is there a directed path from s to a given target vertex v? If so, find such a path.

Single-source shortest directed paths. Given a digraph and a source vertex s, support queries of the form Is there a directed path from s to a given target vertex v? If so, find a shortest such path (one with a minimal number of edges).

On the booksite and in the exercises at the end of this section, we refer to these solu-tions as DepthFirstDirectedPaths and BreadthFirstDirectedPaths, respectively.

Garbage collection scenario

directlyaccessibleobjects

potentially accessible

objects

objects available

for collection

5734.2 Q Directed Graphs

Page 28: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Tri topologique

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xxviii

Probleme de tri topologique, ou ordonnancement de taches :On a une liste de taches X , avec des contraintes captures par l’ordre partiel «x

doit etre complete avant y», denote par x 4 y. On veut trouver un arrangementsequentiel qui assure que x est complete avant y quand x 4 y.

⇒ abstraction : graphe oriente acyclique (antisymetrie + transitivite = aucun cycleoriente)

on veut alors permutation de sommets telle que pour tout arc uv, u se trouveavant v dans la permutation

Page 29: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Tri topologique avec DFS

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xxix

(init) parent[s]← s ; for u← 0, 1, . . . , n− 1 do couleur[u]← verteDFS(s) // parcours en profondeur a partir de sommet s

D1 couleur[s]← jaune // previsite de s

D2 for st ∈ Adj[s] do // pour tout sommet t adjacent a s

D3 if couleur[t] = verte then DFS(t) ; parent[t]← s // visite du voisin t

D4 couleur[s]← rouge // post-visite de s

l’ordre des nœuds a post-visite : quand on appelle DFS(s), pour tout arc st :? si t est verte, alors DFS(t) va etre execute avant que DFS(s) finit? si t est rouge, alors DFS(t) a ete deja execute? si t est jaune, on a un probleme : chemin t→ s existe (chaıne d’appels recursifs)⇒ le graphe n’est pas acylique⇒ l’ordre post-visite est l’inverse de l’ordre souhaite

Page 30: PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t adjacent `a s D3 if couleur[t] = verte then DFS(t); parent[t] s // visite du voisin

Tri topologique 2

Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xxx

T1 for u← 0, 1, . . . , n− 1 do marked[u]← falseT2 for u← 0, 1, . . . , n− 1 do if (¬marked[u]) then DFSTOPO(u)

DFSTOPO(s) // parcours en profondeur a partir de sommet s

D1 marked[s]← true ; for st ∈ Adj[s] do if (¬marked[t]) then DFSTOPO(t) ;D2 P.push(s)

A la fin, P.pop defile dans l’ordre topologique.