Algoritma P2 adalah temuan yang bagus. Ia bekerja dengan membuat beberapa perkiraan kuantil, memperbaruinya secara berkala, dan menggunakan interpolasi kuadrat (bukan linier, bukan kubik) untuk memperkirakan kuantil. Para penulis mengklaim interpolasi kuadrat bekerja lebih baik di ekor daripada interpolasi linier dan kubik akan menjadi terlalu rewel dan sulit.
Anda tidak menyatakan dengan tepat bagaimana pendekatan ini gagal untuk data "ekor berat" Anda, tetapi mudah ditebak: perkiraan kuantil ekstrem untuk distribusi berekor berat akan tidak stabil hingga sejumlah besar data dikumpulkan. Tapi ini akan menjadi masalah (pada tingkat lebih rendah) bahkan jika Anda menyimpan semua data, jadi jangan berharap keajaiban!
Bagaimanapun juga, mengapa tidak menetapkan marker bantu - sebut saja mereka dan --dengan mana Anda sangat yakin quantile akan berbohong, dan simpan semua data yang terletak di antara dan ? Saat buffer Anda terisi, Anda harus memperbarui marker ini, selalu simpan . Algoritma sederhana untuk melakukan ini dapat dibuat dari kombinasi (a) estimasi P2 saat ini dari kuantil dan (b) jumlah jumlah data yang disimpan kurang dari dan jumlah data lebih besar dari . Dengan cara ini Anda dapat, dengan kepastian tinggi, memperkirakan kuantil sama baiknya jika Anda memiliki seluruh dataset yang selalu tersedia, tetapi Anda hanya membutuhkan buffer yang relatif kecil.x 6 x 0 x 6 x 0 ≤ x 6 x 0 x 6x0x6x0x6x0≤x6x0x6
Secara khusus, saya mengusulkan struktur data untuk mempertahankan informasi parsial tentang urutan nilai data . Di sini, adalah daftar tertautn x 1 , x 2 , … , x n y(k,y,n)nx1,x2,…,xny
y=(x(n)[k+1]≤x(n)[k+2]≤⋯≤x(n)[k+m]).
Dalam notasi ini menunjukkan terkecil dari nilai dibaca sejauh ini. adalah konstanta, ukuran buffer . i th n x m yx(n)[i]ithn xmy
Algoritma dimulai dengan mengisi dengan nilai data pertama yang ditemui dan menempatkannya dalam urutan diurutkan, terkecil hingga terbesar. Biarkan menjadi kuantil untuk diestimasi; misalnya, = 0,99. Setelah membaca ada tiga tindakan yang mungkin: m q q x n + 1ymqqxn+1
Jika , tambahkan . kxn+1<x(n)[k+1]k
Jika , jangan lakukan apa pun.xn+1>x(n)[k+m]
Jika tidak, masukkan ke . yxn+1y
Dalam hal apa pun, kenaikan .n
The insert menempatkan prosedur ke dalam rangka diurutkan dan kemudian menghilangkan salah satu nilai ekstrim dalam : y yxn+1yy
Jika , maka hapus dari dan increment ;x ( n ) [ k + 1 ] y kk+m/2<nqx(n)[k+1]yk
Kalau tidak, hapus dari . yx(n)[k+m]y
Asalkan cukup besar, prosedur ini akan mengurung kuantil sebenarnya dari distribusi dengan probabilitas tinggi. Pada setiap tahap dapat diperkirakan dengan cara biasa dalam hal dan , yang kemungkinan besar terletak di . (Saya percaya hanya perlu skala seperti akar kuadrat dari jumlah maksimum data ( ), tetapi saya belum melakukan analisis yang ketat untuk membuktikannya.) Bagaimanapun, algoritma akan mendeteksi apakah telah berhasil (oleh membandingkan dan ke ).n x ( n ) [ ⌊ q n ⌋ ] x ( n ) [ ⌈ q n ⌉ ] y m N k / n ( k + m ) / n qmnx(n)[⌊qn⌋]x(n)[⌈qn⌉]ymNk/n(k+m)/nq
Menguji hingga 100.000 nilai, menggunakan dan (kasus paling sulit) menunjukkan algoritma ini memiliki tingkat keberhasilan 99,5% dalam mendapatkan nilai . Untuk aliran nilai , yang akan membutuhkan buffer hanya dua juta (tetapi tiga atau empat juta akan menjadi pilihan yang lebih baik). Menggunakan daftar tertaut ganda yang diurutkan untuk buffer memerlukan = upaya sambil mengidentifikasi dan menghapus max atau min adalah operasi . Penyisipan yang relatif mahal biasanya hanya perlu dilakukan q=.5x ( n ) [ ⌊ q n ⌋ ] N=10 12 O(log( √m=2N−−√q=.5x(n)[⌊qn⌋]N=1012O(log(N−−√))O(log(N))O(1)O(N−−√)waktu. Dengan demikian biaya komputasi dari algoritma ini adalah dalam waktu dan dalam penyimpanan.O(N+N−−√log(N))=O(N)O(N−−√)