Je recherche des algorithmes de tri qui peuvent fonctionner sur une grande quantité de données, c'est-à-dire qui peuvent fonctionner même lorsque l'ensemble de données ne peut pas être conservé dans la mémoire principale à la fois.
Le seul candidat que j'ai trouvé jusqu'à présent est le tri par fusion: vous pouvez implémenter l'algorithme de telle sorte qu'il analyse votre ensemble de données à chaque fusion sans conserver toutes les données dans la mémoire principale à la fois. La variation du type de fusion que j'ai en tête est décrite dans cet article dans la section Utilisation avec les lecteurs de bande .
Je pense que c'est une bonne solution (avec une complexité O (n x log (n)) mais je suis curieux de savoir s'il existe d'autres algorithmes de tri (éventuellement plus rapides) qui peuvent fonctionner sur de grands ensembles de données qui ne tiennent pas dans la mémoire principale.
[~ # ~] modifier [~ # ~]
Voici quelques détails supplémentaires, comme requis par les réponses:
Une amélioration possible que j'avais à l'esprit était de diviser le fichier en fichiers suffisamment petits pour être triés en mémoire, et enfin de fusionner tous ces fichiers en utilisant l'algorithme que j'ai décrit ci-dessus.
La référence canonique sur le tri et la recherche est Knuth, Vol. . Commencez par là.
Le livre a été écrit à l'origine lorsque les ordinateurs étaient beaucoup plus petits et plus lents qu'aujourd'hui, ce qui rendait les techniques de tri hors mémoire plus importantes qu'elles ne le semblent aujourd'hui.
Fusion R-Way externe comme dans la commande UNIX sort
est une bonne alternative. D'après votre formulation, je ne suis pas sûr que ce soit l'algorithme que vous vouliez dire avec "merge sort", et si vous ne le connaissez pas, jetez un œil.
Sans plus de détails, "Merge Sort" est probablement la meilleure réponse que vous obtiendrez, mais vous pouvez implémenter quelque chose de beaucoup plus intelligent en fonction de vos besoins.
Par exemple, pouvez-vous simplement créer un index en mémoire du fichier, puis copier toutes les valeurs à la fois, en mettant en cache l'emplacement des différentes valeurs clés? Est-ce que 1/2 tient en mémoire à la fois, ou 1/1000000? Si c'est le deuxième, vous ne pourrez peut-être pas ajuster un index en mémoire, si le premier, vous pouvez trier les deux moitiés plus efficacement, puis les fusionner ensemble en une seule dernière étape.
Enfer, puisque vous ne l'avez pas spécifié, il est possible que vos données soient toutes dans une base de données, si c'est le cas, vous pouvez simplement créer une table d'index et l'appeler bien (je suppose que ce n'est pas le cas, mais juste en soulignant que votre situation est critique pour résoudre un problème compliqué comme celui-ci).
Si vous voulez le faire une seule fois et que vous recherchez un hack très rapide, il semble que ce type de fusion externe serait un bon début si vous exécutez Unix (car il est apparemment intégré)
Si vous devez le garder dans l'ordre et que vous ajoutez toujours un seul enregistrement, un tri par insertion sera nécessaire (l'ajout d'un seul enregistrement aux données triées est toujours un tri par insertion).
Pouvez-vous contrôler le code qui "lit" les données? Si c'est le cas, de nombreuses formes d'indexation (plutôt que de trier en déplaçant les données sur le disque) aideront BEAUCOUP (ce sera en fait une exigence absolue).
Donc:
Si vous voulez vraiment une solution évolutive, vous devriez jeter un œil à TeraSort, l'implémentation de tri standard avec map-Reduce; plus de détails sur StackOverflow .
Vous pourriez être intéressé par un tri par sea . La performance moyenne d'un cas est un temps linéaire.
= O (n + d) n: nombre d'éléments et d = longueur du plus grand nombre si vous avez une intuition à propos de vos données ie. Si vous savez combien de "chiffres" est votre plus grand nombre. Donc, si vous avez 2 millions de nombres à 6 chiffres => 0(n) donc linéaire.
Utilisez un algorithme de tri par fusion externe (si vos données sont des continuos), ou un tri par compartiment avec tri par comptage comme implémentation du tri pour les compartiments (si vos données sont discrètes et réparties uniformément ).
La meilleure approche est probablement de créer votre propre fichier d'index/mapping si l'incrément est petit.
Je viens de construire des structures abstraites appelées grande file d'attente et grand tableau pour simplifier le tri des données volumineuses et la tâche de recherche sur une seule machine avec une mémoire limitée. Fondamentalement, l'algorithme utilisé est similaire à celui que vous avez mentionné ci-dessus - tri par fusion externe.
Je peux trier 128 Go de données (chaque élément de 100 octets) en 9 heures sur une seule machine, puis rechercher en binaire les données triées en un rien de temps.
Ici est un article sur la recherche de données volumineuses en utilisant ma grande file d'attente open source et les grandes structures de tableaux.