Estou interessado em classificar uma matriz de valores inteiros positivos em tempo linear (no modelo de RAM com medida de custo uniforme, ou seja, números inteiros podem ter tamanho logarítmico, mas presume-se que as operações aritméticas nelas tempo da unidade). Obviamente, isso é impossível com algoritmos de classificação baseados em comparação, por isso estou interessado em calcular uma classificação "aproximada", isto é, calcular alguma permutação de que não é realmente classificado em geral, mas uma "boa aproximação" da versão classificada de. Suponho que estamos ordenando os números inteiros em ordem decrescente, pois isso torna a sequência um pouco mais agradável de declarar, mas é claro que se poderia dizer o problema da outra maneira.
Um critério possível para uma classificação aproximada é o seguinte (*): deixando ser , para cada , exigimos que (ou seja, a lista "quase ordenada" é delimitada de cima pela função decrescente ). É fácil ver que a classificação real satisfaz isso: deve ser maior que portanto, é no máximo que é e, em geral, deve ser maior que que é.
Por exemplo, o requisito (*) pode ser alcançado pelo algoritmo abaixo (sugerido por @Louis). Minha pergunta é: Existe trabalho existente nessa tarefa de "quase classificar" números inteiros em tempo linear, impondo algum requisito como (*) que a classificação real satisfaria? O algoritmo abaixo, ou alguma variante dele, tem um nome estabelecido?
Edit: corrigido o algoritmo e adicionado mais explicações
Algoritmo:
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
| +
+
Esse algoritmo funciona conforme planejado pelos seguintes motivos:
- Se um elemento estiver no balde então .
- Se um elemento estiver no intervalo então ou .
j = min ( N / v , n ) j = ⌊ N / v ⌋ j = n j = ⌊ N / v ⌋ j ≤ N / v < j + 1 N / ( j + 1 ) < v é colocado no balde , assim ou . No primeiro caso, que significa e, portanto, .
Para , existem, no máximo, elementos nos buckets de 1 a .
Seja e seja o número total de elementos em um dos blocos 1..j. Por 2. temos que todo elemento em um balde (com ) é tal que . Portanto, a soma de todos os elementos nos buckets de a é maior que . Mas essa soma também é menor que portanto, e, portanto, que nos dá ou .v i i ≤ j N / ( j + 1 ) ≤ N / ( i + 1 ) < v K 1 j k × N / ( J + 1 ) K N k × N / ( j + 1 ) < K ≤ N k / ( j + 1 ) 1
satisfaz (*) ou seja, o ésimo elemento de é tal que
Por 3. temos que , o ésimo elemento de , vem de um balde com portanto .
Esse algoritmo leva tempo linear.
A computação de leva tempo linear. Os buckets podem ser implementados com uma lista vinculada que possui inserção e iteração . O loop aninhado é executado quantas vezes houver elementos (ou seja, vezes).