Plusieurs modes de représentation peuvent être implémentés pour stocker des graphes : matrices d’adjacence (ou sommet-sommet), listes des voisins, des successeurs ou des prédécesseurs. Lors de cette séance nous allons écrire les classes réalisant ces implémentations.
Matrice sommet-sommet
Écrire le code de la classe GrapheM qui implémente une matrice sommet-sommet.
La spécification du constructeur de la classe est :
1
2
3
4
def__init__(self:GrapheM,mat:List[List[int]])->None:"""
Constructeur de la classe.
"""
Remarque : cette classe possède l’attribut mat qui référence la matrice d’adjacence.
Solution
1
2
3
4
5
6
7
8
9
10
classGrapheM:"""
Implémentation de la représentation
matricielle d'un graphe.
"""def__init__(self:GrapheM,mat:List[List[int]])->None:"""
Constructeur de la classe.
"""self.mat=mat
Ajouter à la classe GrapheM une redéfinition de la méthode spéciale __str__ de façon à ce qu’un appel à la fonction print avec comme argument un objet représentant un graphe donne un affichage qui rappelle celui d’une matrice (lignes et colonnes).
Solution
1
2
3
4
5
6
7
8
def__str__(self:GrapheM)->str:rep=""foriinrange(len(self.mat)):rep=rep+str(self.mat[i][0])# Premier élement de la ligneforjinrange(1,len(self.mat[0])):rep=rep+" "+str(self.mat[i][j])rep=rep+"\n"returnrep
Écrire le code d’une fonction main qui permet de tester l’implémentation de la classe et la représentation du graphe à l’écran.
Choisir comme matrices tests
$$
M_1 =
\begin{pmatrix}
1 & 1 & 0 \cr
0 & 1 & 1 \cr
0 & 0 & 1 \cr
\end{pmatrix}
\text{ et }
M_2 =
\begin{pmatrix}
0 & 1 & 1 & 0 \cr
1 & 0 & 1 & 1 \cr
1 & 1 & 0 & 1 \cr
0 & 1 & 1 & 0 \cr
\end{pmatrix}
$$
Remarque
Les sommets du graphe sont représentés par des entiers naturels.
Solution
1
2
3
4
5
6
7
8
9
10
11
12
defmain():""" Fonction principale """mat1=[[1,1,0],[0,1,1],[0,0,1]]mat2=[[0,1,1,0],[1,0,1,1],[1,1,0,1],[0,1,1,0]]graph11=GrapheM(mat1)graph21=GrapheM(mat2)print(graph11)print(graph21)main()
Représenter les deux graphes sur une feuille.
Écrire le code de la méthode nbre_sommets qui détermine le nombre de sommets du graphe.
Jeu de tests :
defest_lie(self:GrapheM,i:int,j:int)->bool:"""
Retourne True s'il existe une relation (arête ou arc)
entre les sommets i et j, False sinon.
"""returnself.mat[i][j]!=0
Quelle est la particularité de la matrice sommet-sommet d’un graphe non orienté ?
Solution
La matrice est symétrique par rapport à la diagonale.
Écrire le code de la fonction est_non_oriente dont la spécification est
1
2
3
4
5
6
defest_non_oriente(self:GrapheM)->bool:"""
Retourne True si le graphe est non orienté
(si la matrice est symétrique) et False si le
graphe est orienté.
"""
defest_non_oriente(self:GrapheM)->bool:"""
Retourne True si le graphe est non orienté
(si la matrice est symétrique) et False si le
graphe est orienté.
"""n=len(self.mat)foriinrange(n):forjinrange(i+1,n):ifself.mat[i][j]!=self.mat[j][i]:returnFalsereturnTrue
Liste d’adjacence
Dans cette partie, on implémente la liste d’adjacence (liste des voisins) d’un graphe non orienté ou la liste des successeurs d’un graphe orienté.
Écrire le code de la classe GrapheL qui implémente une liste des voisins.
La spécification du constructeur de la classe est :
1
2
3
4
def__init__(self:GrapheL,lst:List[List[int]])->None:"""
Constructeur de la classe.
"""
Remarque : cette classe possède l’attribut lst qui référence une liste d’adjacence.
Solution
1
2
3
4
5
6
classGrapheL:"""
Implémentation de la liste des voisins d'un graphe non orienté.
"""def__init__(self,lst:List[List[int]])->None:self.lst=lst
Ajouter à la classe GrapheL une redéfinition de la méthode spéciale __str__ de façon à ce qu’un appel à la fonction print avec comme argument un objet représentant un graphe donne un affichage qui rappelle celui d’une liste de listes.
Solution
1
2
3
4
5
6
7
8
9
10
11
12
13
def__str__(self:GrapheLV)->str:"""
Représentation sous forme d'une chaîne de caractères de l'objet.
"""rep=""foriinrange(len(self.lst)):rep+="{} :".format(i)forjinrange(len(self.lst[i])):rep+=" "+str((self.lst[i][j]))rep+="\n"returnrep
Tester le code précédent à l’aide des listes des voisins/successeurs des graphes dont les matrices sommet-sommet sont données dans la première section.
defest_lie(self:GrapheL,i:int,j:int)->bool:"""
Retourne True s'il existe une relation (arête ou arc) entre les sommets i et j, False sinon.
"""returnjinself.lst[i]
Écrire le code de la fonction est_non_oriente dont la spécification est
1
2
3
4
defest_non_oriente(self:GrapheL)->bool:"""
Retourne True si le graphe est non orienté, False sinon.
"""
defest_non_oriente(self:GrapheL)->bool:"""
Retourne True si le graphe est non orienté (si la matrice est symétrique) et False si le graphe est orienté.
"""foriinrange(len(self.lst)):forjinrange(len(self.lst[i])):s=self.lst[i][j]# sommetifinotinself.lst[s]:returnFalsereturnTrue
Passage d’une représentation à l’autre
Ajouter à la classe GrapheL la méthode lst_to_mat dont la spécification est :
1
2
3
4
deflst_to_mat(self:GrapheL)->GrapheM:"""
Génère la matrice sommet-sommet à partir de la liste des voisins/successeurs.
"""
deflst_to_mat(self:GrapheL)->GrapheM:"""
Génère la matrice sommet-sommet à partir de la liste des
voisins/successeurs.
"""mat=[]n=len(self.lst)foriinrange(n):ligne=[]forjinrange(n):ifjinself.lst[i]:ligne.append(1)else:ligne.append(0)mat.append(ligne)returnGrapheM(mat)
Ajouter à la classe GrapheM la méthode mat_to_lst dont la spécification est :
1
2
3
4
defmat_to_lst(self:GrapheM)->GrapheL:"""
Génère la liste des voisins/successeurs à partir de la matrice sommet-sommet.
"""
defmat_to_lst(self:GrapheM)->GrapheL:"""
Génère la liste des voisins/successeurs à partir de la matrice sommet-sommet.
"""liste=[]# liste des listes pour tous les sommetsforiinrange(len(self.mat)):rel=[]# relation pour le sommet iforjinrange(len(self.mat)):ifself.mat[i][j]!=0:rel.append(j)liste.append(rel)returnGrapheL(liste)