Ini adalah teks yang panjang. Tolong bersamaku. Mendidih, pertanyaannya adalah: Apakah ada algoritma jenis radix di tempat yang bisa diterapkan ?
Pendahuluan
Saya punya banyak sekali string dengan panjang tetap kecil yang hanya menggunakan huruf "A", "C", "G" dan "T" (ya, Anda sudah menebaknya: DNA ) yang ingin saya urutkan.
Saat ini, saya menggunakan std::sort
yang menggunakan introsort di semua implementasi umum STL . Ini bekerja dengan sangat baik. Namun, saya yakin itu jenis radix cocok dengan masalah saya yang diatur dengan sempurna dan harus bekerja jauh lebih baik dalam praktek.
Detail
Saya telah menguji asumsi ini dengan implementasi yang sangat naif dan untuk input yang relatif kecil (pada urutan 10.000) ini benar (well, setidaknya lebih dari dua kali lebih cepat). Namun, runtime menurun secara drastis ketika ukuran masalah menjadi lebih besar ( N > 5.000.000).
Alasannya jelas: radix sort membutuhkan penyalinan seluruh data (sebenarnya lebih dari sekali dalam implementasi naif saya). Ini berarti bahwa saya telah memasukkan ~ 4 GiB ke dalam memori utama saya yang jelas membunuh kinerja. Bahkan jika tidak, saya tidak mampu menggunakan memori sebanyak ini karena ukuran masalah sebenarnya menjadi lebih besar.
Gunakan Kasing
Idealnya, algoritma ini harus bekerja dengan panjang tali antara 2 dan 100, untuk DNA dan juga DNA5 (yang memungkinkan karakter wildcard tambahan "N"), atau bahkan DNA dengan kode ambiguitas IUPAC (menghasilkan 16 nilai berbeda). Namun, saya menyadari bahwa semua kasus ini tidak dapat ditutup, jadi saya senang dengan peningkatan kecepatan yang saya dapatkan. Kode dapat memutuskan secara dinamis algoritma mana yang akan dikirim.
Penelitian
Sayangnya, artikel Wikipedia tentang radix sort tidak berguna. Bagian tentang varian di tempat adalah sampah lengkap. Bagian NIST-DADS pada jenis radix ada di sebelah tidak ada. Ada makalah yang terdengar menjanjikan yang disebut Efficient Adaptive In-Place Radix Sorting yang menggambarkan algoritma "MSL". Sayangnya, makalah ini juga mengecewakan.
Secara khusus, ada beberapa hal berikut.
Pertama, algoritma tersebut mengandung beberapa kesalahan dan membuat banyak yang tidak dapat dijelaskan. Secara khusus, itu tidak merinci panggilan rekursi (saya hanya berasumsi bahwa itu menambah atau mengurangi beberapa pointer untuk menghitung nilai shift dan mask saat ini). Selain itu, ia menggunakan fungsi dest_group
dan dest_address
tanpa memberikan definisi. Saya gagal melihat bagaimana menerapkan ini secara efisien (yaitu, dalam O (1); setidaknyadest_address
tidak sepele).
Last but not least, algoritma mencapai di tempat dengan menukar indeks array dengan elemen di dalam array input. Ini jelas hanya bekerja pada array numerik. Saya perlu menggunakannya pada string. Tentu saja, saya hanya bisa mengetikan pengetikan yang kuat dan melanjutkan dengan asumsi bahwa memori akan mentolerir saya menyimpan indeks di tempat yang bukan miliknya. Tapi ini hanya berfungsi selama saya bisa memasukkan string saya ke dalam 32 bit memori (dengan asumsi integer 32 bit). Itu hanya 16 karakter (abaikan saja saat itu 16> log (5.000.000)).
Makalah lain oleh salah satu penulis tidak memberikan deskripsi yang akurat sama sekali, tetapi memberikan runtime MSL sebagai sub-linear yang salah datar.
Untuk merangkum : Apakah ada harapan untuk menemukan implementasi referensi kerja atau setidaknya pseudocode / deskripsi yang baik dari jenis radix yang bekerja di tempat yang bekerja pada string DNA?