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:
- kembalikan elemen dalam urutan yang diurutkan ketika menggunakan komparator sejati (yaitu, perbandingan melakukan apa yang kita harapkan dalam algoritma pengurutan standar)
- mengembalikan permutasi acak seragam elemen ketika pembanding digantikan oleh flip koin yang adil (yaitu, kembali
x < y = true
dengan 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.
Jawaban:
Algoritma deterministik berikut (tanpa pembanding) bekerja untuk input tuple :(a1,…,an)
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.O (nlogn ) O (n) O (logn )
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 <2 logn O(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<a1 0
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 :
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.
sumber
sumber