Apakah ada algoritma subquadratic yang diketahui untuk menghitung lantai akar kuadrat dari n
integer bit?
Algoritma naif akan menjadi sesuatu seperti
def sqrt(x):
r = 0
i = x.bit_length() // 2
while i >= 0:
inc = (r << (i+1)) + (1 << (i*2))
if inc <= x:
x -= inc
r += 1 << i
i -= 1
return r
Ini membutuhkan O(n)
iterasi, masing-masing melibatkan penambahan yang merupakan O(n)
waktu, jadi ini adalah O(n^2)
waktu keseluruhan. Adakah yang lebih cepat? Saya tahu bahwa untuk kasus perkalian ada algoritma khusus yang melakukan lebih baik daripada waktu kuadratik, tetapi saya tidak dapat menemukan apa pun untuk akar kuadrat.
algorithms
numerical-algorithms
Antimon
sumber
sumber
Jawaban:
Anda dapat menggunakan metode Newton atau salah satu dari sejumlah metode lain untuk menemukan pendekatan ke akar polinomial .p(x)=x2−c
Tingkat konvergensi untuk metode Newton akan kuadrat, yang berarti bahwa jumlah bit yang benar berlipat ganda di setiap iterasi. Ini berarti iterasi metode Newton sudah cukup.O(lgn)
Setiap iterasi dari metode Newton menghitung
Kompleksitas bit dari perkalian adalah O ( b lg b ) , untuk mengalikan dua b- bit integer (mengabaikan faktor lg lg b ). Kompleksitas bit untuk pembagian (ke b bit presisi) adalah sama. Oleh karena itu, setiap iterasi dapat dihitung dalam . Mengalikan dengan iterasi , kami menemukan bahwa keseluruhan waktu berjalan untuk menghitung akar kuadrat menjadi bit presisi adalah . Ini sub-kuadratik.O (blgb) b lglgb b O (nlgn) O(lgn) n O (n(lgn)2)
Saya pikir analisis yang lebih cermat menunjukkan bahwa ini dapat ditingkatkan menjadi waktu berjalan (dengan mempertimbangkan bahwa kita hanya perlu mengetahui setiap untuk mengetahui tentang bit presisi, daripada bit presisi). Namun, bahkan analisis yang lebih mendasar sudah menunjukkan waktu berjalan yang jelas subquadratic.xjjnO (nlgn) xj j n
sumber
Salah satu masalah dengan metode Newton adalah bahwa ia membutuhkan operasi divisi di setiap iterasi, yang merupakan operasi integer dasar paling lambat.
Metode Newton untuk akar kuadrat resiprokal tidak. Jika adalah angka yang ingin Anda temukan 1x , iterate:1x√
Ini sering dinyatakan sebagai:
d i = 1 - w i x r i + 1 = r i + r i d i
Itu tiga operasi multiplikasi. Pembagian dengan dua dapat diimplementasikan sebagai shift-right.
Sekarang masalahnya adalah bahwa bukan bilangan bulat. Namun, Anda dapat memanipulasinya dengan menerapkan floating-point secara manual, dan melakukan banyak operasi shift untuk mengkompensasi bila perlu.r
Pertama, mari kita skala ulang :x
di mana kita ingin lebih besar dari, tetapi mendekati, 1 . Jika kita menjalankan algoritma di atas pada x ′ bukannya x , kita menemukan r = 1x′ 1 x′ x . Lalu,√r=1x√′ .x−−√=2erx′
Sekarang mari kita bagi menjadi mantissa dan eksponen:r
di mana adalah bilangan bulat. Secara intuitif, e i mewakili ketepatan jawaban.r′i ei
Kita tahu bahwa metode Newton secara kasar menggandakan jumlah digit signifikan yang akurat. Jadi kita dapat memilih:
Dengan sedikit manipulasi, kami menemukan:
w i = r ′ i 2 x ′ i = x
Di setiap iterasi:
Sebagai contoh, mari kita coba menghitung akar kuadrat dari . Kami kebetulan tahu bahwa jawabannya adalah 2 31 √x=263 . Akar kuadrat resiprokal adalah 12312–√ , jadi kita akan menetapkane=31(ini adalah skala masalah) dan untuk tebakan awal kita akan memilihr′0=3dane0=2. (Yaitu, kami memilih312√2−31 e=31 r′0=3 e0=2 untuk estimasi awal kami ke134 )12√
Kemudian:
e2=8,r ′ 2 =180e3=16,r ′ 3 =46338e4=32,r ′ 4 =3037000481
Kita bisa mengetahui kapan harus berhenti iterasi dengan membandingkan ke e ; jika saya telah menghitung dengan benar, e i > 2 e harus cukup baik. Kami akan berhenti di sini, dan menemukan:ei e ei>2e
Untuk menganalisis kompleksitas metode ini, perhatikan bahwa mengalikan duab O(blogb) r′i<2ei wi ei ei+1 ei+1 2ei+1 nomor-bit.
Namun, analisis ini menyembunyikan prinsip penting yang harus diingat oleh semua orang yang bekerja dengan bilangan bulat besar: karena perkalian adalah superlinear dalam jumlah bit, setiap operasi penggandaan hanya boleh dilakukan pada bilangan bulat yang kira-kira besarnya presisi saat ini (dan , Saya dapat menambahkan, Anda harus mencoba untuk mengalikan angka-angka yang memiliki urutan yang sama besarnya). Menggunakan bilangan bulat lebih besar dari itu adalah usaha yang sia-sia. Faktor konstan penting, dan untuk bilangan bulat besar, mereka penting.
sumber