"Quase classificando" números inteiros em tempo linear

16

Estou interessado em classificar uma matriz de valores inteiros positivos L=v1,,vn 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 devσ(1),,vσ(n)LL. 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 éNivi1invσ(i)N/iiN/ivσ(2)vσ(1)(vσ(1)+vσ(2))/2N/2vσ(i)(jivσ(i))/iN/i.

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:

  1. Se um elemento v estiver no balde j então vN/j .

    vj=min(N/v,n)jN/vN/v

  2. Se um elemento estiver no intervalo então ou . vjN/(j+1)<vj=n

    vj = 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, .j=min(N/v,n)j=N/vj=nj=N/vjN/v<j+1N/(j+1)<v

  3. Para , existem, no máximo, elementos nos buckets de 1 a .j<njj

    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 .j<nkv 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 ) 1viijN/(j+1)N/(i+1)<vK1jk×N/(J+1)KNk×N/(j+1)<KNk/(j+1)<1k<j+1kj

  4. T satisfaz (*) ou seja, o ésimo elemento de é tal quejTT[j]N/j

    Por 3. temos que , o ésimo elemento de , vem de um balde com portanto .T[j]jTiijT[j]N/iN/j

  5. 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).NO(1)n

a3nm
fonte
11
Para não descartar a pergunta (+1, é uma boa), mas a classificação por radix não faria mais do que o necessário?
user541686
@ Mehrdad: Obrigado pelo seu comentário! A classificação Radix classificaria os números inteiros, mas levaria tempo . O(nlog(maxivi))
a3nm
Você poderia comentar o que exatamente é indesejável nessa complexidade de tempo? Você tem um número inteiro muito grande e todo o resto é pequeno, por exemplo?
user541686
11
@ a3nm radix sort não é O (n log n), é O (n), portanto, linear se o tamanho de números inteiros for fixo, por exemplo, números de 32 bits ou números de 64 bits. Os números que você classifica têm tamanho variável?
Xavier Combelle
11
@XavierCombelle: Sim, estou trabalhando no modelo de RAM e não posso supor que os números inteiros de entrada sejam limitados por uma constante.
a3nm

Respostas:

8

Isso parece muito com o algoritmo ASort. Veja este artigo de Giesen et. al .:

https://www.inf.ethz.ch/personal/smilos/asort3.pdf

Infelizmente, o tempo de execução não é linear. O artigo acima prova que qualquer algoritmo aleatório à base de comparação Classificação itens dentro de N 2 / ν ( n ) tem um limite inferior de N * l o g ( ν ( n ) ) (assumindo ν ( n ) < n ).nn2/ν(n)nlog(ν(n))ν(n)<n


EDIT , em resposta aos esclarecimentos da pergunta:

O que você está fazendo é simplesmente uma espécie de balde . No entanto, o algoritmo para classificação de buckets não é linear nesse caso. O problema: você precisa somar os números naturais e, em seguida, realizar a divisão em cada um deles. Como os números são ilimitados em tamanho, não é mais uma operação de tempo constante. Levará mais tempo para realizar o maior número de números que você precisa somar.N/V[i]

Quanto tempo mais? A divisão depende do número de dígitos; portanto, é , vezes n operações de divisão. Provavelmente isso parece familiar. :)lg(n)n

Trixie Wolf
fonte
11
Obrigado por nos indicar este artigo! Na verdade, está um pouco relacionado à questão. No entanto, meu algoritmo (nem a versão original nem a versão revisada ligeiramente diferente) não é tão semelhante ao ASort ;. Primeiro, acredito que meu algoritmo é executado em , não em tempo superlinear como o ASort. Segundo, o critério (*) é bem diferente de aproximar a distância da regra de Spearman; por exemplo, o critério (*) é mais ou menos restrito, dependendo dos valores dos números inteiros, diferentemente da distância da regra do pé. Terceiro, embora nosso algoritmo e ASort sejam elementos de bucket, os critérios são bem diferentes. O(n)
a3nm
@ a3nm O esclarecimento do que você postou acima sugere que você está usando uma classificação de bucket , que é linear (e não baseada em comparação, o que significa testar dois itens um contra o outro). O problema é que ele não funciona para todos os números matemáticos. Só funciona se o tamanho inteiro estiver delimitado.
Trixie Wolf
Quando você diz "Funciona apenas se o tamanho inteiro estiver delimitado", acho que isso só é verdade se eu estivesse realmente classificando os números inteiros. Mas, em geral, o algoritmo que publiquei na verdade não os classifica, apenas reforça o critério mais fraco (*). Então, eu acho que é executado em tempo linear, mesmo quando o tamanho inteiro não é limitado.
a3nm
2
@ a3nm Não é linear. Veja minha resposta expandida acima.
Trixie Wolf
Obrigado pela resposta e desculpe-me pelo atraso. Eu acho que há alguma confusão sobre o modelo. Estou trabalhando no modelo de RAM com medida de tempo uniforme (como em van Emde Boas, Modelos de máquina e simulações, no Manual de computação): portanto, os números que manipulo podem ter tamanho logarítmico, mas as operações aritméticas nesses números têm custo unitário. Eu editei minha pergunta de acordo. Penso que, neste modelo, o algoritmo que proponho realmente é executado em tempo linear (mas, é claro, nesse modelo o limite inferior para a classificação baseada em comparação real ainda se aplica). nlogn
a3nm
2

Afinal, minha pergunta é bastante irrelevante, afinal. Na verdade, estou trabalhando na máquina de RAM com uma medida de custo uniforme (ou seja, temos registradores cujos registros não são necessariamente de tamanho constante, mas podemos armazenar números inteiros de tamanho logarítmico na entrada, no máximo, e as operações nesses registradores levam tempo constante, incluindo pelo menos adição). E, de fato, neste modelo, a classificação de números inteiros (executando essencialmente uma classificação de raiz) pode ser feita em tempo linear. Isso é explicado no artigo de 1996 por Grandjean, Sorting, tempo linear e o problema de satisfação .

(Isso não responde à minha pergunta sobre se existem noções bem estudadas de "quase classificar" um conjunto de números inteiros, mas, para que sejam interessantes, provavelmente seria necessário que essas noções mais fracas fossem mais fáceis de aplicar, ou seja, trabalhe em uma mais fraca modelo ou de alguma forma executado no tempo sublinear. No entanto, atualmente não estou ciente de um sentido em que esse seria o caso.)

a3nm
fonte