PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t...
Transcript of PARCOURS · D1 couleur[s] jaune // previsite de´ s D2 for st 2Adj[s] do // pour tout sommet t...
Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros
GRAPHES : REPRESENTATION ET
PARCOURS
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
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.
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.
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.
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 ′
}.
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
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
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
Listes d’adjacence
Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros x
[Wayne & Sedgewick]
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
Graphe de symboles
Graphes ? IFT2015 H2019 ? UdeM ? Miklos Csuros xii
[Sedgewick & Wayne]
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.
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
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
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)
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
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.
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
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]
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
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
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
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.
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
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
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
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
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
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.