Les graphes

Bibliographie

Ce résumé de cours est basé essentiellement sur le

DIU - EIL

22 mars 2021

Paul Sabatier Toulouse

Représentation d'un graphe

Un peu de vocabulaire

Un graphe non orienté est un couple ( X , E ) où X est un ensemble fini de sommets et E un ensemble de paires { x, y } de deux éléments de X appelées arêtes.

Un graphe orienté est un couple ( X , E ) où X est un ensemble fini de sommets et E un ensemble de couples ( x, y ) d'éléments de X appelées arcs.

G 1 = { X = {1, 2, 3, 4, 5},E = {{1, 5}, {2, 1}, {2, 4}, {3, 2}, {4, 3}, {5, 2}, {5, 4}}}

noter l'utilisation d'accolades

G 2 = { X = {1, 2, 3, 4, 5},E = {(1, 5), (2, 1), (2, 4), (3, 2), (4, 3), (5, 2), (5, 4)}}

noter l'utilisation de parenthèses dans ce cas

On peut également utiliser la représentation sagittale , elle n'est pas unique , sur cet exemple , 8 sommets et 12 arêtes.

Représentation par matrice d'adjacence

ExemplePour un graphe non orienté

Avec deux exemples, cela doit-être suffisant pour la compréhension ..

Représentation par les listes d'adjacence

ExempleEncore deux exemples : orienté et non orienté

En python, on parlerai de liste de liste pour cette représentation .., remarquer la notation entre crochets

Parcourir un graphe

Pourquoi ?

Une application bien connue des graphes est par exemple de trouver le plus court chemin entre deux points (application par exemple) aux échanges de données entre réseau informatiques.

On peut facilement élargir la notion de "plus court chemin" à :

  • plus long / rapide en temps

  • plus ou moins cher en coût (péages)

Dans ce cas, on parle de graphes pondérés

Par exemple, dans ce cas, il y a un coût à chaque liaison, et on peut chercher le moins 'cher', pour aller de 0 à 4 :

  • 0 -> 2 -> 4 : coût 16

  • 0->1->3->4 : coût 13

On utilise généralement deux types de parcours de graphe .

Parcours en largeur

DéfinitionMéthode

Le parcours en largeur est un parcours  "prudent". On part d'un sommet X, on commence par visiter tous les voisins de X , puis les voisins des voisins et ainsi de suite

ExempleUn exemple

Retrouver le ressource complète ici :

En partant du sommet G, étape par étape, on grise au fur et a mesures les sommets visités et on propose le résultat sous forme de liste en python :

[G,B,H,A,F,E,D,C]

Parcours en profondeur

DéfinitionMéthode

Le parcours en profondeur consiste, à partir d'un sommet donné, à suivre un chemin le plus loin possible, sans passer deux fois par le même sommet. Quand on rencontre un sommet déjà visité, on fait marche arrière pour revenir au sommet précédent et explorer les chemins ignorés précédemment.

ExempleExemple

Si on l'exemple précédent , un parcours possible serait en partant de G :

[G,H,F,C,E,D,A,B]

Programmation autour d'un graphe

Comment définir un graphe et l'utiliser dans un programme

En python, on utilisera un dictionnaire avec une liste d'adjacence

M={

"A":{"B","D"},

"B":{"A","F","G","H"},

"C":{"E","F"},

"D":{"A","E"},

"E":{"C","D","F","H"},

"F":{"B","C","E","H"},

"G":{"B","H"},

"H":{"B","E","F","G"}

}

AttentionQuelles fonctions utiliser ?

Comme tous les langages utilisés, python dispose d'un grand nombre fonctions , il faut bien faire attention à celles que l'on autorise ou pas !

Cela va dépendre des connaissances que et savoir faire que l'on désire tester.

le nombre de sommets

Fonctions dictionnaires autorisées

Ici, autorise uniquement le parcours par clefs /valeurs

1
ledico = {'a':0,'b':1,'c':2,'d':3,'e':4,'d':5}
2
3
#parcours clefs/valeurs
4
for key, value in ledico.items():
5
		print (key, value)
6
7
#parcours par clefs
8
for key in ledico:
9
		print (key)
ExempleEn utilisant uniquement parcours par clefs/valeurs ou par clefs , écrire une fonction nbs qui prenne en argument un dictionnaire et retourne le nombre de sommets

Compléter le listing ci-dessous :

1
M={"A":["B","D"],
2
    "B":["A","F","G","H"],
3
    "C":["E","F"],
4
    "D":["A","E"],
5
    "E":["C","D","F","H"],
6
    "F":["B","C","E","H"],
7
    "G":["B","H"],
8
    "H":["B","E","F","G"]
9
   }
10
ExempleRecherche du nombre d'arêtes

En utilisant uniquement :

  • parcours par clefs/valeurs ou par clefs ,

  • En utilisant la fonction len(L) qui donne la longueur d'une liste

écrire une fonction nba qui prenne en argument un dictionnaire et retourne le nombre d'arêtes, le graphe est non orienté et présenté sous forme d'un dictionnaire ou chaque clef est un sommet et sa valeur la liste au sens python des sommets adjacents.

1
M={"A":["B","D"],
2
    "B":["A","F","G","H"],
3
    "C":["E","F"],
4
    "D":["A","E"],
5
    "E":["C","D","F","H"],
6
    "F":["B","C","E","H"],
7
    "G":["B","H"],
8
    "H":["B","E","F","G"]
9
   }
ExempleDe la définition par liste d'adjacence à la matrice d'adjacence.

On part  toujours du même graphe M, écrire la fonction ToMatrice qui prend en argument le dictionnaire M et retourne la matrice d'adjacence A en partant du code ci-dessous

La matrice d'adjacence doit être affichée proprement .

1
M={"A":["B","D"],
2
    "B":["A","F","G","H"],
3
    "C":["E","F"],
4
    "D":["A","E"],
5
    "E":["C","D","F","H"],
6
    "F":["B","C","E","H"],
7
    "G":["B","H"],
8
    "H":["B","E","F","G"]
9
   }
10
11
taille = len(M)
12
13
def pos(Lettre):
14
	Liste = ["A","B","C","D","E","F","G","H"]
15
	return Liste.index(Lettre)
16
17
18
def CreeMatriceCarree(m):
19
	M = []
20
	for i in range(m):
21
		L = []
22
		for j in range(m):
23
			L.append(0) 
24
		M.append(L)
25
	return  M
26
	
27
28
def AfficheMatriceCarre(Mat):
29
	for Elt in Mat :
30
		for i in range(len(Mat)):
31
			print(Elt[i],end=" ")
32
		print()
33
34
35
36
AfficheMatriceCarre(CreeMatriceCarree(taille))
37
38
def CreeMatriceCarree(m):
39
	M = []
40
	for i in range(m):
41
		L = []
42
		for j in range(m):
43
			L.append(0) 
44
		M.append(L)
45
	return  M
46
	
47
48
def AfficheMatriceCarre(Mat):
49
	for Elt in Mat :
50
		for i in range(len(Mat)):
51
			print(Elt[i],end=" ")
52
		print()
53
54
55
56
AfficheMatriceCarre(CreeMatriceCarree(taille))

Exemple structure d'une matrice