Algorithmes de Graphes et Parcours
Algorithmes de Graphes et Parcours
et Graphes
Loïc
Hélouët
[Link]@[Link]
Plan
1.
Defini?ons
de
base
2.
Parcours
1.
en
largeur
2.
en
profondeur
3.
Arbres
couvrants
:
Kruskal
et
Prim
4. Plus
courts
chemins
5. Dijkstra
6. Bellman-‐Ford
7. Floyd
Warshall
8. Johnson
3.
Flot
Maximal
:
Ford
Fulkerson
4. Connexité
:
1. Recherche
de
cycles
:
Tiernan
2. Composantes
connexes
:
Tarjan
Defini?ons
Definition 1 : Un graphe non- orienté est un couple G=(V,E) dans lequel
V est un ensemble de sommets
E ⊆ V x V est un ensemble d arêtes
s3
s1 s3
s1
Exemple de graphe
Exemple de graphe orienté
3.5
s2
s0
2
9.1
10
Poids(s0.s1.s0.s1.s3) = 35.2
s3
s1 7
Exemple de graphe orienté et pondéré
Defini?ons
Definition 5 : Un successeur d un sommet x dans un graphe G=(V,E) (resp G=(V,A))
est un sommet y tel que (x,y) ∈ E (resp (x,y) ∈ A)
Definition 8: Un chemin hamiltonien est un chemin de G qui passe une et une seule
fois par tous ses sommets de G. G est un graphe hamiltonien s il possède
un cycle passant par tous ses sommets une et une seule fois
0 1 2 3 3.5 s2
s0
0 -1 9.1 3.5 -1
2
9.1
1 10 -1 -1 7 10
s3
2 -1 -1 -1 2 s1 7
3 -1 -1 -1 -1 Espace utilisé Θ(n2)
Représenta?on
Représentation par liste
d adjacence s2
s0
0 1 2
s3
1 0 1 s1
2 2 3
Marque:tableau[1..n] de booleens
M[s] := vrai
Pour j dans 1.. Degré(s) faire
v:= jeme successeur de s
Si M[v]=faux alors prof(v,G,M) finsi
finpour
Parcours
(Version matricielle)
M[s] := vrai
Pour j dans 1..n faire
si G[s,j]=vrai et M[j]=faux alors
prof(j,G,M)
finsi
finpour
Parcours
3
1 8 1
9
1 6
3 7
4 1
2
s 3
4 2
1 2
1 2
5 1
1
1
Parcours
Parcours en largeur d abord
7
1 9 1
3
1 8
3 6 1
4
s 2 3
2 4
1 2
1 2
5 1
1
1
Parcours
Algorithmes de base
Lequel choisir ?
n E ⊆ E
W= ∑ M [i, j]
i , j∈E '
Arbres
couvrants
4
9
Arbre
couvrant
minimal
:
1
4
9
5
6
2
G
:
graphe
4
7
3
n connexe
2
9
3
n valué
8
10
n non
orienté
9
9
Trouver
un
ensemble
d arrêtes:
9
8
18
n
connectant
tous
les
sommets
n
de
poids
minimal
Variables :
Arbres
couvrants
Algorithme
de
Prim
(suite)
T := graphe_vide!
M := ensemble_vide !
Pour i= 0 jusqu'à N Faire !
!d[i] := coût(s, i, G) /* ∝ si pas d arc */!
!closer[i] := s !
!M := Ajouter (i,M) !
Fin pour !
!
M := Supprimer (s,M) /* s = sommet de départ */!
!
Tant que M <> Ensemble_vide Faire !
!m := Choisir_min(M,d)!
!M := Supprimer (m,M) !
!z := closer[m] !
!v := coût (m,z,G) !
!T := Ajout arête <m,z> de coût v à T !
!Pour tout y successeur de m dans G !
! !Si y∈M et (cout(m,y,G) < d[y]) alors !
! ! !d[y] := coût(m,y,G) !
! ! !closer[y] := m !
! !Fin Si !
!Fin Pour !
Fin Tant que!
4
9
1
4
9
5
6
2
4
7
3
3
2
9
8
10
9
9
9
8
18
4
9
1
4
9
5
6
2
4
7
3
3
2
9
8
10
9
9
9
8
18
4
9
1
4
9
5
6
2
4
7
3
3
2
9
8
10
9
9
9
8
18
4
9
1
4
9
5
6
2
4
7
3
3
2
9
8
10
9
9
9
8
18
Etc…
Arbres
couvrants
Prim fonctionne par parcours de l arbre en choisissant
les poids minimum
Utilisation d un tableau
sinon
pour k dans 1 à n faire
si comp[k].repr = j1 alors comp[k].repr:=j2
finpour
comp[j2].card := comp[j2].card + comp[j1].card
finsi
Arbres
Couvrants
Algorithme de Kruskal
Procedure Kruskal (Graphe G, Graphe T)
/* S = sommets de G */
/* cout : fonction de cout des arcs */
2
4
9
9
7 7
4
4 9
5
6
2
8
4
7
3
3
3
9
1
3 8
10
10
9
9
5
9
8
18
T=
6
2 3
4
9
9
7 7
4
3 9
5
6
8
4
7
3
3
3
9
1
3 8
10
10
9
9
5
9
8
4
18
T=
6
2 3
4
9
9
7 7
4
3 9
5
6
8
4
7
3
3
9
1
3 8
10
8
9
8
9
5
9
8
4
10
18
T=
6
2 3
Arbres
couvrants
Fonctionnement : par union de composantes connexes
Remarques :
n Kruskall marche sur des graphes non connexes et calcule alors
une forêt couvrante minimale
n La structure T calculée n est pas connexe à chaque étape, même dans
un graphe connexe
Variantes
Dijkstra(G,sdeb,sfin)
Var Q : ensemble de sommets
Initialisation(G,sdeb)
4
9
2
7 1
4
4 Traiter sdeb
9
5
6
2
8
4
6 7
3
3
2
9
sdeb 3 8
10
sfin
9
9
5
9
8
18
2
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
∝
∝
∝
∝
∝
∝
Plus
court
chemin
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
∝
∝
∝
∝
∝
∝
4
9
2
7 1
4
4 Traiter s3
9
5
6
2
8
4
6 7
3
3
2
9
sdeb 3 8
10
sfin
9
9
5
9
8
18
2
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
∝
∝
∝
∝
Plus
court
chemin
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
∝
∝
∝
∝
4
9
2
7 1
4
4 Traiter s6
9
5
6
2
8
4
6 7
3
3
2
9
sdeb 3 8
10
sfin
9
9
5
9
8
18
2
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
14
∝
∝
∝
Plus
court
chemin
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
14
∝
∝
∝
4
9
2
7 1
4
4 Traiter s4
9
5
6
2
8
4
6 7
3
3
2
9
sdeb 3 8
10
sfin
9
9
5
9
8
18
2
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
8
∝
∝
∝
Plus
court
chemin
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
8
∝
∝
∝
4
9
2
7 1
4
4 Traiter s7
9
5
6
2
8
4
6 7
3
3
2
9
sdeb 3 8
10
sfin
9
9
5
9
8
18
2
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
8
13
12
∝
Plus
court
chemin
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
8
13
12
∝
4
9
2
7 1
4
4 Traiter s2
9
5
6
2
8
4
6 7
3
3
2
9
sdeb 3 8
10
sfin
9
9
5
9
8
18
2
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
8
13
12
27
Plus
court
chemin
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
8
13
12
27
4
9
2
7 1
4
4 Traiter s5
9
5
6
2
8
4
6 7
3
3
2
9
sdeb 3 8
10
sfin
9
9
5
9
8
18
2
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
8
13
12
22
Plus
court
chemin
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
8
13
12
22
4
9
2
7 1
4
4 Traiter s9
9
5
6
2
8
4
6 7
3
3
2
9
sdeb 3 8
10
sfin
9
9
5
9
8
18
2
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
8
13
12
16
Plus
court
chemin
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
8
13
12
16
4
9
2
7 1
4
4 Traiter s8
9
5
6
2
8
4
6 7
3
3
2
9
sdeb 3 8
10
sfin
9
9
5
9
8
18
2
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
8
13
12
16
Plus
court
chemin
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
8
13
12
16
4
9
2
7 1
4
4 Traiter sfin
9
5
6
2
8 …. et fin de l algorithme
4
6 7
3
3
2
9
sdeb 3 8
10
sfin
9
9
5
9
8
18
2
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
8
13
12
16
Plus
court
chemin
sdeb
2
3
4
5
6
7
8
9
sfin
0
9
3
6
12
5
8
13
12
16
A= ε /* mot vide*/
s:= sfin
A:= s. A
Tant que s<> sdeb faire
s:= predecesseur(D,s)
A:= s. A
fait
Complexité : en O(n2)
2
Plus
court
chemin
Preuve de l algorithme
Si on ajoute un sommet si, il est forcément « plus loin » de sdeb que tous les
sommets déjà explorés, et tout chemin de sdeb vers un sj déjà exploré passant
par si est de poids supérieur au d(sdeb,si) déjà connu, et donc de poids inférieur
(car tous les poids des arcs sont positifs)
Donc :
une fois un sommet étudié, sa distance ne change plus
lorsque sj est étudié après si, sj est plus loin de sdeb que si
sdeb
3
6
4
7
2
5
9
8
sfin
0
3
5
6
8
9
12
12
13
16
Plus
court
chemin
Poids[1] =0
Pour i dans 2..n faire poids[i] = ∝ finpour
retourner faux
Plus
court
chemin
Complexité en O(|V|3)
Plus
court
chemin
Algorithme de Johnson :
Si tous les poids de G sont >0, alors on peut trouver toutes les distances de
sommet à sommet en exécutant |V| fois Dijkstra
Construire G (S ,A ) avec
S =S ∪ { s }
A = A ∪ { (s,v) | v ∈ S }
w(s,v) =0
Propriété :
Soit p un chemin de v0 à vk
alors w(p) = δ(v0, vk) si et seulement si w (p) = δ (v0, vk)
Plus
court
chemin
Johnson(G)
Calculer G =(S ,A )
Si Bellman-Ford (G ,w,s) alors
afficher « Circuit négatif »
Sinon
pour chaque sommet v de G faire
h(v) = δ(s,v) /* calculé par Bellman Ford */
finpour
pour chaque arc (u,v) ∈ A faire
w (u,v) := w(u,v)+h(u)-h(v)
finpour
pour chaque sommet u ∈ S
executer Dijkstra(G,w ,u)
(donne δ (u,v) pour tout v ∈ S )
pour chaque sommet v ∈ S faire
D[u,v] := δ (u,v) + h(v) - h(u)
finpour
finpour
Plus
court
chemin
Algorithme de Johnson
Applications pratiques :
Données de l algorithme:
v( f ) = ∑ f ( s, y ) = ∑ f ( x, t )
y∈V x∈V
1 1 10
11 7
7 3
8
s 10 s 10
3 t 3 t
15 15
8
12 8 8
2 2
Flot f
Graphe G
V(f)=25
Flot
Maximal
Explication : f(u,v) >0 implique f(v,u) ≤ 0 et donc cf(v,u) = c(u,v) – f(v,u) >0
7
1 11
7 1
8 4
7
s 10 8
3 t
s 10
15 3 t
15
f(s,1)=f(1,t)=7
Algorithme (principe):
1 11
Répéter 7
8
trouver un chemin améliorant p
s 10
améliorer le flot f avec p 3 t
calculer le graphe résiduel Gf=(V,Ef) 15
Jusqu à flot stable 12 8
2
7
1 4
7
8
s 10
3 t
15
12 8
2
Flot
Maximal
Procedure Ford-Fulkerson(G,s,t)
fintantque
Flot
Maximal
7
1 11 1 4
7 7
8 8
s 10 s 10
3 t 3 t
15 15
12 8 12 8
2 2
7
7
1 4
7 1 4
8 7
10 8
s 10
3 t s
5 3 t
15
12 8 3
10 7 5
2 5 2
Flot
Maximal
7 7
1 4 1
7 4
8 7
8
s 10 10
3 t s
3 t
5 15 15
7 5
3 7
5 5 3
2 2
10
1
7 1
5
3
s V(f)= 25
3 t
10 15
4 8
12 2
Flot
Maximal
fintantque
Connexité
Un graphe non-orienté G=(V,E) est dit connexe s il existe un chemin de
tout sommet x à tout autre sommet y
Un graphe orienté G=(V,A) est dit connexe s il existe un chemin de tout sommet x
à tout autre sommet y dans le graphe G =(V,A∪A-1)
s3
s3 s1
s3 s1
s1
Connexité
Algorithme de Warshall
Complexité en O(|V|3)
Connexité
Algorithme de Tiernan : detection de cycles élémentaires
4 Cycle élémentaire :
cycle qui ne passe pas deux fois
0
2 par un sommet (à l exception du sommet
de départ/fin du cycle)
Initialisation
P:=0 ; H:= ∅N ;
/* H : tableau 1..N d ensemble d entiers
/* k ∈ H[i] if k has been considered as a successor of i */
k:=1
P[1]:=1 /* P = current path */
Algorithme de Tiernan
Complexité :
Principe :
9
7
4
8
6
0
3
10
5
2
Composantes
connexes
9
7
4
8
6
0
3
10
5
2
Composantes
connexes
9
7
4
8
6
0
3
10
5
2
Composantes
connexes
On a:
n chaque Gi est fortement connexe
n chaque Gi est maximal
Composantes
connexes
fin de fonction
fonction parcours(G: graphe, num:entier, sommet v, P: pile , partition : liste)
[Link] := num
[Link] := num
num := num + 1
[Link](v)
parcours(G,num,w,P,partition)
[Link] := min([Link], [Link])
10 11 12
10 11 12 10
10
13
13 11
Composantes
connexes
Résumé :
Attention cependant :
Application pratique :
tournée d un visiteur commercial, qui doit revenir
dans sa ville de départ après avoir visité des clients dans
chaque ville.
Problème NP-complet
G=(V,E)
Problème NP-complet