Implémentation des graphes
Il existe de multiples manières de représenter un graphe, selon la nature du graphe mais aussi selon la nature des opérations que l'on souhaite effectuer sur ce graphe. Quelque soit le choix retenu, on souhaite pouvoir :
- utiliser des opérations de construction du graphe. Il faut pouvoir ajouter/supprimer des sommets, des arcs…
- utiliser des opérations de parcours du graphe : parcourir la liste des sommets, des arcs, ou bien des arcs issus d'un sommet donné…
On commence dans un premier temps par implémenter les graphes orientés. On ne considérera que les \(1\)-graphes, c'est à dire les graphes dans lesquelles l'arc \((u, v) \in S^2\) est présent une fois au plus.
Matrices d'adjacence¶
Les sommets du graphe sont les nombres \(0, 1, \ldots, n - 1\), pour un certain entier \(n\in \mathbb{N}\). On représente le graphe à l'aide d'une matrice adj de taille \(n \times n\) (un tableau constitué de \(n\) lignes et \(n\) colonnes). Il existe un arc entre les sommets \(i\) et \(j\) du graphe si et seulement si adj[i][j] vaut True.


Matrice d'adjacence adj de \(G_1\).
On donne ci-dessous le code python du constructeur de la classe Graphe.
class Graphe:bksl-nl """ Un graphe représenté par une matrice d'adjacence.bksl-nl Les sommets sont les nombres 0, 1, ..., n - 1. """bksl-nl def py-undpy-undinitpy-undpy-und(self, n):bksl-nl self.n = nbksl-nl self.adj = [[False]py-strn for py-und in range(n)]bksl-nlbksl-nl def ajouterpy-undsommet(self):bksl-nl """ Graphe -> Nonetypebksl-nl Ajoute un sommet au graphe """bksl-nl passbksl-nlbksl-nl def ajouterpy-undarc(self, source, destination):bksl-nl """ Graphe, int, int -> intbksl-nl Ajoute l'arc source -> destination """bksl-nl passbksl-nlbksl-nl def supprimerpy-undsommet(self, i):bksl-nl """ Graphe, int -> Nonetypebksl-nl Supprime le sommet i du graphe. Les sommets j > i sont renommés en j - 1. """bksl-nl passbksl-nlbksl-nl def supprimerpy-undarc(self, source, destination):bksl-nl """ Graphe, int, int -> Nonetypebksl-nl Supprime l'arc source -> destination """bksl-nl passbksl-nlbksl-nl def estpy-undvoisin(self, source, destination):bksl-nl """ Graphe, int, int -> boolbksl-nl Détermine si source et destination sont voisins """bksl-nl passbksl-nlbksl-nl def sommets(self):bksl-nl """ Graphe -> [int]bksl-nl Renvoie la liste des sommets du graphe self """bksl-nl passbksl-nlbksl-nl def voisins(self, sommet):bksl-nl """ Graphe, int -> [int]bksl-nl Renvoie la liste des voisins de sommet """bksl-nl passbksl-nlbksl-nl def listepy-undarcs(self):bksl-nl """ Graphe -> [(int, int)]bksl-nl Renvoie la liste des arcs du graphe """bksl-nl passbksl-nlbksl-nl def ordre(self):bksl-nl """ Graphe -> intbksl-nl Renvoie l'ordre du graphe """bksl-nl passbksl-nlbksl-nl def taille(self):bksl-nl """ Graphe -> intbksl-nl Renvoie la taille du graphe """bksl-nl passbksl-nlbksl-nl def decrire(self):bksl-nl """ Graphe -> Nonetypebksl-nl Affiche une description du graphe self """bksl-nl passbksl-nlbksl-nl
-
-
Initialiser une variable
g1de typeGraphe, représentant un graphe constitué des 4 somments \(0\), \(1\), \(2\), et \(3\). Initialement, aucun arc n'est présent dans le grapheg1. -
Écrire une méthode
sommetsde la classeGraphequi étant donné un grapheselfrenvoie la liste des sommets qui le constituent.1 2 3 4
def sommets(self): """ Graphe -> [int] Renvoie la liste des sommets du graphe self """ pass1print(g1.sommets())[0, 1, 2, 3]
-
-
-
Écrire une méthode
ajouter_arcde la classeGraphequi étant donné deux sommetssourceetdestinationdu grapheselfajoute l'arcsource\(\to\)destinationau grapheself.1 2 3 4
def ajouter_arc(self, source, destination): """ Graphe, int, int -> Nonetype Ajoute l'arc source -> destination """ pass -
À l'aide de la méthode
ajouter_arcs, construire le grapheg1de l'énoncé.1 2
for row in g1.adj: print(row)[False, True, False, True] [False, False, False, True] [False, True, False, False] [False, False, True, False] -
Écrire une méthode
est_voisinde la classeGraphequi étant donné deux sommetssourceetdestinationdu grapheselfrenvoieTruesi et seulement si il existe un arc reliantsourceàdestinationdans le grapheself.1 2 3 4
def est_voisin(self, source, destination): """ Graphe, int, int -> bool Détermine si source et destination sont voisins """ pass1 2
print(g1.est_voisin(0, 1)) print(g1.est_voisin(1, 0))True False
-
-
-
Écrire une méthode
voisinsde la classeGraphequi étant donné unsommetdu grapheselfrenvoie la liste des voisins desommet.1 2 3 4
def voisins(self, sommet): """ Graphe, int -> [int] Renvoie la liste des voisins de sommet """ pass1 2
print(g1.voisins(0)) print(g1.voisins(1))[1, 3] [3] -
Écrire une méthode
liste_arcsde la classeGraphequi renvoie la liste des couples(source, destination)correspondants à des arcs du grapheself.1 2 3 4
def liste_arcs(self): """ Graphe -> [(int, int)] Renvoie la liste des arcs du graphe """ pass1print(g1.liste_arcs())[(0, 1), (0, 3), (1, 3), (2, 1), (3, 2)]
-
-
-
Écrire une méthode
ordrede la classeGraphequi renvoie l'ordre du graphe.Rappel. L'ordre d'un graphe est le nombre de sommets qui composent le graphe.
1 2 3 4
def ordre(self): """ Graphe -> int Renvoie l'ordre du graphe """ pass1print(g1.ordre())4 -
Écrire une méthode
taillede la classeGraphequi renvoie la taille du graphe.Rappel. La taille d'un graphe est le nombre d'arêtes qui composent le graphe.
1 2 3 4
def taille(self): """ Graphe -> int Renvoie la taille du graphe """ pass1print(g1.taille())5 -
Écrire une méthode
decrirequi affiche les informations du grapheselfsur le modèle donné ci-dessous.1 2 3 4
def decrire(self): """ Graphe -> Nonetype Affiche une description du graphe self """ pass1g1.decrire()Graphe d'ordre 4 et de taille 5 Sommet 0 -> 1 3 Sommet 1 -> 3 Sommet 2 -> 1 Sommet 3 -> 2
-
-
-
Écrire une méthode
ajouter_sommetde la classeGraphequi ajoute un sommet au graphe. Ainsi, si le graphegest constitué de \(n\) sommets, alors après l'application de la méthodeajouter_sommetle graphe est constitué de \(n + 1\) sommets (le sommet ajouté est \(n\)) : la méthodeajouter_sommetmodifiera à la fois l'attributnet l'attributadjdu grapheself. Aucun arc ne sera ajouté par cette méthode.1 2 3 4
def ajouter_sommet(self): """ Graphe -> Nonetype Ajoute un sommet au graphe """ pass1 2
g1.ajouter_sommet() g1.decrire()Graphe d'ordre 5 et de taille 5 Sommet 0 -> 1 3 Sommet 1 -> 3 Sommet 2 -> 1 Sommet 3 -> 2 Sommet 4 -> -
Écrire une méthode
supprimer_arcde la classeGraphequi supprime (si présent) l'arc reliantsourceàdestinationdans le grapheself. Cette méthode ne produira pas d'erreur dans le cas où le graphe ne contient pas l'arc(source)\(\to\)(destination).1 2 3 4
def supprimer_arc(self, source, destination): """ Graphe, int, int -> Nonetype Supprime l'arc source -> destination """ pass -
Écrire une méthode
supprimer_sommetde la classeGraphequi supprime le sommetidu grapheself. La méthodesupprimer_sommetmodifiera l'attributnet l'attributadj. Si \(j > i\) est un sommet du graphe, alors son numéro sera \(j - 1\) après application de la méthodesupprimer_sommet, les sommets \(j < i\) conserveront le même numéro.1 2 3 4
def supprimer_sommet(self, i): """ Graphe, int -> Nonetype Supprime le sommet i du graphe. Les sommets j > i sont renommés en j - 1. """ pass1 2
g1.supprimer_sommet(2) g1.decrire()Graphe d'ordre 4 et de taille 3 Sommet 0 -> 1 2 Sommet 1 -> 2 Sommet 2 -> Sommet 3 ->
-
Dictionnaire d'adjacence¶
Les sommets du graphe sont quelconques (des nombres, non forcément consécutifs, des lettres, des mots, etc). On représente un graphe à l'aide d'un dictionnaire d'adjacence, noté adj. Si \(G = (S, A)\), alors les clés du dictionnaire adj seront les éléments de \(S\). La valeur associée à la clé source sera la liste des sommets destination de telles que (source, destination) \(\in A\).
Par exemple si \(G_2\) est le graphe :

Alors le dictionnaire correspondant est :
1 2 3 4 5 6 | |
On donne ci-dessous le code python du constructeur de la classe Graphe.
class Graphe:bksl-nl """ Un graphe représenté par un dictionnaire d'adjacence. """bksl-nl def py-undpy-undinitpy-undpy-und(self, n):bksl-nl self.n = nbksl-nl self.adj = [[False]py-strn for py-und in range(n)]bksl-nlbksl-nl def ajouterpy-undsommet(self, s):bksl-nl """ Graphe, str -> Nonetypebksl-nl Ajoute le sommet s au graphe self """bksl-nl passbksl-nlbksl-nl def ajouterpy-undarc(self, source, destination):bksl-nl """ Graphe, str, str -> Nonetypebksl-nl Ajoute l'arc source -> destination au graphe self """bksl-nl passbksl-nlbksl-nl
Toutes les questions de cette partie concernent cette classe Graphe. Les sommets seront ici des chaînes de caractère.
-
-
Initialiser une variable
g2de typeGraphereprésentant un graphe initialement vide. -
Écrire une méthode
ajouter_sommetqui ajoute un sommetsau grapheself. Initialement, aucun arc ne sort du sommet ajouté. Si le sommet est déjà présent dans le graphe, alors cette méthode ne fait rien.1 2 3 4
def ajouter_sommet(self, s): """ Graphe, str -> Nonetype Ajoute le sommet s au graphe self """ pass -
Écrire une méthode
ajouter_arcde la classeGraphequi étant donné deux sommetssourceetdestinationdu grapheselfajoute l'arcsource\(\to\)destinationau grapheself.1 2 3 4
def ajouter_arc(self, source, destination): """ Graphe, str, str -> Nonetype Ajoute l'arc source -> destination au graphe self """ pass -
À l'aide des méthodes
ajouter_sommetetajouter_arc, construire le grapheg2de l'énoncé.1print(g2.adj){'A': ['B', 'C', 'D'], 'B': ['D'], 'C': ['A', 'D'], 'D': ['E'], 'E': ['F'], 'F': ['E', 'F']}
-
-
Écrire les méthodes
est_voisin,sommets,voisins,liste_arcs,ordre,taille,decrire,supprimer_arc,supprimer_sommet(dans cet ordre) de la classeGraphe(ainsi que leur signature et leur documentation).VOUS TESTEREZ VOS MÉTHODES.
1g2.decrire()Graphe d'ordre 6 et de taille 10 Sommet A -> B C D Sommet B -> D Sommet C -> A D Sommet D -> E Sommet E -> F Sommet F -> E F1 2
g2.supprimer_sommet('D') g2.decrire()Graphe d'ordre 5 et de taille 6 Sommet A -> B C Sommet B -> Sommet C -> A Sommet E -> F Sommet F -> E F
Rappels.
Si l est un objet de type list, i un indice compatible avec la taille de la liste, et e1 un élément présent dans la liste l, e2 un élément non présent dans la liste l :
l.copy()renvoie une copie indépendante dele1 in ls'évalue àTrue;e2 in ls'évalue àFalsel.pop()supprime le dernier élément de la liste,l.pop(i)supprime l'élément d'indiceide la liste.l.remove(e1)supprime la première occurrence dee1dansl;l.remove(e2)soulève une erreurl.append(e2)ajoute l'élémente2à la fin de la liste ;l.insert(i, e2)insère l'élémente2à l'indicei.enumerate(l)renvoie la liste[(i, l[i]) for i in range(len(l))]
Si d est un objet de type dict, k1 une clé présente dans le dictionnaire, v1 la valeur associée à la clé k1, k2 une clé non présente dans le dictionnaire :
d[k1]renvoiev1;d[k2]soulève une erreur ;d.get(k1)renvoiev1,d.get(k2)renvoieNone;k1 in ds'évalue àTrue;k2 in ds'évalue àFalsed.pop(k1)supprimek1dedet renvoiev1;d.pop(k2)soulève une erreur ;d.setdefault(k1, "valeur par defaut")ne fait rien cark1est déjà présent dans le dictionnaire,d.setdefault(k2, "valeur par défaut")associe àk2la valeur"valeur par défaut"d.keys()renvoie la liste des clés du dictionnaire ;d.values()renvoie la liste des valeurs du dictionnaire ;d.items()renvoie la liste des couples(clé, valeur)du dictionnaire ;
Documents¶
- Implémentation des graphes (sujet)
- Fichiers python :