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,...,n−1][0,2,4,...,2n−2]n[0,1,2,...,n−1][1,3,5,...,2n−1]

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(nlg⁡n)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(log⁡n)
— 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(nlog⁡n)

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.a1…akikik=d⋅i+r(a1…ai−11)da1…arr=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=m−2if(i)=2⋅ii≤n/2f(i)=2⋅(imodn/2)−1i>n/2

O(1)O(log⁡n)


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.