Numeri interi di "quasi ordinamento" in tempo lineare


16

Sono interessato a ordinare una matrice di valori interi positivi L=v1,,vn in tempo lineare (nel modello RAM con misura del costo uniforme, ovvero, gli interi possono avere dimensioni logaritmiche fino a quando si presume che le operazioni aritmetiche su di essi prendere il tempo unitario). Naturalmente, questo è impossibile con gli algoritmi di ordinamento basati sul confronto, quindi sono interessato a calcolare un ordinamento "approssimativo", cioè calcolare una permutazione vσ(1),,vσ(n) di Lche non è davvero ordinato, in generale, ma una "buona approssimazione" della versione ordinata di L . Presumo che stiamo ordinando gli interi in ordine decrescente perché rende il sequel un po 'più piacevole da affermare, ma ovviamente si potrebbe dire il problema al contrario.

Un possibile criterio per un ordinamento approssimativo è il seguente (*): lasciando che N sia ivi , per ogni 1in , è necessario che vσ(i)N/i (ovvero il "quasi-ordinato "l'elenco è limitato dall'alto dalla funzione decrescente iN/i ). È facile vedere che l'ordinamento attuale soddisfa questo: vσ(2) deve essere maggiore di vσ(1)quindi è al massimo (vσ(1)+vσ(2))/2 che è N/2 , e in generale vσ(i) deve essere maggiore di (jivσ(i))/i che è N/i .

Ad esempio, il requisito (*) può essere raggiunto dall'algoritmo seguente (suggerito da @Louis). La mia domanda è: esiste un lavoro esistente su questo compito di "quasi ordinare" numeri interi in tempo lineare, imponendo alcuni requisiti come (*) che l'ordinamento reale soddisferebbe? L'algoritmo di seguito, o qualche sua variante, ha un nome stabilito?

Modifica: risolto l'algoritmo e aggiunte ulteriori spiegazioni


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
| +
+

Questo algoritmo funziona come previsto per i seguenti motivi:

  1. Se un elemento v è nel bucket j allora vN/j .

    v viene inserito nel bucketj=min(N/v,n) , quindijN/vN/v

  2. Se un elemento v è nel bucket j allora N/(j+1)<v oppure j=n .

    v viene inserito nel bucketj=min(N/v,n) , quindij=N/v oj=n . Nel primo casoj=N/v che significajN/v<j+1 e quindiN/(j+1)<v .

  3. Per j<n , ci sono al massimo j elementi nei bucket da 1 a j .

    Sia j<n e sia k il numero totale di elementi in uno dei bucket 1..j. Per 2. abbiamo che ogni elemento v in un bucket i (con ij ) è tale che N/(j+1)N/(i+1)<v . Pertanto la somma K di tutti gli elementi nei bucket da 1 a j è maggiore di k×N/(J+1) . Ma questa sommaK è anche inferiore aN quindik×N/(j+1)<KN e quindi k/(j+1)<1 che ci dàk<j+1 okj .

  4. T soddisfa (*) cioè l'elementoj -esimo diT è tale cheT[j]N/j

    Per 3. abbiamo che T[j] , l' elemento j -esimo di T , proviene da un bucket i con ij quindi T[j]N/iN/j .

  5. Questo algoritmo richiede tempo lineare.

    Il calcolo di N richiede tempo lineare. I bucket possono essere implementati con un elenco collegato con inserzione e iterazione O(1) . Il ciclo nidificato viene eseguito tante volte quanti sono gli elementi (ovvero n volte).


1
Non scartare la domanda (+1, è una buona domanda) ma Radix Sort non farebbe di più di quello che ti serve?
user541686

@Mehrdad: grazie per il tuo commento! L'ordinamento Radix ordinerebbe gli interi, ma richiederebbe tempo . O(nlog(maxivi))
a3nm,

Potresti commentare ciò che è esattamente indesiderabile in quella complessità temporale? Hai un intero molto grande e tutto il resto è piccolo, per esempio?
user541686

1
@ a3nm l'ordinamento radix non è O (n log n) è O (n) quindi lineare se la dimensione degli interi è fissa, ad esempio numeri a 32 bit o numeri a 64 bit. I numeri che ordinate hanno dimensioni variabili?
Xavier Combelle,

1
@XavierCombelle: Sì, sto lavorando nel modello RAM e non posso supporre che gli interi di input siano limitati da una costante.
a3nm,

Risposte:


8

Sembra molto simile all'algoritmo ASort. Vedi questo articolo di Giesen et. al.:

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

Sfortunatamente, il tempo di esecuzione non è del tutto lineare. L'articolo sopra dimostra che qualsiasi algoritmo randomizzato basato sul confronto che classifica elementi all'interno di n 2 / ν ( n ) ha un limite inferiore di n l o g ( ν ( n ) ) (assumendo ν ( n ) < n ).nn2/ν(n)nlog(ν(n))ν(n)<n


EDIT , in risposta ai chiarimenti nella domanda:

Quello che stai facendo è semplicemente un tipo di secchio . Tuttavia, l'algoritmo per l'ordinamento bucket non è lineare in questo caso. Il problema: devi sommare i numeri naturali e quindi eseguire la divisione su ciascuno di essi. Poiché i numeri hanno dimensioni illimitate, non è più un'operazione a tempo costante. Ci vorrà più tempo per eseguire più numeri che devi sommare.N/V[i]

Quanto ancora? La divisione dipende dal numero di cifre, quindi è , volte n operazioni di divisione. Probabilmente sembra familiare. :)lg(n)n


1
Grazie per averci indicato questo articolo! In effetti è un po 'correlato alla domanda. Tuttavia, il mio algoritmo (né la versione originale né la versione rivista leggermente diversa) non è così simile a ASort ;. Innanzitutto, credo che il mio algoritmo funzioni in , non in tempi superlineari come ASort. In secondo luogo, il criterio (*) è piuttosto diverso dall'approssimare la distanza della regola di Spearman; ad esempio, il criterio (*) è più o meno rigoroso a seconda dei valori degli interi, a differenza della distanza di footrule. In terzo luogo, sia il nostro algoritmo sia ASort sono elementi di bucket, i criteri sono piuttosto diversi. O(n)
a3nm,

@ a3nm Il chiarimento di ciò che hai pubblicato sopra suggerisce che stai usando un ordinamento bucket , che è lineare (e non basato sul confronto, il che significa testare due elementi uno contro l'altro). Il problema è che non funziona per tutti gli interi matematici. Funziona solo se la dimensione intera è limitata.
Trixie Wolf,

Quando dici "Funziona solo se la dimensione del numero intero è limitata", penso che ciò sia vero solo se stavo effettivamente ordinando i numeri interi. Ma in generale l'algoritmo che ho pubblicato in realtà non li ordina, applica solo il criterio più debole (*). Quindi penso che funzioni in tempo lineare anche quando la dimensione intera non è limitata.
a3nm,

2
@ a3nm Non è lineare. Vedi la mia risposta estesa sopra.
Trixie Wolf,

nlogn limite inferiore per effettivo confronto basato ordinamento si applica ancora).
a3nm

2

A quanto pare, la mia domanda è abbastanza irrilevante dopo tutto. In effetti, sto lavorando sulla macchina RAM con una misura del costo uniforme (ovvero, abbiamo registri i cui registri non sono necessariamente di dimensione costante ma possono memorizzare numeri interi di dimensione logaritmica nell'input al massimo e le operazioni su questi registri richiedono un tempo costante, tra cui almeno aggiunta). E in effetti, in questo modello, l'ordinamento di numeri interi (essenzialmente eseguendo un ordinamento radix) può essere fatto in tempo lineare. Ciò è spiegato nell'articolo del 1996 di Grandjean, Ordinamento, tempo lineare e problema di soddisfacibilità .

(This does not answer my question of whether there are well-studied notions of "almost sorting" a set of integers, but for them to be interesting one would probably need these weaker notions to be easier to enforce, i.e., work on a weaker model or somehow run in sublinear time. However, I'm currently not aware of a sense in which this would be the case.)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.