Académique Documents
Professionnel Documents
Culture Documents
TP Ro GM
TP Ro GM
TP Ro GM
20/01/2023
Réalisé par :
Elmarzouki abdessamad
Boutayeb youness
Encadré par :
REMERCIEMENT............................................................................................................................. 3
INTRODUCTION GÉNÉRALE............................................................................................................ 4
1
LISTE DES FIGURES
2
REMERCIEMENT
3
Introduction générale
Dans ce TP, nous allons utiliser langage python pour étudier la théorie des
graphes, par exemple calculer le plus court chemin et le plus long chemin….
4
I. Manipulation des graphes en utilisant le langage Python :
1. Exemple d’un graphe :
( )
0 5 3 2 + ∞ +∞ + ∞ +∞
5 0 1 +∞ 2 2 + ∞ +∞
3 1 0 1 + ∞ +∞ + ∞ +∞
2 +∞ 1 0 3 +∞ 2 +∞
+∞ 2 +∞ 3 0 4 4 +∞
+ ∞ 2 + ∞ +∞ 4 0 1 7
+ ∞ +∞ + ∞ 2 4 1 0 6
+ ∞ +∞ + ∞ +∞ + ∞ 7 6 0
5
2. Détermination des degrés des sommets d’un graphe en utilisant le module
NymPy :
Ce code crée une matrice appelée ADJ en utilisant la fonction "matrix" de la bibliothèque
numpy. La matrice est initialisée avec des valeurs spécifiques sous la forme d'un tableau à deux
dimensions, qui représente une matrice d'adjacence. Une matrice d'adjacence est une matrice
carrée utilisée pour représenter un graphe fini, avec des dimensions égales au nombre de
sommets dans le graphe.
6
3. Calculer les degrés des sommets d’un graphe :
Ce code définit une fonction appelée "degrés" qui prend en paramètre une matrice
d'adjacence représentée par "ADJ".
La fonction commence par créer une liste vide appelée "Deg" qui stockera le degré de
chaque sommet.
Ceci est fait pour chaque sommet, ce qui donne le degré de chaque sommet.
En résumé, cette fonction prend en entrée une matrice d'adjacence "ADJ" et renvoie une
liste des degrés de chaque sommet dans le graphe représenté par la matrice d'adjacence.
7
4. Déterminer le type d’un graphe (eulérien, semi-eulérien ou non eulérien) :
Ce code définit une fonction appelée "eulerien" qui prend en paramètre "M", qui est une
matrice d'adjacence. Le but de la fonction est de déterminer si un graphe représenté par la matrice
d'adjacence "M" est Eulérien, semi-Eulérien ou non-Eulérien.
La fonction appelle d'abord une autre fonction appelée "degrés" qui prend en entrée une
matrice d'adjacence et renvoie une liste des degrés de chaque sommet dans le graphe représenté
par la matrice d'adjacence. La fonction utilise ensuite cette liste pour compter le nombre de
sommets ayant un degré impair.
La fonction crée ensuite une variable "n" avec la longueur de la liste des degrés. Il crée une
variable appelée "nb_degre_impair" et l'initialise à 0, cette variable va suivre le nombre de
sommets ayant un degré impair.
Il parcourt la liste des degrés et pour chaque élément, il vérifie s'il est impair en utilisant
l'opérateur modulo (%), s'il est impair, il incrémente "nb_degre_impair" de 1.
si elle est égale à 0, la fonction renvoie "eulerien", indiquant que le graphe est Eulérien.
si elle est égale à 2, la fonction renvoie "semi-eulerien", indiquant que le graphe est semi-
Eulérien.
sinon, la fonction renvoie "non eulerien", indiquant que le graphe n'est ni Eulérien ni semi-
Eulérien.
En résumé, cette fonction prend en entrée une matrice d'adjacence "M" et renvoie une
chaîne indiquant si le graphe représenté par la matrice est Eulérien, semi-Eulérien ou non-Eulérien
en comptant le nombre de sommets ayant un degré impair
8
Figure 7: Résultat de fonction eulérien
5. Implémentation de Dijkstra :
Il parcourt alors à nouveau tous les sommets dans le graphe et pour chaque sommet, il
vérifie si la distance stockée dans la liste "result" est supérieure à la somme de la distance du
dernier sommet visité et le poids de l'arête entre le dernier sommet visité et le sommet courant. Si
c'est vrai, il met à jour la liste "result"
Ce code définit une fonction appelée "Dijkstras" qui prend en paramètre deux variables, "S"
et "M".
La fonction commence par créer une liste appelée "result" et définit tous ses éléments
comme l'infini positif. Ensuite, il définit l'élément à l'index "S" à 0.
La fonction crée également deux listes vides, "visited" et "path", avec la même longueur
que la matrice "M".
Il entre ensuite dans une boucle while qui continue tant que la longueur de "visited" est
égale au nombre de sommets dans le graphe.
9
Dans la boucle, il initialise deux variables "min_dist" et "min_idx" à l'infini positif et à
"None" respectivement.
Il parcourt alors tous les sommets dans le graphe et pour chaque sommet qui n'a pas été
visité, il vérifie si sa distance stockée dans la liste "result" est inférieure à "min_dist". Si c'est vrai, il
met à jour "min_dist" avec la distance et "min_idx" avec l'index du sommet.
Une fois la boucle terminée, il ajoute le sommet avec la distance minimale à la liste
"visited".
6. Arborescence de graphes G :
Il initialise ensuite une liste appelée "result" avec le même nombre d'éléments que le
nombre de lignes de "M" et met la valeur à l'index "S" à 0, et tous les autres éléments à l'infini. Il
initialise également une liste vide appelée "visited" et une liste appelée "path" avec le même
nombre d'éléments que le nombre de lignes de "M" et met la valeur à l'index "S" à "S".
Il entre dans une boucle while qui se poursuit tant que le nombre d'éléments dans "visited"
est inférieur au nombre de lignes de "M". Dans la boucle while, il initialise deux variables appelées
"min_dist" et "min_idx" avec l'infini et None respectivement. Il utilise ensuite une boucle for pour
parcourir les lignes de "M" et si la ligne actuelle n'est pas dans "visited" et la valeur correspondante
dans "result" est inférieure à "min_dist", il met à jour "min_dist" et "min_idx" avec la valeur
actuelle et l'index respectivement.
La prochaine étape, il ajoute l'index "min_idx" courant à la liste "visited" et une autre
boucle for pour parcourir les lignes de "M" et vérifie si la valeur dans "result" à l'index "i" est
supérieure à la valeur dans "result" à "min_idx" plus la valeur dans "M" aux indices "min_idx" et "i".
Si c'est le cas, il met à jour "result" à l'index "i" avec cette nouvelle valeur et met à jour "path" à
l'index "i" en "min_idx".
Enfin, il utilise une boucle for pour parcourir les éléments dans "path" et si l'index n'est pas
égal à la valeur à cet index, il ajoute une arête avec un poids égal à la valeur correspondante dans
"result" de l'index à la valeur à cet index dans "path".
11
7. Algorithme de Floyd-Warshall :
1) Présentation :
L'algorithme utilise une matrice de distance pour stocker les distances les plus courtes
entre les sommets, commençant par initialiser toutes les distances entre les sommets à l'infini sauf
pour les arêtes directes où la distance est égale au poids de l'arête. Il utilise ensuite une boucle de
trois niveaux pour mettre à jour cette matrice de distance en utilisant la règle de Bellman-Ford pour
trouver les chemins les plus courts en passant par un sommet intermédiaire.
Ce code définit une fonction appelée "floyd" qui prend en entrée une matrice "M". Il crée
d'abord une liste à deux dimensions appelée "dist" ayant le même nombre de lignes et de colonnes
que le nombre de lignes dans "M" et initialise tous les éléments avec l'infini positif.
Il utilise ensuite deux boucles imbriquées pour parcourir les lignes et les colonnes de "M"
pour mettre à jour l'élément correspondant dans "dist" avec la valeur de "M" si les indices de ligne
et de colonne ne sont pas égaux, sinon il met la valeur à 0.
12
Ensuite, des boucles imbriquées pour k, i, j sont utilisées pour parcourir les lignes et les
colonnes de "M" et vérifier si la valeur dans "dist" aux indices "i", "j" est supérieure à la somme des
valeurs dans "dist" aux indices "i", "k" et "k", "j". Si c'est le cas, il met à jour "dist" aux indices "i", "j"
avec cette nouvelle valeur.
Ce code semble implémenter l'algorithme de Floyd-Warshall, qui est utilisé pour trouver le
plus court chemin entre tous les sommets d'un graphe pondéré représenté par la matrice "M". Il
initialise d'abord la matrice de distance avec l'infini sauf les arêtes directes où la distance est le
poids de cette arête. Il utilise des boucles imbriquées pour trouver le plus court chemin entre tous
les sommets en relâchant les arêtes à plusieurs reprises.
La fonction commence par initialiser la variable "max" avec la valeur du premier élément de
la première ligne de la matrice (M[0][0]). Elle initialise également la variable "d" à 1, qui sera
utilisée pour stocker le numéro de la colonne de l'élément maximal courant, et la variable "b" à 0,
qui sera utilisée pour parcourir les lignes de la matrice. La liste "parcour" est également initialisée
avec la valeur de "d" pour stocker les numéros de colonnes des éléments maximaux de chaque
ligne.
La fonction utilise ensuite une boucle while pour parcourir chaque ligne de la matrice "M".
Pour chaque ligne, la variable "max" est réinitialisée avec la valeur de la première colonne de cette
ligne (M[b][0]). Il utilise une boucle "for" pour parcourir chaque colonne de la ligne courante, et si
l'élément courant est plus grand que "max", la variable "max" est mise à jour avec cette valeur et la
variable "d" est mise à jour pour stocker le numéro de colonne de cet élément (i+1).
Une fois que toutes les colonnes de la ligne courante ont été parcourues, la variable "b" est
incrémentée de 1 pour passer à la ligne suivante. Le numéro de colonne de l'élément maximal pour
la ligne courante est ajouté à la liste "parcour"
Enfin, une fois que toutes les lignes ont été parcourues, la fonction retourne la liste
"parcour" qui contient les numéros de colonnes des éléments maximaux pour chaque ligne de la
matrice d'entrée.
14
Figure 16: résultat de programme
15