Algoritma pemilahan generik umumnya mengambil satu set data untuk disortir dan fungsi komparator yang dapat membandingkan dua elemen individual. Jika komparator adalah relasi urutan¹, maka output dari algoritma adalah daftar / array yang diurutkan.
Saya bertanya-tanya meskipun algoritma semacam apa yang benar-benar akan bekerja dengan komparator yang bukan hubungan urutan (khususnya yang mengembalikan hasil acak pada setiap perbandingan). Yang saya maksud dengan "kerja" di sini adalah bahwa mereka terus mengembalikan permutasi input mereka dan berjalan pada kompleksitas waktu yang biasanya dikutip (sebagai kebalikan dari merendahkan ke skenario kasus terburuk selalu, atau pergi ke loop tak terbatas, atau elemen yang hilang). Namun, pemesanan hasil akan ditentukan. Bahkan lebih baik, pemesanan yang dihasilkan akan menjadi distribusi yang seragam ketika pembandingnya adalah koin flip.
Dari perhitungan mental kasar saya tampak bahwa semacam gabungan akan baik-baik saja dengan ini dan mempertahankan biaya runtime yang sama dan menghasilkan pemesanan acak yang adil. Saya pikir sesuatu seperti semacam cepat akan merosot, mungkin tidak selesai, dan tidak adil.
Algoritme pengurutan apa lagi (selain gabungan jenis) yang akan berfungsi seperti yang dijelaskan dengan pembanding acak?
Untuk referensi, komparator adalah relasi urutan jika itu adalah fungsi yang tepat (deterministik) dan memenuhi aksioma relasi urutan:
- itu deterministik:
compare(a,b)
untuk yang khususa
danb
selalu mengembalikan hasil yang sama. - itu transitif:
compare(a,b) and compare(b,c) implies compare( a,c )
- itu antisimetris
compare(a,b) and compare(b,a) implies a == b
- itu deterministik:
(Asumsikan bahwa semua elemen input berbeda, sehingga refleksivitas tidak menjadi masalah.)
Komparator acak melanggar semua aturan ini. Namun ada komparator yang tidak memesan hubungan namun tidak acak (misalnya mereka mungkin melanggar mungkin hanya satu aturan, dan hanya untuk elemen tertentu di set).
sumber
Jawaban:
Jadi pada dasarnya, Anda ingin tahu apakah ada algoritma pengurutan yang tidak akan menurun dari kasus rata-rata jika diberi fungsi bandingkan yang mirip dengan:
... di mana Random.Next () adalah beberapa metode yang akan menghasilkan bilangan bulat yang dihasilkan secara acak antara batas bawah dan atas inklusif yang ditentukan.
Jawabannya sebenarnya adalah bahwa sebagian besar algoritma pengurutan dasar akan bekerja sesuai dengan kasus rata-rata mereka, karena mereka mematuhi setidaknya satu dari dua kondisi berikut:
Misalnya, SelectionSort beralih melalui sub-daftar elemen yang tidak disortir, menemukan elemen "paling sedikit" dan / atau "terbesar" (dengan membandingkan masing-masing dengan yang terbesar sejauh ini), menempatkannya pada posisi dan pengulangan yang benar. Akibatnya, bahkan dengan pembanding non-deterministik, pada akhir setiap iterasi algoritma akan menemukan nilai yang dianggap paling atau paling besar, menukarnya dengan elemen di posisi yang ia coba untuk menentukan, dan tidak pernah mempertimbangkan elemen itu lagi, sehingga mematuhi Kondisi 2. Namun, A dan B dapat dibandingkan beberapa kali selama proses ini (sebagai contoh paling ekstrim, pertimbangkan beberapa lintasan SelectionSort pada array yang diurutkan dalam urutan terbalik) sehingga melanggar Kondisi 1 .
MergeSort mematuhi Kondisi 1 tetapi tidak 2; karena sub-array digabung, elemen-elemen dalam sub-array yang sama (di sisi kiri atau kanan) tidak dibandingkan satu sama lain karena telah ditentukan bahwa elemen-elemen di sisi array tersebut berada dalam urutan di antara mereka sendiri; algoritme hanya membandingkan elemen yang paling tidak dihapus dari masing-masing subarray dengan yang lain untuk menentukan mana yang lebih rendah dan harus masuk berikutnya dalam daftar gabungan. Ini berarti bahwa setiap dua objek unik A dan B akan dibandingkan satu sama lain maksimum satu kali, tetapi indeks "final" elemen apa pun yang diberikan dalam koleksi lengkap tidak diketahui hingga algoritme selesai.
InsertionSort hanya mematuhi Persyaratan 1 meskipun strategi keseluruhan dan kompleksitasnya lebih mirip dengan SelectionSort. Setiap elemen yang tidak disortir dibandingkan dengan elemen yang diurutkan, terbesar-pertama, hingga ditemukan lebih sedikit dari elemen yang sedang diperiksa. elemen dimasukkan pada titik itu, dan kemudian elemen berikutnya dipertimbangkan. Hasilnya adalah bahwa urutan relatif dari setiap A dan B ditentukan oleh satu perbandingan, dan perbandingan lebih lanjut antara A dan B tidak pernah dilakukan, tetapi posisi akhir dari setiap elemen tidak dapat diketahui sampai semua elemen dipertimbangkan.
QuickSort mematuhi keduanyaKondisi. Di setiap tingkat, pivot dipilih dan disusun sedemikian rupa sehingga sisi "kiri" mengandung elemen lebih sedikit dari pivot dan sisi "kanan" mengandung elemen yang lebih besar daripada pivot. Hasil level tersebut adalah QuickSort (kiri) + pivot + QuickSort (kanan) yang pada dasarnya berarti posisi elemen pivot diketahui (satu indeks lebih besar dari panjang sisi kiri), pivot tidak pernah dibandingkan dengan elemen lain setelah dipilih sebagai pivot (mungkin telah dibandingkan dengan elemen pivot sebelumnya, tetapi elemen-elemen tersebut juga diketahui dan tidak termasuk dalam sub-susun apa pun), DAN setiap A dan B yang berakhir pada sisi berlawanan dari pivot tidak pernah dibandingkan. Dalam sebagian besar implementasi QuickSort murni, casing dasar adalah satu elemen, di mana titik indeks saat ini adalah indeks akhir dan tidak ada perbandingan lebih lanjut yang dibuat.
Satu-satunya jenis komparatif yang dapat saya pikirkan yang tidak mematuhi kedua kondisi ini adalah BubbleSort yang tidak dioptimalkan. Jika pengurutan tidak menerima bahwa elemen X terbesar berada di tempat yang tepat setelah menjalankan X pass, dan / atau menggunakan pass "periksa ulang" untuk memverifikasi daftar diurutkan, pengurutan hanya akan dianggap "selesai" ketika pembanding acak telah kembali -1 atau 0 untuk setiap dua elemen yang berdekatan dalam daftar selama lulus dan dengan demikian tidak ada swap dilakukan (sebuah acara yang, jika benar-benar acak, akan terjadi dengan probabilitas( 2 / 3 )N- 1 , karena relatif daftar kecil 25 elemen, itu peluang satu dalam 2000, sedangkan untuk 100 elemen probabilitasnya adalah 3,7 * 10 -18). Ketika nilai absolut maksimum hasil komparator meningkat, probabilitas untuk setiap perbandingan untuk mengembalikan negatif atau nol menurun ke 0,5, membuat peluang untuk mengakhiri algoritma yang jauh lebih kecil kemungkinannya (kemungkinan 99 koin membalik semua kepala pendaratan , yang pada dasarnya adalah intinya, adalah 1 dalam 1,2 * 10 30 )
EDIT A LATER TIME LATER: Ada beberapa "macam" yang dirancang khusus sebagai contoh apa yang tidak boleh dilakukan yang menggabungkan pembanding acak; mungkin yang paling terkenal adalah BogoSort. "Diberikan daftar, jika daftar tidak berurutan, kocok daftar dan periksa lagi". Secara teoritis pada akhirnya akan mencapai permutasi nilai yang tepat, seperti "BubbleSort yang tidak dioptimalkan" di atas, tetapi case rata-rata adalah faktorial-waktu (N! / 2), dan karena masalah ulang tahun (setelah permutasi yang cukup Anda menjadi lebih mungkin untuk menghadapi permutasi duplikat daripada yang unik) ada kemungkinan bukan nol dari algoritma tidak pernah menyelesaikan secara resmi algoritma tidak terikat waktu.
sumber
Sunting: Masalahnya lebih menarik seperti yang saya pikirkan, jadi inilah komentar selanjutnya:
Ini memberikan waktu berjalan rata-rataO ( 2 n ) O ( n2)
Akan menyenangkan untuk bekerja di luar rata-rata waktu berjalan untuk algoritma lain yang berbeda mengingat fungsi perbandingan yang seragam ini.
sumber
Mergesort dengan pembanding acak yang adil tidak adil. Saya tidak punya bukti, tapi saya punya bukti empiris yang SANGAT kuat. (Adil berarti terdistribusi secara merata.)
sumber
Pertanyaan yang sangat terkait dijawab dalam Semua Urusan Permutasi (Mutiara Fungsional) oleh Christiansen, Danilenko dan Dylus. Mereka menjalankan algoritma pengurutan dalam daftar monad , yang pada dasarnya mensimulasikan non-determinisme, mengembalikan semua permutasi dari daftar input yang diberikan. Properti yang menarik adalah bahwa setiap permutasi dikembalikan tepat sekali.
Mengutip dari abstrak:
sumber