Chap 4-Graphes
Chap 4-Graphes
Chap 4-Graphes
Plan
1. Introduction aux graphes
2. Définitions
3. Représentation des graphes
4. Parcours des graphes
5. Problème des chemins optimaux
x3 x2
2. Définitions
x1
2.1 Graphes orientés (Directed Graphs)
x4 x5
- Un graphe 𝑮 est un couple (𝑿, 𝑼) où :
𝑋 est un ensemble {𝑥1 , … , 𝑥𝑛 } de nœuds ou sommets.
𝑈 = {𝑢1 , 𝑢2 , … , 𝑢𝑚 } est une famille de couples ordonnées de sommets appelées arcs.
- Un graphe est dit valué s’il une application 𝐶 : 𝑈 → 𝑅, associant à chaque arc 𝑢 un réel 𝑐𝑢 .
- Chaque arc 𝑢 = (𝑥, 𝑦) a deux extrémités appelées initiale (𝑥) et terminale (𝑦). 𝑢 est dit incident
intérieurement à 𝑥 et incident extérieurement à 𝑦.
- Dans un arc de la forme (𝑥, 𝑦), 𝑥 est appelé prédécesseur de 𝑦 et 𝑦 est dit successeur de 𝑥.
𝑥 et 𝑦 sont appelés sommets voisins (ou adjacents).
- L’ensemble des successeurs de 𝑥 est noté 𝛤(𝑥) et celui de ses prédécesseurs est noté 𝛤 − (𝑥).
- Le nombre de successeurs de 𝑥 est appelé demi degré extérieur et est noté 𝑑𝐺+ (𝑥) = |𝛤(𝑥)|.
Le demi degré intérieur de 𝑥 est défini comme étant 𝑑𝐺− (𝑥) = |𝛤 − (𝑥)|. Le degré de 𝑥 est défini
comme suit : 𝑑𝐺 (𝑥) = 𝑑𝐺+ (𝑥) + 𝑑𝐺− (𝑥).
- La densité d’un graphe est définie par le rapport 𝒎/𝒏² c'est-à-dire le nombre actuel d’arcs de 𝐺
divisé par le nombre maximum d’arcs que peut avoir 𝐺. La plupart des graphes rencontrés en
pratique ne sont pas très dense (à faible densité). Ils sont appelés creux (en Anglais sparse).
2.3 Parcours
- On appelle chemin 𝜇 de longueur 𝑝 toute suite de 𝑝 arcs (𝑢1 , … , 𝑢𝑝 ) telle que l’extrémité initiale
de 𝑢𝑖 est égale à l’extrémité terminale de 𝑢𝑖−1 ∀ 𝑖 > 1, et l’extrémité terminale de 𝑢𝑖 est égale à
l’extrémité initiale de 𝑢𝑖+1 ∀ 𝑖 < 𝑝.
- Un arc est un chemin de longueur 1 et une boucle est un circuit de longueur 1 aussi.
- Si le graphe est non orienté, on parle de chaine au lieu de chemin, et de cycle au lieu de circuit.
- Un graphe est dit complet si toute paire de sommets est connectée par un arc ou une arête.
Un graphe valué 𝐺 = (𝑋, 𝑈, 𝑊) peut être représenté par une matrice 𝑊 (𝑛 × 𝑛) qui donne à la fois les
coûts des arcs et fait fonction de la matrice d’adjacence. Les matrices d’adjacence permettent de
détecter les boucles, la symétrie ainsi que la connectivité. On peut facilement à l’aide de cette structure
de données obtenir la liste des successeurs d’un sommet ainsi que celle de ses prédécesseurs.
Cependant, ces structures ne sont pas adéquates pour les graphes dont la densité est faible.
Exemple : Le graphe donné en exemple à la section 2.1. est représenté par la matrice d’adjacence M :
𝑥1 𝑥2 𝑥3 𝑥4 𝑥5
𝑥1 0 0 0 0 0
𝑥2 1 0 1 0 0
𝑥3 0 0 1 1 0
𝑥4 0 0 1 0 1
𝑥5 0 0 0 0 0
a. Listes Contigües
Les listes d’adjacence implémentent la structure 𝐺 = (𝑋, 𝛤) où les sommets sont rangés
consécutivement dans des tableaux ou bien dans des listes chaînées. Dans le cas des tableaux, on note
par Succ le tableau dont les éléments sont les listes des successeurs des sommets 0,1, … , 𝑛 − 1 dans
l’ordre, c'est-à-dire 𝛤(0), 𝛤(1), … , 𝛤(𝑛 − 1). Le nombre d’éléments de Succ est donc le nombre d’arcs
du graphe à savoir 𝑚. Pour délimiter ces listes successives des successeurs, on fait usage d’une structure
Tête sous forme de tableau à 𝑛 éléments, qui donne pour chaque sommet l’indice dans le tableau Succ
où commence ses successeurs. En effet, les successeurs d’un sommet 𝑦 sont rangés dans Succ de
Tete[y] à Tete[y+1]-1. Dans le cas où un sommet 𝑦 n’a pas de successeurs, on pose Tete[y]=Tete[y+1].
Les graphes non orientés sont codés comme des graphes orientés symétriques. Si [𝑥, 𝑦] est une arête, 𝑥
apparaît dans la liste des successeurs de 𝑦, et 𝑦 dans celle de 𝑥. Dans le cas d’un graphe valué 𝐺 =
(𝑋, 𝑈, 𝑊), on fait usage d’un tableau de poids W en regard du tableau Succ.
1 2 3 4 5 6
1 1 3 5 7 7 Tete
1 3 3 4 3 5 Succ
1 2 3 4 5 6
b. Listes Chaînées
Le même principe peut être appliqué en utilisant des listes chaînées comme suit :
Tete
1 null
2 1 3 null
3 3 4 null
4 3 5 null
5 null
Là aussi, il y a lieu d’ajouter pour chaque bloc une case supplémentaire dans le cas de graphe valué pour
stocker le poids de l’arc.
Algorithme :
Marquer s ; Enfiler(F,s)
Repeter …………………………………………………………………………………………………………………N
x = Defiler(F)
pour tout successeur y non marqué de x ……………………………d+(i) = M
Enfiler(F,y)
Marquer y
Finpour
Jusqu’à FileVide(F)
Algorithme :
Marquer s ; Empiler(P,s)
Repeter
Tant qu’il y a un successeur y à TetePile(P) et non marqué faire
Marquer y
Empiler(P,y)
Fintq
x = Depiler(P)
Jusqu’à PileVide(P)
c. Exemple
Soit un graphe G orienté, dont les sommets sont (s1, s2, s3, s4, s5, s6) représenté par la matrice
d’adjacence suivante. Donner les ordres de parcours en largeur BFS et en profondeur DFS, à partir du
sommet s1.
0 1 1 0 0 1
1 1 0 1 1 0
1 0 0 1 1 0
𝐴=
0 1 1 1 0 1
0 1 1 0 0 1
[0 0 0 1 1 1]
BFS :
s5
s6 s4 s5
File
s3 s6 s4 s5 File
s1 s2 s3 s6 s4 s5 Vide
Sommets Marqués s1 s2,s3,s6 s4,s5
DFS :
s6
s5 s5 s5
Pile s3 s3 s3 s3 s3
s4 s4 s4 s4 s4 s4 s4
s2 s2 s2 s2 s2 s2 s2 s2 s2 Pile
s1 s1 s1 s1 s1 s1 s1 s1 s1 s1 s1 Vide
Sommets Marqués s1 s2 s4 s3 s5 s6
Dans cette section, on s’intéressera au second problème en calculant pour chaque sommet 𝑥 la valeur
du plus court chemin du sommet de départ vers 𝑥 ; V[x], appelée aussi étiquette ou label.
Il existe une famille d’algorithmes qui calculent V[x] d’une manière définitive pour chaque sommet 𝑥.
Ces algorithmes sont appelés à fixation d’étiquettes et le plus répandu de cette classe est l’algorithme
de Dijkstra. D’autres algorithmes affinent jusqu'à la dernière itération l’étiquette de chaque sommet x.
Cette classe est appelée à correction d’étiquettes. Il y a lieu de distinguer les cas suivants :
- Cas 𝑊 constante. Le problème se réduit à celui de la recherche des chemins contenant le plus
petit nombre d’arcs qui peut être résolu par une exploration en largeur.
- Cas 𝑊 ≥ 0. Le problème peut être résolu par l’algorithme de Dijkstra qui est du type à fixation
d’étiquettes et dont la complexité est 𝑂(𝑛²). Il existe une implémentation en structure de tas
dont la complexité est 𝑂(𝑛 𝑙𝑜𝑔 𝑛) .
Les applications des problèmes des chemins optimaux sont nombreuses et diverses. Dans le domaine
des transports, par exemple, on s’intéresse aux chemins optimaux d’une ville 𝑥 à une autre ville 𝑦. Dans
le routage du trafic réseau, on parle des protocoles OSPF (open shortest path first).
Algorithme de Dijkstra
s : sommet de départ
Initialiser le tableau V à +∞ //Valeur des plus court chemins
Initialiser le tableau P à 0 //Détail des chemins (Path)
V[s]=O
P[s]=s
Répéter
// Chercher sommet non fixé de V minimal
Vmin=+
Pour i=1 à n faire
Si (i non fixé et V[i]<Vmin) alors x=i; Vmin=V[i] fsi
Finpour
Si Vmin<+
Fixer x
// Mise à jour des successeurs
Pour chaque successeur y de x faire
Si V[x]+W[x][y] < V[y]
V[y] = V[x]+W[x][y];
P[y] = x
Fsi
Finpour
Fsi
Jusqu’à Vmin=+
La complexité de l’algorithme de Dijkstra dans le pire des cas est 𝑂(𝑛²). Elle peut être améliorée en
O(nlogn) en utilisant un tas pour représenter le tableau V.
Exemple : Soit le graphe orienté valué représenté par la figure suivante. Dérouler l’algorithme de
Dijkstra en prenant comme sommet de départ 1.
Tableau V (Values)
Sommets
1 2 3 4 5 6
Marqués
0 ∞ ∞ ∞ ∞ ∞ 1
4 1 2 ∞ ∞ 3
4 2 5 7 4
4 5 7 2
5 7 5
6 6
Résultat
0 4 1 2 5 6
Final
Tableau P (Paths)
1 2 3 4 5 6
1 0 0 0 0 0
1 1 1 3 3
5