Algorithme de Flajolet et Martin
# Algorithme de Flajolet et Martin

L'algorithme de Flajolet et Martin est un algorithme donnant une estimation du nombre d'éléments distincts dans un flot, en une seule passe et avec une complexité logarithmique en mémoire, proportionnelle au nombre maximum d'éléments distincts. Cet algorithme a été inventé en 1984 par Philippe Flajolet and G. Nigel Martin, puis amélioré par Marianne Durand et Philippe $Flajolet^,.$ C'est un algorithme de fouille de flots de données (streaming).

En 2010, Daniel M. Kane, Jelani Nelson et David P. Woodruff ont proposé un algorithme avec une complexité spatiale presque optimale et un coût de modification en O(1).

## L'algorithme

L'algorithme nécessite une fonction de hashage $hash(x)$, associant à une entrée $x$ un entier dans $[0,2^{L}-1]$, dont les images sont uniformément réparties. L'ensemble des entiers de 0 à $2^{L}-1$ correspond en fait à l'ensemble des chaînes binaires de longueur $L$.

Étant donné un entier positif $y$, on note $bit(y,k)$ le $k$-ème bit dans la représentation binaire de $y$, de sorte que :

    $y=\sum _{k\geq 0}{\text{bit}}(y,k)2^{k}$

On définit ensuite une fonction $\rho (y)$ qui associe à y la position du bit de poids faible dans sa représentation binaire :

    $\rho (y)=\min _{k\geq 0}{\text{bit}}(y,k)\neq 0$

avec $\rho (0)=L$. Par exemple, $\rho (13)=\rho (1101)=0$ car le premier bit est non nul, alors que $\rho (8)=\rho (0100)=2$ avec le bit de poids faible en troisième position. Étant donné que les images de la fonction de hashage sont uniformément réparties, la probabilité d'observer un nombre finissant par $2^{k}$ (un 1 suivi de $k$ zéros) est $2^{-(k+1)}$ et correspond à tirer $k$ piles suivi d'un face en lançant une pièce de monnaie équilibrée.

### Description de l'algorithme

Algorithme de Flajolet-Martin — L'algorithme de Flajolet–Martin estime la cardinalité d'un multiensemble $M$ de la manière suivante :

* Initialiser un vecteur BITMAP contenant $L$ zéros.
* Pour chaque élément $x$ dans $M$, effectuer :
   * $index=\rho ({\text{hash}}(x))$,
   * $BITMAP[index]=1$.
* On note $R$ le plus petit indice $i$ tel que $BITMAP[i]=0$.
* La cardinalité de $M$ est approchée par $2^{R}/\phi$ avec $\phi \approx 0.77351$.

### Commentaires

Avec $n$ le nombre d'éléments distincts de $M$, alors $BITMAP[0]$ est accédé environ $n/2$ fois, $BITMAP[1]$ accédé $n/4$ fois, etc. Ainsi, si $i\gg \log _{2}n$, $BITMAP[i]$ vaut certainement 0, de même que si $i\ll \log _{2}n$, $BITMAP[i]$ vaut certainement 1. Si $i\approx \log _{2}n$ alors $BITMAP[i]$ vaut soit 1 soit 0.

Les calculs pour obtenir le facteur de correction $\phi \approx 0.77351$ sont détaillés dans l'article de Flajolet et Martin.

