Algoritmo shuffle riffle sul posto a tempo lineare


15

Esiste un algoritmo di riffle shuffle sul posto lineare nel tempo? Questo è l'algoritmo che alcune mani particolarmente abili sono in grado di eseguire: dividere uniformemente un array di input di dimensioni pari e quindi intercalare gli elementi delle due metà.

Mathworld ha una breve pagina sulla riproduzione casuale dei riffle . In particolare, sono interessato alla varietà out-shuffle che trasforma l'array di input 1 2 3 4 5 6 in 1 4 2 5 3 6. Si noti che nella loro definizione, la lunghezza di input è .2n

È semplice eseguirlo in tempo lineare se abbiamo un secondo array di dimensioni o più utili. Prima copia gli ultimi elementi nell'array. Quindi, assumendo l'indicizzazione basata su 0, copiare i primi elementi dagli indici su . Quindi copiare gli elementi dal secondo array di nuovo nell'array di input, mappando gli indici su . (Possiamo fare un po 'meno lavoro di quello, perché il primo e l'ultimo elemento nell'input non si muovono.)nnn[0,1,2,...,n1][0,2,4,...,2n2]n[0,1,2,...,n1][1,3,5,...,2n1]

Un modo per tentare di eseguire questa operazione sul posto consiste nella decomposizione della permutazione in cicli disgiunti e quindi nel riordinare gli elementi in base a ciascun ciclo. Ancora una volta, supponendo l'indicizzazione basata su 0, la permutazione implicata nel caso dei 6 elementi è

σ=(012345024135)=(0)(5)(1243).

Come previsto, il primo e l'ultimo elemento sono punti fissi e se permutiamo i 4 elementi centrali otteniamo il risultato atteso.

Sfortunatamente, la mia comprensione della matematica delle permutazioni (e del loro ) si basa principalmente su Wikipedia, e non so se questo possa essere fatto in tempo lineare. Forse le permutazioni coinvolte in questo mescolamento possono essere rapidamente decomposte? Inoltre, non abbiamo nemmeno bisogno della decomposizione completa. È sufficiente determinare un singolo elemento di ciascuno dei cicli disgiunti, dal momento che possiamo ricostruire il ciclo da uno dei suoi elementi. Forse è necessario un approccio completamente diverso.LATEX

Buone risorse sulla matematica correlata sono preziose quanto un algoritmo. Grazie!


Esiste una soluzione temporale (con spazio extra). Non conosco alcuna soluzione lineare. O(nlgn)O(1)
Radu GRIGore,

4
È più appropriato per cs.stackexchange. Nel modello non uniforme, volte è sempre possibile. In questo caso dovrebbe essere possibile anche in modo uniforme. O(n)
Yuval Filmus,

1
@Radu Simile a questa domanda , questo problema probabilmente non ha una soluzione che utilizza solo spazio extra, ma spazio extra. O(1)O(logn)
Tyson Williams,

2
Prendo il mio commento (e voto per chiudere) indietro! (Sebbene la domanda abbia una risposta in letteratura.)
Yuval Filmus,

1
Ho sentito questa domanda da uno studente CS la scorsa settimana, che l'ha ascoltata durante un colloquio di lavoro.
Jeffε

Risposte:


12

Il problema è sorprendentemente non banale. Ecco una bella soluzione di Ellis e Markov, In-Situ, Stable Merging tramite Perfect Shuffle (sezione 7). Ellis, Krahn e Fan, Computing the Cycles in the Perfect Shuffle Permutazione riescono a selezionare "leader del ciclo", a scapito di più memoria. Inoltre è correlato il bel documento di Fich, Munro e Poblete, Permuting In Place , che fornisce un algoritmo di tempo per il modello dell'oracolo. Se è disponibile solo un oracolo per la permutazione, l'algoritmo richiede spazio logaritmico; se abbiamo anche un oracolo per l'inverso, richiede spazio costante.O(nlogn)

Ora per la soluzione di Ellis e Markov. Innanzitutto, supponiamo che . Quindi calcolare il perfetto riordino dell'ordine riduce al calcolo della perfetta riordino degli ordini ed , con una rotazione li precede. Ecco una dimostrazione di esempio ( , , ): n=x+ynxyn=5x=3y=2

012345678901256734890516273849

Ellis e Markov hanno trovato un modo semplice per calcolare lo shuffle perfetto quando , usando spazio costante e tempo lineare. Usando questo, otteniamo un algoritmo per calcolare lo shuffle perfetto per arbitrario . Per prima cosa, scrivi usando la codifica binaria di , e lascia che . Ruota i bit , mescola i bit di destra . Ignorando la mano destran=2knn=2k0++2kwnni=2ki++2kwn02k02k0 bit, ruotare il mezzo bit, e mescolare la destra 2 k 1n12k1bit. E così via. Si noti che la rotazione è semplice poiché i primi elementi ruotati funzionano come leader del ciclo. La complessità totale della rotazione è , poiché n t + 1 < n t / 2 . La complessità totale dei riordini interni è O ( 2 k 0 + + 2 k w ) = O ( n ) .O(n0++nw)=O(n)nt+1<nt/2O(2k0++2kw)=O(n)

Resta da mostrare come calcolare lo shuffle perfetto quando . In effetti, saremo in grado di identificare i leader del ciclo, seguendo il lavoro classico sulle collane (Fredricksen e Maiorana, Collane di perline in k colori e sequenze di k -ary de Bruijn ; Fredricksen e Kessler, Un algoritmo per generare collane di perline in due colori ).n=2kkk

Qual è la connessione? Dichiaro che la permutazione shuffle corrisponde al giusto spostamento della rappresentazione binaria. Ecco una dimostrazione per esempio, per : 000 001 010 011 100 101 110 111 000 100 001 101 010 110 011 111 Pertanto, per trovare i leader del ciclo, dobbiamo trovare un rappresentante per ciascuna classe di equivalenza della rotazione di stringhe binarie di lunghezza k . I documenti sopra menzionati forniscono il seguente algoritmo per generare tutti i leader del ciclo. Inizia con 0 kn=8

000001010011100101110111000100001101010110011111
k0k. Ad ogni passo, siamo ad un certo punto . Trova l'indice massimo i di un bit zero, dividi k per i per ottenere k = d i + r e lascia che il punto seguente sia ( a 1 ... a i - 1 1 ) d a 1 ... a r . Ogni volta che r = 0 , la nuova stringa è un leader del ciclo.a1akikik=di+r(a1ai11)da1arr=0

Ad esempio, quando questo genera la sequenza 0000 , 0001 , 0010 , 0011 , 0101 , 0110 , 0111 , 1111 .n=16

0000,0001,0010,0011,0101,0110,0111,1111.

I leader del ciclo sono evidenziati.


3
Vedi anche la risposta di Aryabhata, che utilizza arxiv.org/abs/0805.1598 . Quel documento, "Un semplice algoritmo sul posto per In-Shuffle" di Jain, usa la stessa idea, ma invece di poteri di , usa poteri di 3 . Il punto è che poiché 2 è una radice primitiva modulo 3 k , si vede facilmente che 3 0 , , 3 k sono leader del ciclo. Ancora più semplice di Ellis e Markov! 2323k30,,3k
Yuval Filmus,

Anche se penso che il documento di Jain sia un po 'più semplice, preferisco quello precedente, così come quello precedente con il maggior numero di voti.
Johny,


2

mn=m2if(i)=2iin/2f(i)=2(imodn/2)1i>n/2

O(1)O(logn)


Ah aspetta. Ciò presuppone che tutti i valori nella permutazione del riffle si trovino sullo stesso ciclo. Questa strategia dovrebbe essere modificata un po ', a seconda di quanti cicli disgiunti ci sono.
Robert Robere,
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.