Ordinamento usando una scatola nera


20

Supponiamo di voler ordinare un elenco di numeri reali. Supponiamo che ci venga data una scatola nera che può ordinare istantaneamente numeri reali. Quanto vantaggio possiamo ottenere usando questa scatola nera?n Snn

Ad esempio, possiamo ordinare i numeri con solo chiamate nella casella nera? Il miglior algoritmo che ho trovato utilizza chiamate alla scatola nera. Ma non sono stato in grado di migliorarlo ulteriormente. Ecco il mio algoritmo che è simile a merge-sort:nO(n)n

Per prima cosa partiziona l'elenco in lists con approssimativamente dimensioni. Quindi usa chiamate alla casella nera per ordinare questi elenchi. Infine, unisci gli elenchi ordinati utilizzando la casella nera come segue:S s1,s2,. . . ,sns1,s2,...,snnn

Inserisci gli elementi più piccoli degli elenchi in un nuovo elenco , quindi chiama la casella nera per ordinarlo. Il numero in (primo e più piccolo elemento di ) sarà il numero più piccolo in . Possiamo metterlo al primo posto dell'elenco di output. Supponendo che l'elemento è stato scelto da , sostituiamo con il secondo elemento più piccolo di elenco di ordinamento , e di nuovo corre la scatola nera su di esso per calcolare il secondo più piccolo membro della . Continuiamo fino a quando tutti gli elementi non vengono ordinati. Il numero totale di chiamate a scatola nera per questa parte saràL [ 1 ] L S s j L [ 1 ] s j S n - LL[1]LS
sjL[1]sjS
nn. Pertanto nel complesso il numero totale di chiamate sarà .n

D'altra parte, sembra che dovremmo essere in grado di ottenere un limite inferiore utilizzando il limite inferiore sui confronti numerici necessari per l'ordinamento come segue: Possiamo implementare la scatola nera usando confronti. Se riusciamo a risolvere il problema con chiamate alla scatola nera e fondendoci in tempo lineare possiamo ordinare numeri reali con confronti di che è impossibile.o(nlgn=12nlgnnO(nlgn)o(n)no(nlgn)

Immagino che potremmo dimostrare che è un limite inferiore per il numero di chiamate alla scatola nera, dal momento che molti confronti che usano nella scatola nera sarebbero condivisi e quindi vengono raccontati nel nostro argomento.Ω(n)

AGGIORNAMENTO: Come suggeriscono gli altri post, è anche possibile ottenere un .nlgn


2
Sembra che ci sia un refuso nel tuo commento. Intendevi dire: "nessun algoritmo che usa meno di chiamate alla macchina può ordinare numeri reali con meno di confronti"? ps: dovresti anche stare attento al fatto che il limite inferiore vale solo per gli algoritmi di ordinamento basati sul confronto. NNlgNNlgNNNNlgNNlgN
Kaveh,

8
Penso che possiamo persino ottenere usando la rete di smistamento di AKS. La loro rete può essere pensata come un'istanza del tuo modello in cui la scatola nera può ordinare i blocchi di dimensione 2. I loro algoritmi usano i round , ogni round chiamando i tempi 2 sorter . Un "giro" di sorter di 2 può essere facilmente simulato con -sorter. O(logn)O(n)O(n)O(O(nlogn)O(logn)O(n)O(n)O(n) n
Vinayak Pathak,

6
@VinayakPathak: suddividere i dati di input in blocchi di dimensioni , quindi ordinare i blocchi utilizzando la rete AKS, dopo aver sostituito ciascun comparatore con un -sorter. 2NN/2N
Jeffε

1
@ Jɛ ff E: Sì, fantastico, sembra decisamente più semplice della mia costruzione.
Vinayak Pathak,

1
@ Jɛ ff E, i tuoi commenti possono essere una risposta. :)
Kaveh

Risposte:


15

È possibile ordinare con chiamate alla casella nera e nessun confronto.O(nlogn)

Innanzitutto, considera il seguente problema di partizionamento bilanciato: dati elementi (dove ), partizionali in due gruppi, la dimensione più piccola almeno di circa , quindi che tutti gli elementi nel primo gruppo sono più piccoli di tutti gli elementi nel secondo gruppo. Questo può essere fatto con chiamate alla casella nera. (Lo descriverò più avanti.) Quindi usa quicksort con questo algoritmo di partizionamento:A [ 1 .. m ] mA[1..m]m/4O(m/nmnm/4O(m/n)

def qsort(A[1..m]):
   if m < sqrt(n): sort A with one call to the black box
   else:
     Partition A[1..m] into two groups as described above.
     Recursively qsort the first group.
     Recursively qsort the second group.

Supponendo che ogni passaggio della partizione porti chiamate alla scatola nera, l'algoritmo sopra, dato l'input , effettuerà chiamate alla scatola nera, perché l'albero di ricorsione ha profondità e ogni livello dell'albero ha un totale di chiamate alla casella nera.A[1 ..n]O(O(m/n)A[1..n]O(logn)O(n/O(nlogn)O(logn)O(n/n)=O(n)

Eseguire il passaggio di partizionamento come segue:

def partition(A[1..m]):  (where sqrt(n) <= m <= n)
   Divide A into m/sqrt(n) groups of size sqrt(n) each.
   Sort each group with one call to the black box per group.
   Sort the medians of the groups with one call to the black box.
   (Note the number of groups is less than sqrt(n), because m <= n.)
   Let X be the median of the medians.
   Partition all m elements around X, using the black box as follows:
      For each group G, let Y be its median:
        Call the black box once on (G - {Y}) union {X}.
        (This gives enough information to order all elts w.r.t. X.)

Nell'ultimo passaggio della partizione algoritmo (): "Partiziona tutti gli elementi m attorno a X", questo non utilizzerà m ulteriori confronti?
Vinayak Pathak,

2
Vedi la linea che segue solo l'algoritmo, spiega come fare quel passo. Lo modificherò per renderlo più chiaro.
Neal Young,

24

Penso che la tua domanda sia stata affrontata nel documento di Beigel e Gill " Ordinamento di n oggetti usando k-sorter " del 1990 e l'abstract del documento dice tutto:

Un sorter k è un dispositivo che ordina gli oggetti k in unità di tempo. La complessità di un algoritmo che utilizza un sorter k è definita come il numero di applicazioni del sorter k. In questa misura, la complessità dell'ordinamento di n oggetti è compresa tra e4nlognnlognklogk , fino ai termini del primo ordine in n e k.4nlognklogk


Grazie. Non sono riuscito a trovare il giornale. Potete fornire il link al documento o alla sua prova?
AmeerJ


Anche su citeseerx .
Kaveh,

8
Nota che quando , il limite di Beigel e Gill èΘ(k=n. Θ(n)
Jeffε

12

È possibile ordinare in modo ignaro con chiama la scatola nera, ciascuna applicata a un sottoarray contiguo dell'input originale. L'algoritmo non tocca mai i dati di input se non tramite chiamate in black box. In particolare, la stessa sequenza di chiamate in black box è solo una funzione din, non i dati di input effettivi (quindi "ignari").O(nlogn)n

Ecco uno schizzo di un algoritmo più semplice, che utilizza una scatola nera che ordina i subarrays di dimensione anziché solo kn2(n/k)2k2n/k

BlockBubbleSort(X[0..n-1], k):
   m = floor(n/k)
   for i = 1 to m
      for j = 0 to m-1
          BlackBoxSort(X[j*k .. (j+1)*k-1])
      for j = 0 to m-1
          BlackBoxSort(X[j*k + k/2 .. (j+1)*k + k/2 - 1])

n=18k=4k

inserisci qui la descrizione dell'immagine

k/2k

O((n/k)2)O((n/k)log2(n/k))=O(nlog2n)O((n/k)log(n/k))=O(nlogn)


Ω(n lg(n))

2
O(n)

+1 per quella bella foto! Potrei sbagliarmi, ma mi sembra che non sia del tutto corretto (correggimi se sbaglio). Supponendo che l'uscita sia in ordine crescente, se l'elemento più piccolo si trova nell'ultima posizione, non esiste un "percorso" per "spostarsi" nella prima posizione. La modifica di "per i = 1 in m" in "per i = 1 in m + 1" sembra correggere ciò, sebbene potrebbe introdurre un sovraccarico non necessario.
George,

@ George Oops, hai ragione; Ho bisogno di un altro livello!
Jeffε
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.