Skip to content
Snippets Groups Projects
Commit a88f9911 authored by Sania Mekchiche's avatar Sania Mekchiche
Browse files

soucis de conflit entre les versions

parents 374ba3b0 fea94c4d
No related branches found
No related tags found
No related merge requests found
TP2_hachage/Histogramme 7B.png

17.8 KiB

TP2_hachage/Histogramme 7C.png

17.4 KiB

......@@ -55,6 +55,10 @@ Initialiser dans la fonction `experiment_load_factor` des listes `insertion_time
6. A quoi sert la fonction `experiment_longest` ?
La fonction experiment_longest parcourt, par une itération, les nombres de 0 à 999 et stocke chaque valeur dans un dictionnaire
avec une clé correspondant au nombre sous forme de chaîne de caractères.
À chaque insertion d'un élément dans le dictionnaire, le temps d'insertion est mesuré et ajouté dans un histogramme.
## Visualisation des résultats
7. Créez quatre graphiques au format png ou pdf :
......@@ -65,3 +69,27 @@ Initialiser dans la fonction `experiment_load_factor` des listes `insertion_time
- Un histogramme des fréquences des temps d'insertions discrétisés (code fourni, remplacer la liste vide par la bonne entrée)
10. Commentez vos résultats.
7A : Ce graphique représente le temps d'insertion des éléments dans le dictionnaire en fonction du facteur de charge.
Nous avons calculé la moyenne du temps d'insertion pour chaque facteur de charge et l'avons représentée sur le graphique.
Nous nous attendions à ce que le temps d'insertion soit plus faible pour les petits facteurs de charge, mais nous avons observé l'inverse, sans pouvoir l'expliquer.
Nous avons cherché un éventuel biais en utilisant la médiane au lieu de la moyenne, mais les résultats sont restés identiques.
Nous pouvons cependant noter qu'un dictionnaire possède une taille initiale définie.
Lorsqu'un élément est ajouté, il faut parcourir le dictionnaire et trouver un emplacement libre, ce qui explique le temps d'insertion observé, qui est censé être plus grand avec le facteur de charge.
7B : Ce graphique illustre le nombre de réallocations de mémoire en fonction du facteur de charge.
On remarque que les petits facteurs de charge nécessitent peu d'espace, et donc peu de réallocations.
En revanche, pour les plus grands facteurs de charge, la mémoire requise augmente, entraînant davantage de réallocations.
On observe également des plateaux dans le graphique. En effet, la taille du dictionnaire double à chaque réallocation,
laissant un espace libre suffisant pour insérer de nouveaux éléments sans nécessiter immédiatement une nouvelle réallocation.
Ainsi, on insère jusqu'à saturation, puis une nouvelle réallocation est déclenchée.
7C : Ce graphique représente la taille de la mémoire occupée en fonction du nombre d'éléments insérés.
On observe que pour les petites valeurs, le nombre de réallocations de mémoire est faible.
À mesure que le facteur de charge augmente, la taille des réallocations croît également.
Cependant, on note des écarts importants à certains moments. Cela s'explique par le mécanisme des réallocations : la taille du dictionnaire double lorsque l'espace est insuffisant.
Par conséquent, pour certaines valeurs du facteur de charge, il reste suffisamment d’espace pour insérer plusieurs éléments sans nécessiter de nouvelle réallocation.
Histogramme.png : Ce dernier graphique montre la distribution des temps d'insertion sous forme d'histogramme.
On remarque que la plupart des valeurs sont insérées très rapidement dans le dictionnaire, tandis qu'un faible nombre d'insertions prennent plus de temps.
Cela s’explique par le fait que le dictionnaire doit parfois parcourir son espace de stockage pour trouver une position libre avant d'insérer la nouvelle clé et sa valeur.
TP2_hachage/histogramme 7A.png

21.8 KiB

TP2_hachage/histogramme.png

18.6 KiB

TP2_hachage/mphf.png

27.7 KiB

......@@ -11,8 +11,8 @@ import math
def experiment_load_factor(load_factors): # = load_factor = liste de facteur de charge
"""
Étude du facteur de charge
"""
Étude du facteur de charge
"""
insertion_times = []
num_resizes = []
sizes = []
......@@ -44,11 +44,11 @@ def experiment_load_factor(load_factors): # = load_factor = liste de facteur de
def experiment_longest():
"""
TODO: cette focntion apour objectif de créer un dictionnaire, à partir d'une valleur de départ,
pour chaque iteration, elle associé une clé qui est la chaine de caractère de la valeur. A chaque insertion, le temps
est ajouté est mésuré et est stocké dans une variable.
A la fin un histogramme est créer et stocké dans un histogramme.
"""
TODO: cette focntion apour objectif de créer un dictionnaire, à partir d'une valleur de départ,
pour chaque iteration, elle associé une clé qui est la chaine de caractère de la valeur. A chaque insertion, le temps
est ajouté est mésuré et est stocké dans une variable.
A la fin un histogramme est créer et stocké dans un histogramme.
"""
d = {}
insertion_times = []
......@@ -65,8 +65,8 @@ def experiment_longest():
def visualisation(load_factors, insertion_times, num_resizes, sizes, frequencies):
"""
Visualisation des résultats
"""
Visualisation des résultats
"""
# Temps d'insertion en fonction du facteur de charge
plt.figure(figsize=(10, 6))
plt.bar(load_factors, insertion_times, width=0.01, label="insertion_time", color='blue')
......
......@@ -8,8 +8,7 @@ import random
###### PARTIE 1 ######
def construction_mphf(set_kmer, n, gamma=2, nb_niveaux=3):
"""
"""
Construit une fonction de hachage minimale parfaite (MPHF) pour un ensemble de k-mers.
Parameters:
......@@ -32,52 +31,52 @@ def construction_mphf(set_kmer, n, gamma=2, nb_niveaux=3):
>>> len(mphf) == n
True
"""
# Initialisation
set_kmer_courant = set_kmer.copy()
tableaux = []
collision = set()
for _ in range(nb_niveaux):
if len(set_kmer_courant) > 0:
l = len(set_kmer_courant)
tableau_principal = [-1] * (gamma * l)
for kmer in set_kmer_courant:
index = abs(hash(kmer)) % (gamma*l)
if tableau_principal[index]!= -1:
collision.add(kmer)
else :
tableau_principal[index] = index
tableaux.append(tableau_principal) # expliquer
set_kmer_courant = collision.copy() # expliquer
collision = set() # expliquer je pense que c'est pour éliminer les collisoin de même valeurs
# Construction de la MPHF
mphf = []
grand_tableau = []
for tableau in tableaux:
grand_tableau.extend(tableau) # expliquer elle va ajouté toute les valeurs du tableau
rangs = []
max_rang = 0
i = 0
for kmer in set_kmer:
hacher = abs(hash(kmer))
if hacher in grand_tableau :
index = grand_tableau.index(hacher)
rangs.append(grand_tableau[:index].count(hacher))
mphf.append([hacher, rangs[-1]])
max_rang = max(rangs)
for kmer in set_kmer_courant: #gestion des collisions: expliquer les 3 lignes du dessous
max_rang += 1
h = abs(hash(kmer))
mphf.append([h, max_rang])
return mphf
# Initialisation
set_kmer_courant = set_kmer.copy()
tableaux = []
collision = set()
for _ in range(nb_niveaux):
if len(set_kmer_courant) > 0:
l = len(set_kmer_courant)
tableau_principal = [-1] * (gamma * l)
for kmer in set_kmer_courant:
index = abs(hash(kmer)) % (gamma * l)
if tableau_principal[index] != -1:
collision.add(kmer)
else:
tableau_principal[index] = index
tableaux.append(tableau_principal) # expliquer
set_kmer_courant = collision.copy() # expliquer
collision = set() # expliquer je pense que c'est pour éliminer les collisoin de même valeurs
# Construction de la MPHF
mphf = []
grand_tableau = []
for tableau in tableaux:
grand_tableau.extend(tableau) # expliquer elle va ajouté toute les valeurs du tableau
rangs = []
max_rang = 0
i = 0
for kmer in set_kmer:
hacher = abs(hash(kmer))
if hacher in grand_tableau:
index = grand_tableau.index(hacher)
rangs.append(grand_tableau[:index].count(hacher))
mphf.append([hacher, rangs[-1]])
max_rang = max(rangs)
for kmer in set_kmer_courant: # gestion des collisions: expliquer les 3 lignes du dessous
max_rang += 1
h = abs(hash(kmer))
mphf.append([h, max_rang])
return mphf
def get_hash_mphf(mphf, kmer):
"""
"""
Calcule le hash d'un k-mer à l'aide d'une fonction de hachage minimale parfaite (MPHF).
Parameters:
......@@ -96,13 +95,14 @@ def get_hash_mphf(mphf, kmer):
>>> 0 <= hash_mphf < n
True
"""
hacher = abs(hash(kmer))
for h, rang in mphf :
if h == hacher :
return rang
hacher = abs(hash(kmer))
for h, rang in mphf:
if h == hacher:
return rang
def create_hash_table(set_kmer, n):
"""
"""
Crée une table de hachage à partir d'un ensemble de k-mers et d'une mphf
Parameters:
......@@ -122,50 +122,51 @@ def create_hash_table(set_kmer, n):
>>> all(kmer in tableau for kmer in set_kmer)
True
"""
mphf = construction_mphf(set_kmer, n)
tableau = n*[None]
for i in set_kmer:
hacher = get_hash_mphf(mphf, i)
if hacher :
tableau[hacher] = i
return tableau, mphf
mphf = construction_mphf(set_kmer, n)
tableau = n * [None]
for i in set_kmer:
hacher = get_hash_mphf(mphf, i)
if hacher:
tableau[hacher] = i
return tableau, mphf
def generer_kmers(n, k):
'''
'''
genere un set de n k-mers
'''
kmers = set()
while len(kmers) < n:
kmer = ''.join(random.choice('ATCG') for _ in range(k))
kmers.add(kmer)
return kmers
kmers = set()
while len(kmers) < n:
kmer = ''.join(random.choice('ATCG') for _ in range(k))
kmers.add(kmer)
return kmers
def compare_taille(n_max, fichier_sortie):
n_values = []
table_size = []
dict_size = []
k = 21
for n in range(100, n_max, 1000):
set_kmer = generer_kmers(n, k)
tableau, mphf = create_hash_table(set_kmer,n)
n_values.append(n)
table_size.append(sys.getsizeof(tableau)+sys.getsizeof(mphf)) # pourquoi ici on ne mesure pas juste la taille en mémoire du tableau ?
dict_size.append(sys.getsizeof(set_kmer))
plt.plot(n_values, table_size, label='Table avec MPHF')
plt.plot(n_values, dict_size, label='Dict')
plt.xlabel('n')
plt.xticks(n_values, [str(x) for x in n_values], rotation=45)
plt.ylabel('Taille (octets)')
plt.title('Évolution de la taille de la table de hachage avec MPHF et du dict')
plt.legend()
plt.savefig(fichier_sortie)
plt.close()
n_values = []
table_size = []
dict_size = []
k = 21
for n in range(100, n_max, 1000):
set_kmer = generer_kmers(n, k)
tableau, mphf = create_hash_table(set_kmer, n)
n_values.append(n)
table_size.append(sys.getsizeof(tableau) + sys.getsizeof(
mphf)) # pourquoi ici on ne mesure pas juste la taille en mémoire du tableau ?
dict_size.append(sys.getsizeof(set_kmer))
plt.plot(n_values, table_size, label='Table avec MPHF')
plt.plot(n_values, dict_size, label='Dict')
plt.xlabel('n')
plt.xticks(n_values, [str(x) for x in n_values], rotation=45)
plt.ylabel('Taille (octets)')
plt.title('Évolution de la taille de la table de hachage avec MPHF et du dict')
plt.legend()
plt.savefig(fichier_sortie)
plt.close()
# dé-commenter quand vous êtes prêts, expliquer les résultats
compare_taille(10000,"mphf.png")
compare_taille(10000, "mphf.png")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment