Académique Documents
Professionnel Documents
Culture Documents
1) Origines
Graphe :
Un graphe G est défini par G=(S,A), où S est un ensemble de sommets et A l’ensemble d'arcs (ou arêtes) ; Un arc
(ou arête) est un couple de sommets, donc, un élément du produit cartésien SxS
Exemple
S={1, 2, 3, 4}
A={ {1, 2} , {1,3} , {1,4} , {2,4} , {3,4} }
Si les arêtes ne sont pas orientées, on parle d’un graphe non orienté. Dans le cas contraire on parle d’un graphe
orienté et les arêtes sont appelées aussi les arcs.
Exemple
Graphe non orienté Graphe orienté
S={1, 2, 3, 4} S={1, 2, 3, 4}
A={ {1, 2} , {1,3} , {1,4} , {2,4} , {3,4} } A={(1, 2) , (1,3), (1,4) , (2,4) ,(3,4)}
Un graphe pondéré est défini par le triplet (S, A, C) où : S est l’ensemble des sommets, A est l’ensemble des
arrêtes (ou arcs), et C est la fonction de coût de A dans IR. Par convention Ca représente le coût ou le poids de
l’arc (ou de l’arête) a (distance entre 2 villes, temps du trajet…).
3) Terminologies
Boucle : est un arc qui part d’un sommet vers le même sommet
Chaîne : Une chaine de longueur n est une suite de n arêtes qui relient un sommet i à un autre j ou à lui-
même.
Cycle : Un cycle est une chaine qui permet de partir d’un sommet et revenir à ce sommet en parcourant
une et une seule fois les autres sommets.
Exemple :
Dans le graphe ci-contre,
A – B – C – D – E est une chaîne de longueur 4.
B – C – D – E – B est un cycle de longueur 4.
Chaine hamiltonienne : est une chaine qui passe par tous les sommets une et
une seule fois.
Cycle eulérien : si le sommet de départ d’une chaine eulérienne est celui d’arrivé on parle de cycle
eulérienne
Cycle hamiltonien : c’est un cycle passant une seule fois par tous les sommets d’un graphe et revenant au
sommet de départ.
Chaine eulérienne : e– b– d– e– c– a– b– c– d
Chaine hamiltonienne : d – e– c – b– a
Pas de cycle eulérien
Cycle hamilotnien : d – e – b – a – c – d
Graphe eulérien : Un graphe admettant un cycle eulérien est dit Graphe eulérien
Graphe hamiltonien: Un graphe admettant un cycle hamiltonien est dit Graphe hamiltonien
Graphe Connexe : Un graphe connexe est un graphe dont tout couple de sommets peut être relie par une
chaine de longueur n>=1.
Graphe Connexe Graphe non connexe
4) Théorèmes d’Euler
Théorème 1:
Un graphe connexe G admet un cycle eulérien si et seulement si tous ses sommets sont de degré pair.
Théorème 2:
Un graphe connexe G admet une chaîne eulérienne distincte d'un cycle si et seulement si le nombre de sommets
de G de degré impair est égal à 2.
Dans ce cas, si A et B sont les deux sommets de G de degré impair, alors le graphe G admet une chaîne eulérienne
d'extrémités A et B.
Exemple :
Dans le graphe ci-contre, tous les sommets sont de degré pair sauf B et C.
Ce graphe admet donc bien une chaîne eulérienne.
Un graphe peut être implémenté de différentes manières selon le langage utilisé. En Python en peut représenter
un graphe à l’aide d’un dictionnaire ou à l’aide d’une matrice d’adjacence.
Exemple :
G={ G=[
1 : [2,5] , [0, 1, 0, 0, 1, 0],
2 : [1,3,5] , [1, 0, 1, 0, 1, 0],
3 : [2,4] , [0, 1, 0, 1, 0, 0],
4 : [3,5,6] , [0, 0, 1, 0, 1, 1],
5 : [1,2,4] , [1, 1, 0, 1, 0, 0],
6 : [4] [0, 0, 0, 1, 0, 0]
} ]
Exercice 3:
Soit un graphe non orienté et non pondéré de matrice d’adjacence G.
Ecrire les fonctions suivantes :
1- degre(G,i) : qui retourne le degré d’un sommet ayant l’indice i
2- nombreArcs(G) qui retourne le nombre d’arcs.
3- cycleEulerien(G) : qui retourne True si le graphe admet un cycle eulérien, False sinon.
4- chaineEulerienne(G): qui retourne True si le graphe admet une chaine eulérienne, False
sinon
5- chaineEulerienne2(G) : qui retourne une liste ayant les indices des extrémités de la chaine
eulérienne si elle existe. None sinon
C
I
B F Le parcours en profondeur de ce graphe :
A
A, B, C, F, D, H, I, G, E
D
H
E
G
def parcoursDFS(G,i,T) :
P=[i] #initialiser une pile P
C=[] #liste à retourner
while P!=[] :
n=P.pop()
if T[n]==0 :
C+=[n]
T[n]=1 #marquer le noeud comme visité
succ= succNonvisite(G, n,T)
succ.reverse()
for x in succ : P.append(x)
return C
La fonction parcoursDFS peur être récursive :
def DFSRecursif(G,i,T) :
T[i]= 1 #marquer le noeud comme visité
succ=succNonvisite(G, i ,T)
for x in succ:
if T[x]==0: return [i]+ DFSRecursif(G,x,T)
return [i]
parcoursProfondeur(G) : fonction qui lance le parcours, elle faire appel à la fonction parcoursDFS.
succNonVisite(G,i,T) : retourne la liste des successeurs de sommet d’indice i non visités.
C
I
B F Le parcours en largeur de ce graphe :
A
A, B, D, E, C, G, F, H, I
D
H
E
G
En python :
def ParcoursEnlargeur(G) :
def BFS(G,i,T) :
T=[0]*len(G) #marquer non visités F=[i] #initialiser la file
C=[] #liste à retourner
L=[] #liste à retourner
while F !=[ ] :
for i in range(len(G)) : n=F.pop(0) #défiler
if T[n]==0 :
if T[i]==0:
T[n]=1
L+=BFS(G,i,T) C+=[n]
succ= succNonvisite(G,n,T)
return L
F+= succ
return C
Il existe de nombreux algorithmes déterminant un ou le plus court chemin dans un graphe connexe pondéré.
Par exemple: Warshall, Floyd, Dijkstra, Branch and Bound, Bellman-Ford, A star
On se limitera à la recherche d'un plus court chemin entre deux sommets du graphe pondéré avec des poids
positifs en utilisant la matrice d’adjacence pour représenter le graphe.
Algorithme de dijkstra
E. W. Dijkstra (1930-2002) a proposé en 1959 un algorithme qui permet de déterminer le plus court chemin entre
deux sommets d'un graphe connexe pondéré (orienté ou non) dont le poids lié aux arêtes est positif ou nul.
Exemple
2
Le graphe ci-contre représente le réseau A D
routier d'une région qui prend en compte
7
le sens de la circulation, chaque arc 5 2
1 4
représente une route à sens unique dont
le poids est la distance en kilomètre 3 1
entre deux sommets. Quel est l'itinéraire E B G S
le plus court qui relie E à S ? 4
2
1 3 6
Principe de l'algorithme de Dijkstra
2
L'algorithme dû à Dijkstra est basé sur le C F
principe suivant :
Si le plus court chemin reliant E à S passe par les sommets s1 , s2 , …, sk alors, les différentes étapes sont aussi les
plus courts chemins reliant E aux différents sommets s1 , s2 , …, sk.
Initialisation de l'algorithme :
Étape 1 : On affecte le poids 0 au sommet origine (E) et on attribue provisoirement un poids ∞ aux autres
sommets.
Répéter les opérations suivantes tant que le sommet de sortie (S) n'est pas affecté d'un poids définitif.
Étape 2 : Parmi les sommets dont le poids n'est pas définitivement fixé choisir le sommet X de poids p minimal.
Marquer définitivement ce sommet X affecté du poids p(X).
Étape 3 : Pour tous les sommets Y qui ne sont pas définitivement marqués, adjacents au dernier sommet fixé X :
Le plus court chemin de E à S s'obtient en écrivant de gauche à droite le parcours en partant de la fin S.
Pour faciliter la recherche du plus court chemin il est commode de présenter les résultats dans un tableau :
10 (F) S
9 D 7
A E
6
5 4
2 2
3
8 2 9 J
I G H
3 1 5
6 3 4
7 8
B C F
I A B C D E F G H J Sommet sélectionné
0 ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞
Sachant que la fonction minD(D,C)retourne l’indice du sommet de C ayant la petite valeur dans D. c.à.d. le
sommet prochain ayant une distance minimale avec le sommet du départ.
def minD(D,C) :
imin = C[0]
for i in C :
if D[i] < D[imin] : imin = i
return imin
Exemple d’exécution :
35 D Gr=[ [99, 3, 12, 99, 99, 99, 99],
A [99, 99, 99, 5, 35, 99, 99],
13
3 8 [99, 99, 99, 9, 99, 15, 99],
5
[99, 99, 99, 99, 8, 10, 99],
E C S
10 [99, 99, 99, 99, 99, 99, 13],
12 9 14 [99, 99, 99, 99, 99, 99, 14],
B 15 [99, 99, 99, 99, 99, 99, 99]
F
]
>>>dijkstra(Gr,0)
([0, 0, 0, 1, 3, 3, 4] , [0, 3, 12, 8, 16, 18, 29]) # La chaîne la plus courte de poids 29 se lit à l’envers en partant du sommet 6
Gr=[[99, 3, 12, 99, 99, 99, 99], chemin plus court : ['E', 'A', 'C', 'D', 'S']
[99, 99, 99, 5, 35, 99, 99],
cout = 29
[99, 99, 99, 9, 99, 15, 99],
[99, 99, 99, 99, 8, 10, 99],
[99, 99, 99, 99, 99, 99, 13],
[99, 99, 99, 99, 99, 99, 14],
[99, 99, 99, 99, 99, 99, 99]
]
sommets=['E', 'A','B','C', 'D','S']
chemin, cout = cheminPlusCourt(sommets, Gr, 0)