Apakah ada algoritma "pengurutan" yang mengembalikan permutasi acak ketika menggunakan pembanding koin-balik?

9

Terinspirasi oleh pertanyaan ini di mana penanya ingin tahu apakah waktu berjalan berubah ketika pembanding yang digunakan dalam algoritma pencarian standar digantikan oleh flip koin yang adil, dan juga kegagalan Microsoft yang menonjol untuk menulis generator permutasi yang seragam, pertanyaan saya adalah demikian :

Apakah ada algoritma penyortiran berbasis perbandingan yang akan, tergantung pada implementasi kami dari pembanding:

  1. kembalikan elemen dalam urutan yang diurutkan ketika menggunakan komparator sejati (yaitu, perbandingan melakukan apa yang kita harapkan dalam algoritma pengurutan standar)
  2. mengembalikan permutasi acak seragam elemen ketika pembanding digantikan oleh flip koin yang adil (yaitu, kembali x < y = truedengan probabilitas 1/2, terlepas dari nilai x dan y)

Kode untuk algoritma pengurutan harus sama. Hanya kode di dalam "kotak hitam" perbandingan yang diizinkan untuk diubah.

Joe
sumber
Lihat juga pertanyaan ini .
Raphael
2
Lihat juga pertanyaan menarik berikut: cstheory.stackexchange.com/questions/5321/… .
Yuval Filmus
1
Apakah Anda ingin pembanding acak Anda berperilaku baik? Berikut adalah dua cara yang mungkin. (1) Setelah pembanding memutuskan bahwa , maka x < y selalu, dan juga y > x . (2) Sama, tetapi jika lebih jauh pembanding memutuskan bahwa x < y dan y < z , maka berkomitmen untuk x < z (dan z > x ). Dalam kedua kasus, setiap kueri yang tidak dibatasi masih sepenuhnya acak. x<yx<yy>xx<yy<zx<zz>x
Yuval Filmus
@YuvalFilmus Saya ingin dasarnya apa yang diminta dalam pertanyaan Anda yang ditautkan, kecuali bahwa sirkuit yang sama juga harus mengurutkan jika kita mengganti gerbang acak dengan gerbang pertukaran-tukar yang memesan sepasang elemen.
Joe
1
Lihat di sini untuk visualisasi yang bagus.
Raphael

Jawaban:

3

Algoritma deterministik berikut (tanpa pembanding) bekerja untuk input tuple :(a1,,an)

  1. Apakah yang Fisher-Yates mengocok menggunakan komparator Anda dengan beberapa pasangan statis (mengatakan ) sebagai flip koin (melakukan penerimaan-penolakan sampling). Jika komparator mengeluarkan 1 pertama kali, gunakan itu terbalik untuk menghindari loop penolakan tanpa akhir dalam kasus deterministik.Sebuah1<Sebuah21
  2. (speedup opsional: Coba satu pasangan kali, di mana n adalah panjang atau input Anda. Jika ada dua output yang berbeda, kembalikan permutasi yang diperoleh dalam (1))nn
  3. Sortir array Anda menggunakan sortir gabungan.

Diberikan relasi urutan deterministik sebagai pembanding, algoritma ini mengurutkan array dalam waktu karena shuffle Fisher-Yates berjalan dalam O ( n ) menggunakan maksimal O ( log n ) "acak bit" nonrandom (misalnya panggilan ke pembanding Anda ) pada setiap langkah dan gabungan, memiliki kompleksitas asimptotik yang sama. Hasil dari (1) sama sekali tidak berguna dalam kasus ini, tetapi karena diikuti oleh semacam nyata, ini tidak ada salahnya.HAI(ncatatann)HAI(n)HAI(catatann)

Diberikan flip koin nyata sebagai pembanding (1) memungkinkan array dengan probabilitas yang sama untuk setiap permutasi dan jika Anda benar-benar harus melakukan (3) (Anda ditinggalkan (2) atau (2) gagal menentukan keacakan), ini bukan salahnya karena distribusi hasil hanya tergantung pada urutan inputnya yang terdistribusi secara merata di antara semua permutasi karena (1), sehingga hasil dari seluruh algoritma juga terdistribusi secara seragam. Jumlah setiap pengambilan sampel penerimaan-penolakan harus diulang didistribusikan secara geometris (tolak dengan probabilitas ) dan karena itu memiliki nilai yang diharapkan<2. Setiap penggunaan pengulangan palinglognbit, sehingga analisis runtime hampir sama seperti dalam kasus deterministik, tetapi kami hanya mendapatkanruntime diharapkandariO(nlogn), dengan kemungkinan nontermination (Menghentikan hanyahampir pasti).<12<2lognO(nlogn)


Seperti Joe menunjukkan: Jika Anda tidak menyukai tes untuk bit pertama dalam (1), melakukan (3) maka (1) dan menggunakan yang selalu 0 , karena array sudah diurutkan dalam kasus deterministik. Selain itu Anda harus mengurangi angka acak Anda dari batas atas pada rentang dalam loop, karena batas atas untuk angka acak menghasilkan permutasi yang sama. Namun ketahuilah bahwa (2) itu dilarang, karena Anda selalu harus melakukan shuffle dalam kasus tebusan.an<a10


Anda bahkan dapat menggunakan panggilan yang sama ke komparator Anda untuk (1) dan (3), tetapi kemudian membuktikan bahwa hasilnya didistribusikan secara merata setidaknya jauh lebih sulit, jika mungkin sama sekali.


Algoritme berikut tidak memiliki fase berbeda untuk mengocok dan mengurutkan, tetapi secara asimptot lebih lambat. Ini pada dasarnya semacam penyisipan dengan pencarian biner . Saya akan menggunakan untuk menunjukkan input dan b k = ( b k , 1 , ... , b k , k ) untuk menunjukkan hasil setelah putaran ke- k :a=(a1,,an)bk=(bk,1,,bk,k)k

  1. Set b1,1=a1
  2. Jika maka b 2 = ( a 2 , a 1 ) dan ( c , d ) : = ( 2 , 1 ) lain b 2 = ( a 1 , a 2 ) dan ( c , d ) : = ( 1 , 2 ) . Dalam kedua kasus a d <a2<a1b2=(a2,a1)(c,d):=(2,1)b2=(a1,a2)(c,d):=(1,2) akan selalu menjadi 0 (mis. salah) untuk pembanding nonrandom.ad<ac0
  3. Untuk mendapatkan untuk k 3, dapatkan b k - 1 terlebih dahulu.bkk3bk1
  4. Mari dan k ' = 2 l , yaitu k ' adalah kekuatan paling 2 tidak lebih kecil dari k .l=log2kk=2lk2k
  5. Biarkan . Untuk setiap j { 1 , , l } biarkan aku j = { i j - 1 + 2 l - j i j - 1 + 2 l - j > k - 1 a d < a c i j - 1 i j - 1 + 2 l -i0=0j{1,,l}
    ij={ij1+2ljij1+2lj>k1ad<acij1ij1+2lj>k1¬(ad<ac)ij1+2ljij1+2ljk1bk1,ij1+2lj<akij1ij1+2ljk1¬(bk1,ij1+2lj<ak)
  6. il>kbk=(bk1,1,,bk1,il1,ak,bk1,il,,bk1,k1)
  7. bn

k1k

Perhatikan bahwa algoritma ini tidak efisien dalam kedua mode dibandingkan dengan pengocokan dan gabungan jenis Fisher-Yates karena memasukkan elemen ke posisi sewenang-wenang mahal jika menggunakan array dan pencarian biner membutuhkan waktu linier jika menggunakan daftar. Tapi mungkin modifikasi heap sort atau tree sort dengan cara yang sama dapat menghasilkan algoritma yang lebih cepat.

frafl
sumber
@Jo, bisakah kamu menaruh semua poin kamu masih berlaku untuk posting dalam bentuk saat ini menjadi satu komentar dan menghapus sisanya?
frafl
Saya berharap untuk algoritma yang tidak melakukan langkah-langkah berbeda tergantung pada komparator mana yang digunakan. Bisakah Anda menghindari loop penolakan tanpa batas tanpa memeriksa pembanding? Saya pikir Anda dapat menghindari penolakan dengan melakukan langkah (3) terlebih dahulu ...
Joe
i
Komentar pertama: Perhatikan bahwa saya tidak membuang sedikit sampel pertama, itu "penggunaan ganda". Saya berpikir tentang membalikkan setiap bit ke-2, tetapi itu tidak akan mencegah loop tanpa akhir. Bahkan beberapa pola tidak teratur diperlukan dan bahkan dapat menolak lebih banyak entri. Tentu saja saya bisa XOR dua bit paling baru, bukan yang pertama dan yang terbaru, tapi itu tidak terlalu berbeda.
frafl
ian<a10
4

n2A/2B1/n!n>21/n!A/2B

Yuval Filmus
sumber
1
Tetapi ini hanya berlaku, jika kita membutuhkan batasan deterministik pada runtime, yang tidak diminta dalam pertanyaan. Jika kita hanya membutuhkan runtime yang diharapkan menjadi terbatas, ini seharusnya tidak menjadi masalah.
frafl
1
Apakah Anda mengetahui adanya algoritma penyortiran yang masuk akal yang tidak berakhir dalam waktu polinomial?
Yuval Filmus
2
Anda mencampur kasus deterministik dan acak. Algoritma dapat berakhir dalam waktu polinom deterministik jika dipanggil dengan hubungan urutan deterministik dan dalam waktu polinomial yang diharapkan jika dipanggil dengan koin sebagai pembanding.
frafl
2k
kA/2k