• Aucun résultat trouvé

Structures de données relationnelles : les graphes 1. Présentation

N/A
N/A
Protected

Academic year: 2022

Partager "Structures de données relationnelles : les graphes 1. Présentation"

Copied!
5
0
0

Texte intégral

(1)

Structures de données relationnelles : les graphes 1. Présentation

Source : http://spikedmath.com/382.html

Les arbres font partie de la grande famille des graphes. Plus précisément, un arbre est un « graphe acyclique orienté possédant une seule racine tel que tous les nœuds sauf la racine ont un unique prédécesseur (parent) ».

Quelques exemples de graphes

F A

B E

C D

A E

B C D

Exemple 1 - Graphe G1 non orienté simple Exemple 2 - Graphe G2 non orienté, deux boucles, un sommet isolé

10

5 14

2 8

11 18

A

D 300 280

B 150 C 310

80 E

110 F

60

70 90 G 260 H

50 190

100 I 40

Exemple 3 - Graphe G3 orienté Exemple 4 - Graphe G4 non orienté pondéré

Vocabulaire

Les nœuds d’un graphe sont aussi appelés sommets. Un nœud contient une donnée (ou étiquette).

Une arête relie deux sommets, qui sont alors voisins ou adjacents.

Les arêtes peuvent être orientées. Le graphe est alors orienté et les arêtes sont appelées arcs. On dit que l’arc (x, y) part du sommet x et arrive au sommet y.

(2)

Dans un graphe pondéré, chaque arête porte une valuation, aussi appelée poids ou coût.

Une boucle est une arête reliant un sommet à lui-même.

Des arêtes multiples sont deux arêtes, ou plus, qui joignent les mêmes sommets.

Dans un graphe non orienté et non pondéré, le degré d’un sommet est le nombre d’arêtes incidentes à ce sommet, c’est-à-dire ayant ce sommet pour extrémités, les boucles étant comptées deux fois. Dans un graphe pondéré, on ajoute les poids des arêtes, et dans un graphe orienté, on distingue le degré entrant du degré sortant.

Un sommet de degré zéro est dit isolé.

Dans un graphe orienté, l’ensemble des successeurs d’un sommet x est l’ensemble des sommets y tels qu’il existe un arc allant de x vers y. L’ensemble des prédécesseurs d’un sommet x est

l’ensemble des sommets y tels qu’il existe un arc allant de y vers x.

Un graphe simple est un graphe ne contenant ni boucle, ni arêtes multiples.

Un chemin est une succession de sommets reliés par des arêtes, ou des arcs.

Un cycle est un chemin dont les deux extrémités sont identiques et passant par des arêtes toutes distinctes. Ainsi, si A et B sont reliés par une seule arête (non orientée), A-B-A n’est pas un cycle.

Application

Les graphes sont utilisés :

• pour représenter une relation entre un ensemble d’objets homogènes : réseaux routiers, réseaux électriques, Internet, réseaux sociaux…

• dans des algorithmes : recherche du plus court chemin (protocole de routage ou GPS routier), ordonnancement de tâches …

2. Définitions

Rappel - Notations mathématiques

Étant donné deux éléments distincts x et y,

• la paire {x, y} est l’ensemble contenant x et y, sans ordre, utilisé par exemple pour des solutions d’équations : {2 ; 3} = {3 ; 2} ;

• le couple (x, y) est la liste ordonnée (x, y) utilisée par exemple pour des coordonnées : (2 ; 3) ≠ (3 ; 2).

Définitions

Un graphe est un couple (S, A) dans lequel :

S est un ensemble {s1, s2, …, sn} de sommets

A est un ensemble {a1, a2, …, am} d’arêtes reliant ces sommets

Dans un graphe non orienté, les arêtes sont des paires de sommets : chaque arête ai s’écrit sous la forme {x, y} avec x, y ∈ S.

Dans un graphe orienté, les arêtes, généralement appelées arcs, sont des couples de sommets : chaque arc ai s’écrit (x, y) avec x, y ∈ S.

Dans un graphe non orienté pondéré, une arête va être sous la forme ({x, y}, p) avec x, y des sommets et p un nombre.

Remarque : On utilise aussi (V, E) au lieu de (S, A) pour Vertex et Edge.

(3)

Exemple

Graphe de l’exemple 2 : V2 = {A, B, C, D, E} et E2 = {{A, A}, {A, B}, {A, C}, {B, C}, {B, D}, {C, D}, {D, D}}

Exercice

1. Écrire les ensembles V et E correspondant aux graphes des exemples 1 et 3.

2. Représenter le graphe décrit par les ensembles V et E : V = {A, B, C, D, E, F}

E = {(A, B), (A, C), (B, C), (B, E), (C, A), (C, D), (D, A), (D, E), (E, F), (F, D)}

3. Représentation en machine

On trouve principalement deux représentations des graphes en machine. La matrice d’adjacence utilise les tableaux à deux dimensions ; la liste des successeurs utilise les dictionnaires.

Exemples

Graphe G1 - dictionnaire G1 = {A : [B, C],

B : [A, C, E, F], C : [A, B, D], D : [C, E], E : [B, D, F], F : [B, E]}

Graphe G1 - matrice d’adjacence On numérote les sommets dans l’ordre alphabétique.

⎜⎜

0 1 1 0 0 0 1 0 1 0 1 1 1 1 0 1 0 0 0 0 1 0 1 0 0 1 0 1 0 1 0 1 0 0 1 0⎠

⎟⎟

Le 1 ligne 4 colonne 3 signifie qu’une arête relie le sommet 4 (D) au sommet 3 (C).

Liste des successeurs Matrice d’adjacence

Un dictionnaire de listes permet de représenter le graphe.

Les clés du dictionnaire sont les sommets ; la valeur associée à un sommet est la liste des successeurs de ce sommet. On peut aussi utiliser la liste de prédécesseurs.

Ces deux listes sont identiques dans un graphe non orienté : liste des voisins.

Dans le cas d’un graphe pondéré, les listes sont remplacées par des dictionnaires. Le graphe est alors un dictionnaire de

dictionnaires : le dictionnaire de successeurs a pour clés les étiquettes des sommets successeurs et pour valeurs les valuations des arêtes associées.

Les sommets sont numérotés de 0 à n – 1.

Les arêtes sont représentées par une matrice M, un tableau 2D.

Un coefficient non nul ligne i colonne j correspond à un arc ou une arête allant du sommet i vers le sommet j.

Ce coefficient vaut 0 ou 1, ou est égal à la valuation de l’arête dans le cas d’un graphe pondéré.

Avec un graphe non orienté, ce tableau est symétrique : M[i, j] = M[j, i].

Les étiquettes des sommets peuvent être données dans une liste. Le graphe est alors le couple (lst_sommets, matrice_adjacence).

(4)

Graphe G3 - dictionnaire Avec liste des successeurs

G3 = {2 : [11, 18], 5 : [8], 8 : [2, 14], 10 : [5, 14], 11 : [], 14 : [8, 18], 18 : [11, 14]}

Avec liste des prédécesseurs G3 = {2 : [8], 5 : [10], 8 : [5, 14],

10 : [], 11 : [2, 18], 14 : [8, 10, 18], 18 : [2, 14]}

Graphe G3 - matrice d’adjacence

Les étiquettes des sommets sont dans une liste : [2, 5, 8, 10, 11, 14, 18].

⎜⎜

⎜⎛

0 0 0 0 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 1 0⎠

⎟⎟

⎟⎞

Graphe G4 - dictionnaire

G4 = {A : {B : 300, C : 310, D : 280}, B : {A : 300, C : 80},

C : {A : 310, B : 80, E : 150}, D : {A : 280, {F : 110},

E : {C : 150, F : 60, G : 90, H : 190}, F : {D : 110, E : 60, G : 70, H : 260}, G : {E : 90, F : 70, H : 50, I : 100}, H : {E : 190, F : 260, G : 50, I : 40}, I : {G : 100, H : 40}}

Graphe G4 - matrice d’adjacence Sommets : [A, B, C, D, E, F, G, H, I]

0 300 310 280 0 0 0 0 0

300 0 80 0 0 0 0 0 0

310 80 0 150 0 0 0 0 0

280 0 0 0 0 110 0 0 0

0 0 150 0 0 60 0 190 0

0 0 0 110 60 0 70 260 0

0 0 0 0 90 70 0 50 100

0 0 0 0 190 260 50 0 40

0 0 0 0 0 0 100 40 0

Complexité

Dans un graphe G à n sommets et m arêtes, la complexité en mémoire est en O(n2) avec une matrice d’adjacence et en O(m + n) avec une liste de successeurs.

La complexité en temps dépend aussi de la représentation. Tester si un sommet est isolé est immédiat avec une liste de successeurs et en O(n) avec une matrice d’adjacence. Tester si deux sommets sont adjacents est immédiat avec la matrice d’adjacence, mais nécessite un parcours d’une liste de successeurs avec la représentation par dictionnaire de listes.

4. Interface et implémentation

On peut travailler sur les graphes directement avec les fonctions et opérateurs des tableaux ou des dictionnaires, ou écrire des fonctions spécifiques :

• creer_graphe(s : liste de Sommets) -> Graphe: renvoie le graphe (S, Δ) où Δ est une liste vide d’arêtes

• ajouter_arete(g : Graphe, s1 : Sommet, s2 : Somme) -> graphe: à partir du graphe g = (S, A) et de deux sommets s1 et s2 appartenant à S renvoie le graphe (S, A ∪ {(s1, s2)})

• sommets(g : Graphe) -> liste de Sommets : à partir du graphe (S, A) renvoie S

• voisins(g : Graphe, s : Sommets) -> liste de Sommets: renvoie la liste des sommets voisins de s dans le graphe g. Cette fonction est remplacée par une fonction successeurs et/ou predecesseurs dans le cas d’un graphe orienté.

(5)

On peut rajouter : ajouter_sommet, supprimer_sommet, sont_adjacents, supprimer_arete, retourner_valeur_sommet, fixer_valeur_sommet et, dans le cas d’un graphe pondéré, retourner_valeur_arete et fixer_valeur_arete.

Implémentation objet

L’utilisation d’une classe graphe permet d’encapsuler dans un même objet la liste des sommets avec leurs valeurs, la matrice d’adjacence, et d’intégrer les méthodes les plus utiles (voisins…).

Remarques

R1 - Dans l’implémentation de gauche, les sommets sont désignés par leurs étiquettes (ou valeurs). À droite, ils sont désignés par leurs indices dans la liste sommets. On peut désigner les sommets par leurs étiquettes en modifiant les méthodes ajouter_arete et voisins :

def ajouter_arete(self, s1, s2):

i = self.sommets.index(s1) j = self.sommets.index(s2) self.aretes[i][j] = 1

self.aretes[j][i] = 1

def voisins(self, s):

i = self.sommets.index(s)

return [sommets[j] for j in range(self.n) if self.aretes[i][j] == 1]

R2 - On peut créer une classe sommet (éventuellement arête) pour attribuer des propriétés supplémentaires à ces objets : couleur d’un sommet, statut « visité » lors d’un parcours…

R3 - Choix du nom sommets pour le dictionnaire des sommets discutable : self._sommets, self.graphe ou self.dico_graph plutôt ? puis sommets au lieu de get_sommets ?

Liste des successeurs – Version objet Matrice d’adjacence – Version objet class Graphe:

"Graphe orienté non pondéré"

def __init__(self, sommets):

self.sommets = {s: [] for s in sommets}

self.n = len(sommets) def ajouter_arc(self, s1, s2):

self.sommets[s1].append(s2) def get_sommets(self):

return list(self.sommets.keys()) def successeurs(self, s):

return self.sommets[s]

class Graphe:

"Graphe non orienté non pondéré"

def __init__(self, sommets):

self.sommets = [s for s in sommets]

self.n = n = len(sommets)

self.aretes = [[0]*n for i in range(n)]

def ajouter_arete(self, s1, s2):

self.aretes[s1][s2] = 1 self.aretes[s2][s1] = 1 def get_sommets(self):

return self.sommets def voisins(self, s):

return [v for v in range(self.n) if self.aretes[s][v] == 1]

Références

Documents relatifs

Si deux angles alternes-internes ont même mesure, alors les droites qu’ils forment sont parallèles. Deux angles correspondants formés par deux parallèles ont

On utilise les trois représentations classiques des graphes : dessin, tableau de successeurs (prédécesseurs si indiqué, voisins si graphe non orienté), matrice d’adjacence.. Donner

Si on utilise une pile pour S, les sommets enregistrés en dernier vont être visités en premier : on parcourt le graphe en visitant à chaque fois un voisin du dernier sommet, sauf

Cette structure de données existe officiellement, mais en terminale on peut se contenter de l’implémenter avec une liste, et la trier à chaque itération (ce

Les parcours en profondeur et en largeur permettent de déterminer l’existence d’un chemin entre deux sommets, il suffit que les deux sommets soient dans la liste du parcours..

ainsi qu'un chemin entre deux sommets d'un graphe non pondéré d onné sous forme de liste de

LaBRI - Universit´ e de Bordeaux 351 cours de la lib´ eration, 33405 Talence, France..

cations préuniformément continues correspondant de deux structures catégoriques, dont l’une admet pour ensemble des unités l’ensemble des. applications uniformément