Algoritma riffle shuffle waktu linear di tempat

15

Apakah ada algoritma waktu riffle shuffle linear waktu? Ini adalah algoritma yang mampu dilakukan oleh beberapa tangan yang sangat tangkas: membagi array input berukuran rata, dan kemudian menyatukan elemen dari dua bagian.

Mathworld memiliki halaman singkat tentang riffle shuffle . Secara khusus, saya tertarik pada variasi out-shuffle yang mengubah array input 1 2 3 4 5 6 menjadi 1 4 2 5 3 6. Perhatikan bahwa dalam definisi mereka, panjang input adalah .2n

Ini mudah untuk melakukan ini dalam waktu linier jika kita punya array kedua ukuran atau lebih berguna. Pertama-tama salin elemen terakhir ke array. Kemudian, dengan asumsi pengindeksan berbasis 0, salin elemen pertama dari indeks ke . Kemudian salin elemen dari array kedua kembali ke array input, pemetaan indeks ke . (Kita dapat melakukan pekerjaan sedikit lebih sedikit dari itu, karena elemen pertama dan terakhir dalam input tidak bergerak.)n n [ 0 , 1 , 2 , . . . , N - 1 ] [ 0 , 2 , 4 , . . . , 2 n - 2 ] n [ 0 , 1 , 2 , . . . , N - 1 ] [ 1 , 3 , 5 , . . . ,nnn[0,1,2,...,n1][0,2,4,...,2n2]n[0,1,2,...,n1][1,3,5,...,2n1]

Salah satu cara untuk melakukan hal ini di tempat melibatkan dekomposisi permutasi menjadi siklus terpisah, dan kemudian mengatur ulang elemen sesuai dengan setiap siklus. Sekali lagi, dengan asumsi pengindeksan berbasis 0, permutasi yang terlibat dalam kasus 6 elemen adalah

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

Seperti yang diharapkan, elemen pertama dan terakhir adalah poin tetap, dan jika kita mengubah 4 elemen tengah kita mendapatkan hasil yang diharapkan.

Sayangnya, pemahaman saya tentang matematika permutasi (dan L merekaLATEX ) sebagian besar didasarkan pada wikipedia, dan saya tidak tahu apakah ini dapat dilakukan dalam waktu linier. Mungkin permutasi yang terlibat dalam pengocokan ini dapat dengan cepat terurai? Juga, kita bahkan tidak perlu dekomposisi lengkap. Cukup menentukan satu elemen saja dari masing-masing siklus disjoint akan cukup, karena kita dapat merekonstruksi siklus dari salah satu elemennya. Mungkin diperlukan pendekatan yang sangat berbeda.

Sumber daya yang baik pada matematika terkait sama berharganya dengan algoritma. Terima kasih!

Johny
sumber
Ada solusi waktu (dengan O ( 1 ) ruang ekstra). Saya tidak tahu solusi linear apa pun. O(nlgn)O(1)
Radu GRIGore
4
Itu lebih tepat untuk pertukaran cs.stack. Dalam model yang tidak seragam, kali selalu dimungkinkan. Dalam hal ini harus dimungkinkan bahkan secara seragam. O(n)
Yuval Filmus
1
@ Radu Serupa dengan pertanyaan ini , masalah ini mungkin tidak memiliki solusi hanya dengan menggunakan ruang ekstra, tetapi O ( log n ) ruang ekstra. O(1)O(logn)
Tyson Williams
2
Saya mengambil komentar saya (dan memilih untuk menutup) kembali! (Meskipun pertanyaannya dijawab dalam literatur.)
Yuval Filmus
1
Saya mendengar pertanyaan ini dari seorang siswa CS minggu lalu, yang mendengarnya saat wawancara kerja.
Jeffε

Jawaban:

12

Masalahnya secara mengejutkan adalah non-sepele. Ini adalah solusi yang bagus dari Ellis dan Markov, In-Situ, Stable Merging melalui Perfect Shuffle (bagian 7). Ellis, Krahn dan Fan, Menghitung Siklus dalam Permutasi Acak Sempurna berhasil memilih "pemimpin siklus", dengan mengorbankan lebih banyak memori. Juga terkait adalah kertas bagus oleh Fich, Munro dan Poblete, Permuting In Place , yang memberikan algoritma waktu umum untuk model oracle. Jika hanya sebuah oracle untuk permutasi tersedia, algoritma membutuhkan ruang logaritmik; jika kita juga memiliki oracle untuk kebalikannya, itu membutuhkan ruang yang konstan.O(nlogn)

Sekarang untuk solusi Ellis dan Markov. Pertama, misalkan . Kemudian menghitung acak shuffle pesanan dan mengurangi untuk menghitung acak shuffle pesanan x dan y , dengan rotasi sebelumnya. Berikut ini adalah bukti dengan contoh ( n = 5 , x = 3 , y = 2 ): 012 345 67 89 012 567 34 89 051627 3849n=x+ynxyn=5x=3y=2

012345678901256734890516273849

Ellis dan Markov menemukan cara mudah untuk menghitung shuffle sempurna ketika , menggunakan ruang konstan dan waktu linier. Dengan menggunakan ini, kami memperoleh algoritma untuk menghitung shuffle sempurna untuk arbitrary n . Pertama, menulis n = 2 k 0 + + 2 k w menggunakan pengkodean biner dari n , dan biarkan n i = 2 k i + + 2 k w . Putar tengah n 0 bit, kocok 2 k kanann=2knn=2k0++2kwnni=2ki++2kwn0 bit. Mengabaikanbitkanan2 k 0 bit, putar tengahn1bit, dan kocok bit kanan2 k 1 . Dan seterusnya. Perhatikan bahwa rotasi mudah karena beberapa elemen pertama yang diputar berfungsi sebagai pemimpin siklus. Kompleksitas total rotasi adalahO(n0++nw)=O(n), karenan t + 1 <nt/2. Kompleksitas total dari shuffles bagian dalam adalahO(2k02k0n12k1O(n0++nw)=O(n)nt+1<nt/2 .O(2k0++2kw)=O(n)

Tetap menunjukkan bagaimana menghitung shuffle sempurna ketika . Bahkan, kita akan dapat mengidentifikasi pemimpin siklus, berikut karya klasik pada kalung (Fredricksen dan Maiorana, Kalung manik-manik di k warna dan k -ary de urutan Bruijn ; Fredricksen dan Kessler, Sebuah algoritma untuk menghasilkan kalung dari manik-manik dalam dua warna ).n=2kkk

Apa hubungannya? Saya mengklaim bahwa permutasi shuffle sesuai dengan pergeseran kanan representasi biner. Berikut ini adalah bukti dengan contoh, untuk : 000 001 010 011 100 101 110 111 000 100 001 101 010 110 011 111 Oleh karena itu, untuk menemukan pemimpin siklus, kita perlu menemukan satu perwakilan dari setiap kelas ekivalensi dari rotasi string biner dengan panjang k . Makalah yang disebutkan di atas memberikan algoritma berikut untuk menghasilkan semua pemimpin siklus. Mulai dengan 0 kn=8

000001010011100101110111000100001101010110011111
k0k. Pada setiap langkah, kita di beberapa titik . Temukan indeks maksimal i dari bit nol, bagilah k dengan i untuk mendapatkan k = d i + r , dan biarkan titik berikut ini menjadi ( a 1 ... a i - 1 1 ) d a 1 ... a r . Setiap kali r = 0 , string baru adalah pemimpin siklus.a1akikik=di+r(a1ai11)da1arr=0

Misalnya, ketika ini menghasilkan urutan 0000 , 0001 , 0010 , 0011 , 0101 , 0110 , 0111 , 1111 .n=16

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

Pemimpin siklus disorot.

Yuval Filmus
sumber
3
Lihat juga jawaban Aryabhata, yang menggunakan arxiv.org/abs/0805.1598 . Makalah itu, "Algoritma In-Place Sederhana untuk In-Shuffle" oleh Jain, menggunakan ide yang sama, tetapi bukannya kekuatan , menggunakan kekuatan 3 . Intinya adalah karena 2 adalah modulo akar primitif 3 k , mudah terlihat bahwa 3 0 , , 3 k adalah pemimpin siklus. Bahkan lebih sederhana dari Ellis dan Markov! 2323k30,,3k
Yuval Filmus
Meskipun saya pikir kertas Jain sedikit lebih mudah, saya lebih suka kertas sebelumnya, serta posting sebelumnya dengan suara terbanyak.
Johny
6

Ini adalah pertanyaan awal di cs.stackexchange.com dan jawabannya ada di sini: /cs/332/in-place-algorithm-for-interleaving-an-array/400#400

Ini adalah penjelasan dari makalah ini: http://arxiv.org/abs/0805.1598 .

k2k32k=2

j2jmod2n+1

Aryabhata
sumber
Ha! Saya benar-benar lupa tentang pertanyaan itu, bahkan jika saya berpartisipasi dalam diskusi. Ini berarti saya tidak begitu mengerti bagaimana cara kerjanya saat itu.
Radu GRIGore
2

Apa yang terjadi jika Anda menuliskan fungsi riffle shuffle? Jikam adalah panjang dari total array, mis n=m-2menjadi panjang array setelah menghapus elemen pertama dan terakhir. Kemudian diacak indeks indeksnyasaya adalah f(saya)=2saya jika sayan/2 dan f(saya)=2(sayamodn/2)-1 jika saya>n/2. Kemudian Anda bisa "pointer jump" melalui array, bertukar dengan menerapkan kembali fungsi.

Dengan asumsi akses acak, ini akan menjadi waktu linear sambil memerlukan HAI(1) kata-kata tambahan (untuk menyimpan nilai array pada indeks yang diberikan), dan sebagainya HAI(catatann) ruang ekstra.

Robert Robere
sumber
Ah, wait. This assumes that all of the values in the riffle permutation lie on the same cycle. This strategy would have to be modified a bit, depending on how many disjoint cycles there are.
Robert Robere