From 77d319bfd3307b33d91f64fc7faf5fc537682b52 Mon Sep 17 00:00:00 2001
From: Antaaa28 <diop2802anta@gmail.com>
Date: Sun, 23 Mar 2025 00:10:22 +0100
Subject: [PATCH]  5 ; 6 ; 7

---
 Readme.md            | 36 ++++++++++++++++++++++++++++--------
 querykmers_tpmiso.py | 30 +++++++++++++++++++++++++++---
 2 files changed, 55 insertions(+), 11 deletions(-)

diff --git a/Readme.md b/Readme.md
index 9ecac6f..60be436 100644
--- a/Readme.md
+++ b/Readme.md
@@ -20,26 +20,46 @@ Vous allez améliorer la situation pour que l'équipe puisse se servir du code d
     __init__(self, bloom_filter=None): Si un bloom_filter est passé en argument lors de l'initialisation, il est utilisé. Sinon un nouveau filtre de Bloom est créé puis continue avec l'initialisation à None des enfants gauche et droite de l'arbre jusqu'à ce qu'ils soient définis. De plus, il y aura une liste vide datasets qui stockera les noms des jeux de données associé à ce noeud.
 
 3. Décrivez à quoi sert `class Structure`. Ecrivez les doctests pour cette classe.
+Cette classe construit un arbre binaire dont chaque feuille correspond à un jeu de données.
+Chaque feuille contient un filtre de Bloom créé à partir des k-mers propres à ce jeu de données.
+Les nœuds internes fusionnent les filtres de Bloom de leurs enfants (par opération OU bit à bit)
+et regroupent l'ensemble des noms des jeux de données correspondant.
+La méthode 'query' permet de rechercher un k-mer dans l'arbre et retourne la liste des jeux de données
+susceptibles de le contenir.
 
 4. Cette structure mélange donc deux structures de données que nous avons vues. Quelles sont elles ?
-
------
-### La stucture Structure mélange deux structures de données principales:
-
-*** 1-Filtre de Bloom:
+La structure combine essentiellement :
+1-Les Tables de hachage via le filtre de bloom
 Utilisé pour représenter les k-mers de chaque jeu de données. Le filtre de Bloom permet de tester
 rapidement si un k-mer est potentiellement présent dans un jeu de donnnées, avec un certain taux de
 faux positifs.
 
-
-*** 2-Arbre binaire:
+2- Les arbre :
 La structure est organisée sous forme d'arbre binaire, où chaque noeud interne présente l'union
 des filtres de Bloom de ses enfants. Les feuilles de l'arbre correspondent aux jeux de données
 individuels.
------
 
 5.D'après vous, que peut-on dire sur la complexité de la requête de cette structure ? 
+La complexité de la requête dépend de l'efficacité du filtre de Bloom. Si le filtre ne produit pas de faux positifs, 
+la recherche suit un chemin unique dans un arbre équilibré, soit O(log N). 
+En cas de faux positifs, plusieurs branches inutiles peuvent être explorées, ce qui peut dégrader la complexité jusqu'à O(N).
 
 6.Quelles sont les différences avec la table basée sur une MPHF que nous avons vu ? 
+La principale différence réside dans la nature des structures :
+
+En terme d'exactitude :
+La table basée sur une MPHF fournit un accès exact aux k-mers sans faux positifs,
+tandis que la structure avec filtres de Bloom et arbre est probabiliste et peut donner des faux positifs.
+
+Complexité de la requête :
+La MPHF permet un accès en temps constant (O(1)) une fois la table construite,
+alors que la recherche dans la structure hybride est, dans le meilleur des cas, logarithmique (O(log N)) et peut se dégrader en linéaire (O(N)) en cas de nombreux faux positifs.
+
+Mémoire et construction :
+La MPHF est adaptée à des ensembles statiques et optimise l'espace en évitant les collisions par construction itérative.
+La structure Bloom/arbre, quant à elle, offre une organisation hiérarchique facilitant la fusion d'indices
+mais au prix d'une imprécision probabiliste et d'une complexité potentiellement plus élevée en cas d'erreurs.
 
 7.Bonus : Pouvez-vous retracer de quel papier de bioinformatique vient cette idée ?
+Cette approche – combiner des filtres de Bloom avec une structure arborescente pour indexer des k-mers – a été popularisée par les travaux sur les Sequence Bloom Trees (SBT). 
+Dans ce papier, Solomon et Kingsford ont proposé d’organiser des Bloom filters dans un arbre afin de faciliter la recherche rapide dans de vastes bases de données de séquençage.
\ No newline at end of file
diff --git a/querykmers_tpmiso.py b/querykmers_tpmiso.py
index 1618d4c..16dbf68 100644
--- a/querykmers_tpmiso.py
+++ b/querykmers_tpmiso.py
@@ -104,7 +104,7 @@ class Structure:
 	def _build_tree(self, datasets, kmers_dict, bloom_size, num_hashes):
 		nodes = []
 
-		# Step 1
+		# Step 1 : # Création des feuilles pour chaque jeu de données
 		for dataset in datasets:
 			bf = SimpleBloomFilter(bloom_size, num_hashes)
 			for kmer in kmers_dict[dataset]:
@@ -114,7 +114,7 @@ class Structure:
 			self.leaves[dataset] = node
 			nodes.append(node)
 
-		# Step 2
+		# Step 2 : Fusion itérative des nœuds pour construire l'arbre
 		while len(nodes) > 1:
 			new_nodes = []
 			for i in range(0, len(nodes), 2):
@@ -132,6 +132,30 @@ class Structure:
 		return nodes[0] if nodes else None  
 
 	def query(self, kmer):
+		"""
+		Recherche un k-mer dans l'arbre et retourne la liste des jeux de données
+		susceptibles de le contenir.
+
+		Exemple d'utilisation:
+		>>> datasets = ["DS1", "DS2", "DS3"]
+		>>> kmers_dict = {
+		...   "DS1": ["AAA", "CCC"],
+		...   "DS2": ["GGG", "TTT"],
+		...   "DS3": ["CCC", "GGG"]
+		... }
+		>>> s = Structure(datasets, kmers_dict, bloom_size=10, num_hashes=1)
+		>>> sorted(s.query("CCC"))
+		['DS1', 'DS3']
+		>>> sorted(s.query("GGG"))
+		['DS2', 'DS3']
+		>>> s.query("AAA")
+		['DS1']
+		>>> s.query("TTT")
+		['DS2']
+		>>> s.query("XYZ")
+		[]
+		"""
+
 		results = []
 		self._query_recursive(self.root, kmer, results)
 		return results
@@ -139,7 +163,7 @@ class Structure:
 	def _query_recursive(self, node, kmer, results):
 		if node is None:
 			return
-		if node.bloom.contains(kmer): 
+		if node.bloom.contains(kmer):   # Si le nœud est une feuille, ajouter directement les jeux de données
 			if node.left is None and node.right is None: 
 				results.extend(node.datasets)
 			else:
-- 
GitLab