C'est délicat à obtenir le droit en général, en particulier pour gérer les dégénérés de la série qui sont déjà triées, ou avoir un tas de valeurs au "début" de la liste, mais la fin de la liste a des valeurs dans une plage différente.
L'idée de base de faire un histogramme qui est le plus prometteur. Cela vous permet d'accumuler de l'information sur la distribution et de répondre à des requêtes (comme la médiane) de celui-ci. La médiane sera approximatifs, car manifestement, vous n'avez pas de stocker toutes les valeurs. L'espace de stockage est fixé afin qu'il fonctionne avec n'importe quelle longueur de la séquence que vous avez.
Mais vous ne pouvez pas construire un histogramme de dire que les 100 premières valeurs et de l'utilisation de l'histogramme en permanence.. la modification des données peut faire l'histogramme invalide. Si vous avez besoin d'une dynamique de l'histogramme de changer de gamme et les poubelles à la volée.
Faire une structure qui a la N des bacs. Vous allez stocker la valeur X de chaque logement de transition (N+1 valeurs total) ainsi que de la population de la corbeille.
Flux de données. Le premier N+1 valeurs. Si le flux se termine avant cette, grande, vous avez toutes les valeurs chargé et vous pouvez trouver exactement la même médiane et le retourner. Bien utiliser les valeurs à définir votre première histogramme. Juste trier les valeurs et les utiliser comme corbeille de définitions, chaque cellule ayant une population de 1. C'est OK d'avoir des dupes (0 largeur des bacs).
Maintenant, flux de nouvelles valeurs. Pour chacun, binaire de recherche pour trouver le bin il appartient.
Dans la plupart des cas, vous avez juste incrémenter la population de ce bac et continuer.
Si votre échantillon est au-delà de l'histogramme bords (plus haut ou plus bas), il suffit de prolonger la fin de la corbeille de la gamme de l'inclure.
Lorsque votre flux est fait, vous pouvez trouver la médiane de l'échantillon valeur par trouver le bin qui a l'égal de la population sur les deux côtés, et l'interpolation linéaire le reste bin-largeur.
Mais cela ne suffit pas.. vous avez encore le besoin d'ADAPTER l'histogramme à des données d'être transmises. Lorsqu'une cellule devient de plus plein, vous êtes la perte d'information à ce sujet bin sous la distribution.
Vous pouvez résoudre ce problème en adaptant basée sur certaines heuristiques... Le plus simple et le plus fiable est de savoir si un bac atteint un certain seuil de population (quelque chose comme 10*v/N v= nombre de valeurs vu jusqu'à présent dans le flux, et N est le nombre de poubelles), vous divisez le trop plein de la corbeille. Ajouter une nouvelle valeur à mi-chemin de la poubelle, donnez à chaque côté de la moitié de l'original de la corbeille de la population. Mais maintenant, vous avez trop de poubelles, de sorte que vous besoin de SUPPRIMER une poubelle. Une bonne heuristique pour ce qui est de trouver la poubelle avec le plus petit produit de la population et de la largeur. De le supprimer et de le fusionner avec de sa la gauche ou la droite voisin (celui des voisins lui-même a le plus petit produit de la largeur et de la population.). Fait!
Notez que la fusion ou de la séparation des bacs de perdre de l'information, mais qui est inévitable.. vous n'avez de stockage fixe.
Cet algorithme est agréable en ce qu'elle permettra de traiter tous les types de flux d'entrée et de donner de bons résultats. Si vous avez le luxe de choisir l'ordre d'échantillon, un échantillon aléatoire est le meilleur, car qui minimise les scissions et fusions.
L'algorithme permet également d'interroger n'importe quel percentile, et pas seulement médiane, puisque vous avez une distribution complète estimation.
J'utilise cette méthode dans mon propre code dans de nombreux endroits, surtout pour les journaux de débogage.. où certaines stats que vous enregistrez sont inconnus de la distribution. Avec cet algorithme, vous n'avez pas besoin de deviner à l'avance.
L'inconvénient, c'est l'inégalité de bin largeurs signifie que vous avez à faire une recherche binaire pour chaque échantillon, de sorte que votre net de l'algorithme est O(NlogN).