Je souhaite trier un tableau de valeurs entières positives en temps linéaire (dans le modèle RAM avec mesure de coût uniforme, c'est-à-dire que les entiers peuvent avoir jusqu'à la taille logarithmique mais les opérations arithmétiques sur eux sont supposées prendre le temps unitaire). Bien sûr, cela est impossible avec des algorithmes de tri basés sur la comparaison, donc je suis intéressé par le calcul d'un tri "approximatif", c'est-à-dire le calcul d'une permutation de qui est pas vraiment triés en général , mais une « bonne approximation » de la version triée de . Je suppose que nous trions les entiers par ordre décroissant car cela rend la suite un peu plus agréable à énoncer, mais bien sûr, on pourrait formuler le problème dans l'autre sens.
Un critère possible pour un tri approximatif est le suivant (*): laisser soit , pour chaque , nous exigeons que (c. -à- la « quasi-triai "La liste est délimitée par le haut par la fonction décroissante ). Il est facile de voir que le tri réel satisfait à ceci: doit pas être supérieur à c'est donc au plus qui est , et en général doit pas être supérieur à qui est .
Par exemple, l'exigence (*) peut être obtenue par l'algorithme ci-dessous (suggéré par @Louis). Ma question est la suivante: existe-t-il un travail sur cette tâche de "tri presque" des entiers en temps linéaire, en imposant une exigence comme (*) que le tri réel satisferait? L'algorithme ci-dessous, ou une variante de celui-ci, a-t-il un nom établi?
Edit: correction de l'algorithme et ajout de plus d'explications
Algorithme:
INPUT: V an array of size n containing positive integers
OUTPUT: T
N = Σ_{i<n} V[i]
Create n buckets indexed by 1..n
For i in 1..n
| Add V[i] into the bucket min(floor(N/V[i]),n)
+
For bucket 1 to bucket n
| For each element in the bucket
| | Append element to T
| +
+
Cet algorithme fonctionne comme prévu pour les raisons suivantes:
- Si un élément est dans le seau alors .
- Si un élément est dans le seau alors ou .
j = min ( N / v , n ) j = ⌊ N / est placé dans le seau , donc ou . Dans le premier cas qui signifie et donc .
Pour , il y a, au plus, éléments dans les godets de 1 à .
Soit et soit le nombre total d'éléments dans l'un des compartiments 1..j. Par 2. nous avons que chaque élément dans un seau (avec ) est tel que . Par conséquent, la somme de tous les éléments dans les godets de à est supérieure à . Mais cette somme est également inférieure à donc et donc ce qui nous donne ou .
vérifie (*)dire la -ième élément de est telle que
Par 3. nous avons que , le ème élément de , provient d'un seau avec donc .
Cet algorithme prend du temps linéaire.
Le calcul de prend un temps linéaire. Les compartiments peuvent être implémentés avec une liste chaînée qui a une insertion et une itération . La boucle imbriquée s'exécute autant de fois qu'il y a d'éléments (c'est-à-dire fois).
Réponses:
Cela ressemble beaucoup à l'algorithme ASort. Voir cet article de Giesen et. Al.:
https://www.inf.ethz.ch/personal/smilos/asort3.pdf
Malheureusement, le temps de course n'est pas tout à fait linéaire. L'article ci-dessus prouve que tout algorithme randomisé basé sur une comparaison classant éléments dans n 2 / ν ( n ) a une borne inférieure de n ∗ l o g ( ν ( n ) ) (en supposant ν ( n ) < n ).n n2/ν(n) n∗log(ν(n)) ν(n)<n
EDIT , en réponse aux clarifications de la question:
Ce que vous faites est simplement une sorte de seau . Cependant, l'algorithme de tri par compartiment n'est pas linéaire dans ce cas. Le problème: vous devez additionner les nombres naturels puis effectuer la division sur chacun d'eux. Comme les nombres n'ont pas de taille illimitée, n'est plus une opération à temps constant. Il faudra plus de temps pour effectuer le plus de nombres que vous devez additionner.N/V[i]
Encore combien de temps? La division dépend du nombre de chiffres, c'est donc , fois n opérations de division. Cela semble probablement familier. :)lg(n) n
la source
Il s'avère que ma question est tout à fait hors de propos après tout. En effet, je travaille sur la machine RAM avec une mesure de coût uniforme (c'est-à-dire que nous avons des registres dont les registres ne sont pas nécessairement de taille constante mais peuvent stocker des entiers de taille logarithmique au plus en entrée, et les opérations sur ces registres prennent un temps constant, y compris au moins addition). Et en fait, dans ce modèle, le tri des entiers (en effectuant essentiellement un tri radix) peut être effectué en temps linéaire. Ceci est expliqué dans l'article de 1996 de Grandjean, Sorting, temps linéaire et problème de satisfiabilité .
(Cela ne répond pas à ma question de savoir s'il existe des notions bien étudiées de "presque trier" un ensemble d'entiers, mais pour qu'elles soient intéressantes, il faudrait probablement que ces notions plus faibles soient plus faciles à appliquer, c'est-à-dire, travailler sur un plus faible modèle ou en quelque sorte exécuté en temps sublinéaire. Cependant, je ne suis actuellement pas au courant d'un sens dans lequel ce serait le cas.)
la source