Construit une fonction de hachage minimale parfaite (MPHF) pour un ensemble de k-mers.
Parameters:
set_kmer (set): Ensemble de k-mers.
n (int): Taille de l'ensemble de k-mers.
gamma (int): Facteur de réduction de la taille de la table de hachage. Default: 2.
nb_niveaux (int): Nombre de niveaux de réduction de la taille de la table de hachage. Default: 3.
Returns:
mphf (list): Table de hachage minimale parfaite.
Examples:
>>>set_kmer={str(i)foriinrange(10)}
>>>n=10
>>>mphf=construction_mphf(set_kmer,n)
>>>len(mphf)==n
True
>>>all(0<=mphf[i]<nforiinrange(n))
True
>>>len(mphf)==n
True
"""
# Initialisation
set_kmer_courant=set_kmer.copy()
tableaux=[]
collision=set()
for_inrange(nb_niveaux):
iflen(set_kmer_courant)>0:
l=len(set_kmer_courant)
tableau_principal=[-1]*(gamma*l)
forkmerinset_kmer_courant:
x=abs(hash(kmer))%len (tableau_principal)# On calcule le hachage du k-mer avec hash(kmer), puis on prend la valeur absolue de ce hachage pour garantir que l'index est toujours positif et qu'il reste bien dans les limites de la taille de la table de hachage.
iftableau_principal[x]isNone:# Si l'index est libre
tableau_principal[x]=kmer# On place le k-mer dans la table
else:
collision.add(kmer)# mettre le kmer dans collision()
# compléter
# hacher le k-mer (attention, hash() peut rendre des entiers signés, nous voulons des entiers positifs)
# récupérer l'adresse
# si le tableau principal est déjà rempli à l'adresse:
# mettre le kmer dans collision()
#sinon, écrire le hash à l'adresse dans le tableau principal
tableaux.append(tableau_principal)# ajoute le tableau principal à la liste tableaux
set_kmer_courant=collision.copy()# On copie l'ensemble des k-mers en collision puis deviendront le nouvel ensemble à traiter dans le niveau suivant
collision=set()# Réinitialiser les collisions pour le prochain niveau
# Construction de la MPHF
mphf=[]
grand_tableau=[]
fortableauintableaux:
grand_tableau.extend(tableau)# expliquer
rangs=[]
max_rang=0
i=0
forkmerinset_kmer:
x=abs(hash(kmer))%len (tableau_principal)
ifgrand_tableau[h]==kmer:
"""
Construit une fonction de hachage minimale parfaite (MPHF) pour un ensemble de k-mers.
Parameters:
set_kmer (set): Ensemble de k-mers.
n (int): Taille de l'ensemble de k-mers.
gamma (int): Facteur de réduction de la taille de la table de hachage. Default: 2.
nb_niveaux (int): Nombre de niveaux de réduction de la taille de la table de hachage. Default: 3.
Returns:
mphf (list): Table de hachage minimale parfaite.
Examples:
>>>set_kmer={str(i)foriinrange(10)}
>>>n=10
>>>mphf=construction_mphf(set_kmer,n)
>>>len(mphf)==n
True
>>>all(0<=mphf[i]<nforiinrange(n))
True
>>>len(mphf)==n
True
"""
# Initialisation
set_kmer_courant=set_kmer.copy()
tableaux=[]
collision=set()
for_inrange(nb_niveaux):
iflen(set_kmer_courant)>0:
l=len(set_kmer_courant)
tableau_principal=[-1]*(gamma*l)
forkmerinset_kmer_courant:
x=abs(hash(kmer))%len (tableau_principal)# On calcule le hachage du k-mer avec hash(kmer), puis on prend la valeur absolue de ce hachage pour garantir que l'index est toujours positif et qu'il reste bien dans les limites de la taille de la table de hachage.
iftableau_principal[x]isNone:# Si l'index est libre
tableau_principal[x]=kmer# On place le k-mer dans la table
else:
collision.add(kmer)# mettre le kmer dans collision()
# compléter
# hacher le k-mer (attention, hash() peut rendre des entiers signés, nous voulons des entiers positifs)
# récupérer l'adresse
# si le tableau principal est déjà rempli à l'adresse:
# mettre le kmer dans collision()
#sinon, écrire le hash à l'adresse dans le tableau principal
tableaux.append(tableau_principal)# ajoute le tableau principal à la liste tableaux
set_kmer_courant=collision.copy()# On copie l'ensemble des k-mers en collision puis deviendront le nouvel ensemble à traiter dans le niveau suivant
collision=set()# Réinitialiser les collisions pour le prochain niveau
# Construction de la MPHF
mphf=[]
grand_tableau=[]
fortableauintableaux:
grand_tableau.extend(tableau)# expliquer
rangs=[]
max_rang=0
i=0
forkmerinset_kmer:
x=abs(hash(kmer))%len (tableau_principal)
ifgrand_tableau[x]==kmer:
rang=rangs.count(kmer)# Récupérer le rang du k-mer (utilisation de count() ici)
rangs.append(rang)# Ajouter le rang à la liste des rangs
mphf.append([h,rang])# Ajouter l'index et le rang à la MPHF
mphf.append([x,rang])# Ajouter l'index et le rang à la MPHF
max_rang=max(max_rang,rang)# Mettre à jour le rang maximum
# compléter:
# hacher le kmer
# si le hash est dans le grand_tableau
# récupérer son index
# récupérer son rang (utiliser la fonction count())
# ajouter à la mphf [h, rang]
# mettre à jour max_rang
forkmerinset_kmer_courant:#gestion des collisions: expliquer les 3 lignes du dessous
max_rang+=1
h=abs(hash(kmer))
mphf.append([h,max_rang])
returnmphf
# compléter:
# hacher le kmer
# si le hash est dans le grand_tableau
# récupérer son index
# récupérer son rang (utiliser la fonction count())
# ajouter à la mphf [h, rang]
# mettre à jour max_rang
forkmerinset_kmer_courant:#gestion des collisions: expliquer les 3 lignes du dessous
max_rang+=1
h=abs(hash(kmer))
mphf.append([h,max_rang])
returnmphf
defget_hash_mphf(mphf,kmer):
"""
Calcule le hash d'un k-mer à l'aide d'une fonction de hachage minimale parfaite (MPHF).
Parameters:
mphf (list): Table de hachage minimale parfaite.
kmer (str): K-mer à hasher.
Returns:
int: Hash du k-mer.
Examples:
>>>set_kmer={str(i)foriinrange(10)}
>>>n=10
>>>mphf=construction_mphf(set_kmer,n)
>>>kmer="5"
>>>hash_mphf=get_hash_mphf(mphf,kmer)
>>>0<=hash_mphf<n
True
"""
h=abs(hash(kmer))
forpairinmphf:
ifpair[0]==h:
returnpair[1]
returnNone
"""
Calcule le hash d'un k-mer à l'aide d'une fonction de hachage minimale parfaite (MPHF).