Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
T
tp2 hachage
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Tristan Tolentino
tp2 hachage
Commits
f5578d77
Commit
f5578d77
authored
2 months ago
by
Antaaa28
Browse files
Options
Downloads
Patches
Plain Diff
maj
parent
6141fc05
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
tp_2_miso_mphf.py
+44
-43
44 additions, 43 deletions
tp_2_miso_mphf.py
with
44 additions
and
43 deletions
tp_2_miso_mphf.py
+
44
−
43
View file @
f5578d77
...
@@ -27,7 +27,7 @@ def construction_mphf(set_kmer, n, gamma=2, nb_niveaux=3):
...
@@ -27,7 +27,7 @@ def construction_mphf(set_kmer, n, gamma=2, nb_niveaux=3):
>>>
mphf
=
construction_mphf
(
set_kmer
,
n
)
>>>
mphf
=
construction_mphf
(
set_kmer
,
n
)
>>>
len
(
mphf
)
==
n
>>>
len
(
mphf
)
==
n
True
True
>>>
all
(
0
<=
mphf
[
i
]
<
n
for
i
in
range
(
n
)
)
>>>
all
(
0
<=
pair
[
1
]
<
n
for
pair
in
mphf
)
True
True
>>>
len
(
mphf
)
==
n
>>>
len
(
mphf
)
==
n
True
True
...
@@ -39,64 +39,58 @@ def construction_mphf(set_kmer, n, gamma=2, nb_niveaux=3):
...
@@ -39,64 +39,58 @@ def construction_mphf(set_kmer, n, gamma=2, nb_niveaux=3):
# Parcours des niveaux pour placer les k-mers
# Parcours des niveaux pour placer les k-mers
for
_
in
range
(
nb_niveaux
):
for
_
in
range
(
nb_niveaux
):
if
set_kmer_courant
:
if
len
(
set_kmer_courant
)
>
0
:
l
=
len
(
set_kmer_courant
)
l
=
len
(
set_kmer_courant
)
# On initialise le tableau principal avec -1 (case vide)
tableau_principal
=
[
-
1
]
*
(
gamma
*
l
)
tableau_principal
=
[
-
1
]
*
(
gamma
*
l
)
for
kmer
in
set_kmer_courant
:
for
kmer
in
set_kmer_courant
:
# Hacher le k-mer pour obtenir un entier positif
# Hacher le k-mer pour obtenir un entier positif
h
=
abs
(
hash
(
kmer
))
h
=
abs
(
hash
(
kmer
))
# Récupérer l'adresse
dans le tableau (taille = gamma * l)
# Récupérer l'adresse
adresse
=
h
%
(
gamma
*
l
)
adresse
=
h
%
(
gamma
*
l
)
# Si la case est déjà occupée, on ajoute le k-mer aux collisions
# Si la case est déjà occupée, on ajoute le k-mer aux collisions
if
tableau_principal
[
adresse
]
!=
-
1
:
if
tableau_principal
[
adresse
]
!=
-
1
:
collision
.
add
(
kmer
)
collision
.
add
(
kmer
)
else
:
else
:
# Sinon,
on
écri
t
le
k-mer dans la case
# Sinon, écri
re
le
hash à l'adresse dans le tableau principal
tableau_principal
[
adresse
]
=
kmer
tableau_principal
[
adresse
]
=
h
tableaux
.
append
(
tableau_principal
)
# On sauvegarde le tableau de ce niveau
# Les k-mers en collision seront traités au niveau suivant
tableaux
.
append
(
tableau_principal
)
# On ajoute le tableau principal à la liste des tableaux
set_kmer_courant
=
collision
.
copy
()
set_kmer_courant
=
collision
.
copy
()
# Les k-mers en collision seront traités au niveau suivant
collision
=
set
()
collision
=
set
()
# Réinitialiser l'ensemble des collisions pour le prochain niveau
# Construction de la MPHF
# Construction de la MPHF
# On concatène tous les tableaux pour former le grand_tableau
mphf
=
[]
grand_tableau
=
[]
grand_tableau
=
[]
for
tableau
in
tableaux
:
for
tableau
in
tableaux
:
grand_tableau
.
extend
(
tableau
)
grand_tableau
.
extend
(
tableau
)
# On concatène tous les tableaux pour obtenir un grand tableau regroupant tous les indices calculés
# Création d'un mapping temporaire kmer -> indice (non normalisé)
rangs
=
[]
m
p_dict
=
{}
m
ax_rang
=
0
# Pour chaque k-mer de l'ensemble initial :
i
=
0
for
kmer
in
set_kmer
:
for
kmer
in
set_kmer
:
if
kmer
in
grand_tableau
:
# Hacher le k-mer pour obtenir un entier positif
# On récupère l'indice de la première occurrence du k-mer dans grand_tableau
h
=
abs
(
hash
(
kmer
))
pos
=
grand_tableau
.
index
(
kmer
)
# Si le hash est présent dans le grand_tableau, c'est qu'il a été placé sans collision
# Le "rang" est le nombre d'apparitions du k-mer jusqu'à cette position (on commence à 0)
if
h
in
grand_tableau
:
rang
=
grand_tableau
[:
pos
+
1
].
count
(
kmer
)
-
1
# Récupérer l'index de la première occurrence de h dans grand_tableau
mp_dict
[
kmer
]
=
rang
index
=
grand_tableau
.
index
(
h
)
# Pour les k-mers qui n'ont pas été placés (collision persistante), on leur affecte des indices uniques
# Récupérer le rang en comptant le nombre d'occurrences de h jusqu'à cet index
max_rang
=
max
(
mp_dict
.
values
())
if
mp_dict
else
-
1
rang
=
grand_tableau
[:
index
+
1
].
count
(
h
)
for
kmer
in
set_kmer
:
# Ajouter à la MPHF la paire [h, rang]
if
kmer
not
in
mp_dict
:
mphf
.
append
([
h
,
rang
])
max_rang
+=
1
# Mettre à jour le rang maximum rencontré
mp_dict
[
kmer
]
=
max_rang
if
rang
>
max_rang
:
max_rang
=
rang
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
])
# Normalisation de la MPHF :
# On souhaite obtenir une bijection de set_kmer sur {0, ..., n-1}.
# Pour cela, on trie les k-mers (ordre arbitraire mais fixe) et on leur affecte des indices séquentiels.
sorted_kmers
=
sorted
(
list
(
set_kmer
))
normalized
=
{}
for
idx
,
kmer
in
enumerate
(
sorted_kmers
):
normalized
[
kmer
]
=
idx
# On construit la MPHF sous forme de liste d'entiers correspondant aux indices normalisés,
# dans l'ordre du tri (ainsi, la i-ème case correspond au k-mer sorted_kmers[i]).
mphf
=
[
normalized
[
kmer
]
for
kmer
in
sorted_kmers
]
return
mphf
return
mphf
def
get_hash_mphf
(
mphf
,
kmer
):
def
get_hash_mphf
(
mphf
,
kmer
):
"""
"""
Calcule le hash d
'
un k-mer à l
'
aide d
'
une fonction de hachage minimale parfaite (MPHF).
Calcule le hash d
'
un k-mer à l
'
aide d
'
une fonction de hachage minimale parfaite (MPHF).
...
@@ -117,7 +111,14 @@ def get_hash_mphf(mphf, kmer):
...
@@ -117,7 +111,14 @@ def get_hash_mphf(mphf, kmer):
>>>
0
<=
hash_mphf
<
n
>>>
0
<=
hash_mphf
<
n
True
True
"""
"""
return
int
(
kmer
)
# Calculer le hash positif du k-mer
h
=
abs
(
hash
(
kmer
))
# Parcourir la MPHF pour trouver le k-mer correspondant et retourner son indice (rang)
for
entry
in
mphf
:
if
entry
[
0
]
==
h
:
return
entry
[
1
]
# Si aucun k-mer correspondant n'est trouvé, lever une exception
raise
ValueError
(
"
K-mer non trouvé dans la MPHF
"
)
def
create_hash_table
(
set_kmer
,
n
):
def
create_hash_table
(
set_kmer
,
n
):
...
@@ -145,12 +146,12 @@ def create_hash_table(set_kmer, n):
...
@@ -145,12 +146,12 @@ def create_hash_table(set_kmer, n):
mphf
=
construction_mphf
(
set_kmer
,
n
)
mphf
=
construction_mphf
(
set_kmer
,
n
)
# Initialiser une table de taille n (liste de n cases)
# Initialiser une table de taille n (liste de n cases)
table
=
[
None
]
*
n
table
=
[
None
]
*
n
# Ici, nous utilisons l'ordre trié pour affecter l'adresse : le perfect hash d'un k-mer
# écrire les kmers aux adresses du tableau données par la mphf
# est sa position dans l'ordre trié.
sorted_kmers
=
sorted
(
list
(
set_kmer
))
sorted_kmers
=
sorted
(
list
(
set_kmer
))
for
kmer
in
set_kmer
:
for
kmer
in
set_kmer
:
index
=
sorted_kmers
.
index
(
kmer
)
index
=
sorted_kmers
.
index
(
kmer
)
table
[
index
]
=
kmer
table
[
index
]
=
kmer
# retourner le tableau et la mphf
return
table
,
mphf
return
table
,
mphf
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment