Vous êtes sur la page 1sur 10

CI-1

TP Recherche
Opérati onnelle
2022 - 2023
Exercice 1 :
Partie I :

( )
0 5 3 2 ∞ ∞ ∞ ∞
5 0 1 ∞ 2 2 ∞ ∞
3 1 0 1 ∞ ∞ ∞ ∞
2 ∞ 1 0 3 ∞ 2 ∞
1. la matrice d’adjacence A du graphe : A=
∞ 2 ∞ 3 0 4 4 ∞
∞ 2 ∞ ∞ 4 0 1 7
∞ ∞ ∞ 2 4 1 0 6
∞ ∞ ∞ ∞ ∞ 7 6 0

2. . Implémentation de la matrice A sur Python en utilisant le module NymPy :

import numpy as np

A =[[0, 5, 3, 2, np.inf, np.inf, np.inf, np.inf],

[5, 0, 1, np.inf, 2, 2, np.inf, np.inf],

0
[3, 1, 0, 1, np.inf, np.inf, np.inf, np.inf],

[2, np.inf, 1, 0, 3, np.inf, 2, np.inf],

[np.inf, 2, np.inf, 3, 0, 4, 4, np.inf],

[np.inf, 2, np.inf, np.inf, 4, 0, 1, 7],

[np.inf, np.inf, np.inf, 2, 4, 1, 0, 6],

[np.inf, np.inf, np.inf, np.inf, np.inf, 7, 6, 0]]

# voilà ce qu’il affiche :

> print(A)

[[0, 5, 3, 2, inf, inf, inf, inf], [5, 0, 1, inf, 2, 2, inf, inf], [3, 1, 0, 1, inf, inf, inf, inf], [2, inf, 1, 0, 3, inf, 2, inf], [inf, 2, inf, 3, 0, 4, 4,
inf], [inf, 2, inf, inf, 4, 0, 1, 7], [inf, inf, inf, 2, 4, 1, 0, 6], [inf, inf, inf, inf, inf, 7, 6, 0]]

3. La fonction degres(M) qui prends en argument la matrice d’adjacence M d’un graphe et qui
retourne les degrés de ses sommets :

import numpy as np

def degres(M):

V = len(M) # la taille de la matrice

degres_des_sommes = [] #la liste ou on incrémente le dégrée de chaque sommet

for i in range(V):

degre = sum([1 for j in range(V) if M[i][j] != 0 and M[i][j] != np.inf ]) # on prend 1 pour chaque éléments
dans la ligne ou il est n’est nulle et diffèrent de l’infinie

degres_des_sommes.append(degre) # il ajoute la valeur degre à la fin de la liste

1
return degres_des_sommes

# Voilà ce qu’il affiche :

> degres(A)

[3, 4, 3, 4, 4, 4, 4, 2]

4. La fonction eulerien(M) qui prends en argument la matrice d’adjacence M d’un graphe et qui
permet de détecter si le graphe est eulérien, semi-eulérien ou non. On appelons la fonction
degres(M)

def eulerien(M):

degrés = degres(M) # on appelle la fonction précédente (degres(M) pour travailler sur chaque degré du sommet

nb_sommets_pairs = len([ 1 for d in degrés if d % 2 == 0]) # on applique la proposition du cour

if nb_sommets_pairs == len(M):

return "eulérien"

elif nb_sommets_pairs == len(M)-2:

return "semi-eulérien"

else:

2
return "non eulérien"

#Voilà ce qu’il affiche :

> eulerien(A)

'semi-eulérien'

Partie II :

5. la fonction Dijkstra(S, M) permettant de déterminer les plus courts chemin du sommet S vers
le reste des sommets du graphe de matrice d’adjacence M.

import numpy as np

def Dijkstra(S, M):

n = len(M)

D = [np.inf] * n # tableau des distances de S à chaque sommet

Q = [i for i in range(n)] # ensemble de sommets non encore visités

D[S] = 0 # la distance de S à S est 0

while Q: # Boucle principale

u = Q[0] # Trouver le sommet avec la distance minimale

for v in Q:

if D[v] < D[u]:

u=v

3
Q.remove(u) # retirer u de l'ensemble des sommets non encore visités

for v in range(n): # Mise à jour des distances

if M[u][v] is not None and D[v] > D[u] + M[u][v]:

D[v] = D[u] + M[u][v]

return D

6. Affichage du résultat obtenu par l’exécution de la fonction précédente sur le graphe


précédent en prenant comme sommet racine S=0.

> S=0

> Dijkstra(S,A)

[0, 4, 3, 2, 5, 5, 4, 10]

7. Modification sur la fonction précédente pour afficher l’arborescence des plus courts chemins
issus du sommet S.

def Dijkstra(S, M):

n = len(M)

D = [np.inf] * n # tableau des distances de S à chaque sommet

Q = [i for i in range(n)] # ensemble de sommets non encore visités

pred = [None] * n # tableau des prédécesseurs de chaque sommet

D[S] = 0 # la distance de S à S est 0

while Q: # Boucle principale

u = Q[0] # Trouver le sommet avec la distance minimale

4
for v in Q:

if D[v] < D[u]:

u=v

Q.remove(u) # retirer u de l'ensemble des sommets non encore visités

for v in range(n): # Mise à jour des distances et des prédécesseurs

if M[u][v] is not None and D[v] > D[u] + M[u][v]:

D[v] = D[u] + M[u][v]

pred[v] = u

# Affichage de l'arborescence des plus courts chemins

for v in range(n):

if v != S:

path = [v]

while pred[v] is not None:

v = pred[v]

path.append(v)

#On affiche ensuite ce tableau path en le retournant

print("Le plus court chemin de", S, "à", path[0], "passe par les sommets", list(reversed(path)))

# Voilà le résultat obtenu par l’exécution de cette fonction sur le graphe précédent

> S=0

> Dijkstra(S,A)

Le plus court chemin de 0 à 1 passe par les sommets [0, 2, 1]

Le plus court chemin de 0 à 2 passe par les sommets [0, 2]

Le plus court chemin de 0 à 3 passe par les sommets [0, 3]

Le plus court chemin de 0 à 4 passe par les sommets [0, 3, 4]

Le plus court chemin de 0 à 5 passe par les sommets [0, 3, 6, 5]

Le plus court chemin de 0 à 6 passe par les sommets [0, 3, 6]

Le plus court chemin de 0 à 7 passe par les sommets [0, 3, 6, 7]

5
8. une présentation claire de l’algorithme Floyd-Warshall.

L'algorithme Floyd-Warshall est un algorithme de recherche de plus courts chemins dans un


graphe valué avec des distances positives ou nulles. Il permet de trouver les distances
minimales entre tous les couples de sommets d'un graphe, c'est-à-dire la distance minimale
entre chaque sommet i et chaque sommet j.

9. Implémenter la fonction FloydWarshall(M) avec M représente la matrice d’adjacence d’un


graphe.

def FloydWarshall(M):

n = len(M)
#la fonction vérifie si le chemin de i à j
F = M.copy() en passant par le sommet k est plus
court que le chemin actuel de i à j. Si
for k in range(n):
c'est le cas, la distance de i à j dans la
matrice F est mise à jour avec la
for i in range(n):
distance du nouveau chemin.
for j in range(n):

if F[i][k] + F[k][j] < F[i][j]:

F[i][j] = F[i][k] + F[k][j]

6
return F

# Exécution sur le graphe précèdent

> FloydWarshall(A)

[[0, 4, 3, 2, 5, 5, 4, 10], [4, 0, 1, 2, 2, 2, 3, 9], [3, 1, 0, 1, 3, 3, 3, 9], [2, 2, 1, 0, 3, 3, 2, 8], [5, 2, 3,


3, 0, 4, 4, 10], [5, 2, 3, 3, 4, 0, 1, 7], [4, 3, 3, 2, 4, 1, 0, 6], [10, 9, 9, 8, 10, 7, 6, 0]]

Exercice 2 :
Pour traiter ce problème on va utiliser le logarithme est une fonction mathématique qui
permet de transformer des multiplications en additions, et puisque le graphe contient des arcs de
poids négatifs et positifs, ça ne guide à utiliser l'algorithme de Bellman-Ford pour trouver le plus
longs chemin.

Pour utiliser l'algorithme de Bellman-Ford pour trouver le plus long chemin au lieu du plus
court chemin, simplement on inverse les poids de tous les arcs du graphe. Cela signifie que les arcs
qui avaient un poids positif auront maintenant un poids négatif, et vice versa.

Le graphe que on va traiter :

Log100
07
Implémentation de la matrice d’adjacence A de ce graphe sur Python :

import numpy as np

import math as ma

A =[[np.inf, ma.log(100), np.inf, np.inf, np.inf, np.inf, np.inf, np.inf, np.inf],

[np.inf, np.inf, ma.log(2), ma.log(5), np.inf, np.inf, np.inf, np.inf, np.inf],

[np.inf, np.inf, np.inf, ma.log(3), np.inf, np.inf, ma.log(6), np.inf, np.inf],

[np.inf, np.inf, np.inf, np.inf, ma.log(3), ma.log(5), np.inf, np.inf, np.inf],

[np.inf, np.inf, np.inf, np.inf, ma.log(2), np.inf, ma.log(6), np.inf, np.inf],

[np.inf, np.inf, np.inf, np.inf, np.inf, np.inf, np.inf, np.inf, ma.log(12)],

[np.inf, np.inf, np.inf, np.inf, np.inf, np.inf,np.inf,ma.log(0.5),ma.log(10)],

[np.inf, np.inf, np.inf, np.inf, np.inf, np.inf, np.inf, np.inf, ma.log(2)],

[np.inf, np.inf, np.inf, np.inf, np.inf, np.inf, np.inf, np.inf, np.inf]]

import numpy as np

import math as ma

A =[[-np.inf, -ma.log(100), -np.inf, -np.inf, -np.inf, -np.inf, -np.inf, -np.inf, -np.inf],

[-np.inf, -np.inf, -ma.log(2), -ma.log(5), -np.inf, -np.inf, -np.inf, -np.inf, -np.inf],

[-np.inf, -np.inf, -np.inf, -ma.log(3), -np.inf, -np.inf, -ma.log(6), -np.inf, -np.inf],

[-np.inf, -np.inf, -np.inf, -np.inf, -ma.log(3), -ma.log(5), -np.inf, -np.inf, -np.inf],

[-np.inf, -np.inf, -np.inf, -np.inf, -ma.log(2), -np.inf, -ma.log(6), -np.inf, -np.inf],

[-np.inf, -np.inf, -np.inf, -np.inf, -np.inf, -np.inf, -np.inf,-np.inf, -ma.log(12)],

[-np.inf, -np.inf, -np.inf, -np.inf, -np.inf, -np.inf,-np.inf,-ma.log(0.5),-ma.log(10)],

[-np.inf, -np.inf, -np.inf, -np.inf, -np.inf, -np.inf, -np.inf, -np.inf, -ma.log(2)],

8
[-np.inf, -np.inf, -np.inf, -np.inf, -np.inf, -np.inf, -np.inf, -np.inf, -np.inf]]

Vous aimerez peut-être aussi