Telechargé par ليلى الزاك

Analyse de complexité graphe

publicité
1. Représentation des graphes :
a) Listes d'adjacences :
#Liste de listes :
S=[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' ] #liste de correspondance
G= [ ['b', 'c'], ['a', 'd', 'e'], ['a', 'd'], [ 'c', 'b', 'e'], ['b', 'c', 'e'], ['b', 'd', 'f', 'g'], ['e', 'g'], ['e', 'f'], ['g'] ]
#Dictionnaire :
G = { 'a': ['b', 'c'], 'b': ['a', 'd', 'e'], 'c': ['a', 'd'],'d' :[ 'c', 'b', 'e'], 'd': ['b', 'c', 'e'], 'e': ['b', 'd', 'f', 'g'],
'f': ['e', 'g'], 'g': ['e', 'f'], 'h': ['g'] }
b) Matrice d'adjacences :
S= ['a','b','c','d','e']
M = [ [0, 0, 1, 0, 1],
[0, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 1, 0, 1, 0]]
M = [ [0, 0,
[0, 0,
[0, 0,
[0, 1,
[0, 0,
[0, 0,
0,
0,
0,
1,
0,
1,
0,
1,
1,
0,
1,
0,
0,
0,
0,
1,
0,
1,
0],
0],
1],
0],
1],
1]]
Pas besoin d’une liste de correspondance dans ce cas !
2. La structure de données deque :
 L'implémentation des Piles et Files à l'aide d'une liste :
On utilise les méthodes pop et append avec les complexités suivantes :
 O(1) pour append() et pop(-1)
 O(n) pour pop(0)
 L'implémentation des Files et Piles à l'aide de deque():
La structure deque (Doubly Ended Queue) du module collections est préférée à une liste dans les cas où
nous avons besoin d’opérations d’ajout et de suppression plus rapides à partir des deux extrémités de la
structure, car deque fournit une complexité temporelle O(1) pour toutes les opérations d’ajout et de
suppression par rapport à la liste qui peut avoir une complexité temporelle O(n).
Méthodes de deque :
Méthode
append(x)
appendleft(x)
Rôle
append ajoute une valeur du côté droit du deque
append ajoute une valeur du côté gauche du deque
pop()
Supprime et renvoie la dernière valeur du deque
popleft()
Supprime et renvoie la première valeur du deque
clear()
Vide le deque
Exemple :
from collections import deque
File = deque()
File.append("A")
#ajout à la fin de la File
File.append("B")
#ajout à la fin de la File
print(File)
#affiche deque(['A', 'B'])
File.popleft()
#renvoie: 'A'
3. Analyse de la complexité du parcours en largeur :
Soit n le nombre de sommets du graphe, et p le nombre d'arcs/arêtes.
La version de base du parcours en largeur :
def parcoursLargeur(G,s):
Parcours = []
File = [ s ]
while File != [] :
tete = File.pop(0)
for v in G[tete]:
if v not in File and v not in Parcours :
File.append(v)
Parcours.append(tete)
return Parcours
# O(1)
# O(1)
# O(n)
# O(n)
# O(1)
len(G[tete]) itérations
au total
n itérations (while)
 Lors du parcours, chaque sommet entre une seule fois dans la file F, et en sort aussi une seule fois. Donc le
nombre total des itérations de la boucle while est n.
 chaque liste de voisins d'un sommet est parcourue au plus une seule fois, or la somme des longueurs de toutes
les listes est égale à 2 fois le nombre d'aretes p ( ou une fois le nombre d'arcs si G est oriénté). On obtient alors
un cout en O(p) donc le nombre total des itérations de la boucle for est 2p (ou p si G est oriénté).
Complexité : O( n2 + np )
from collections import deque
Version améliorée :
def parcoursLargeurAmelioree(G,s):
Parcours = []
visites = {k: 0 for k in G} #en compréhension, tous les sommets sont initialement non visités (0) : O(n)
File = deque([ s ])
visites[ s ] = 1
while File != deque([]) :
tete = File.popleft()
# n itérations
# O(1)
for v in G[tete]:
if visites[v] == 0 :
# p itérations au total
# O(1)
File.append(v)
visites[v] = 1
Parcours.append(tete)
return Parcours
Complexité : O( n + p )
4. Applications :
a) Détection de la connexité d’un graphe :
def connexe(G,s):
P=parcoursLargeur(G,s)
return len(G)==len(P)
Graphe non orienté
def connexe(G):
for k in G :
P=parcoursLargeur(G,k)
if len(P)!=len(G) :
return False
return True
Graphe orienté
b) Détection de cycles :
Téléchargement