Saya mencari algoritma yang efisien untuk masalah ini:
Input : Bilangan bulat positif (disimpan sebagai bit) untuk beberapa bilangan bulat .
Output : Jumlahnya .
Pertanyaan : Bisakah kita menghitung dari bit dalam waktu ?
Ini adalah pertanyaan teoretis yang dimotivasi oleh jawaban saya terhadap matematika. Pertanyaan SE Bagaimana cara menemukan formula untuk penambangan ini? . Dalam pertanyaan ini, penulis ingin menemukan bijection dari dan bilangan asli . Saya mengusulkan sebagai solusi. Jawaban lain di sana menegaskan "tidak ada rumus sederhana", yang membuat saya bertanya-tanya bagaimana (secara komputasi) sederhana solusi yang saya usulkan.
Dengan solusi yang saya usulkan, jika kita tahu dan , kita dapat dengan mudah menghitung (tulis digit biner dari diikuti oleh diikuti oleh nol). Ini membutuhkan waktu .
Menemukan dari bit sama dengan menemukan bit paling signifikan (yang dapat dihitung dengan menghitung pergeseran bit kanan, meninggalkan dalam memori). Ini membutuhkan waktu .2 m 3 n 3 n O ( m )
Namun, kita juga perlu menemukan , yang mungkin lebih sulit. Adalah mungkin untuk menemukan dengan berulang kali membaginya dengan , tetapi ini tampaknya sia-sia. Ini membutuhkan operasi divisi , yang masing-masing akan memakan waktu , jadi ini adalah total waktu . [Sebenarnya, setelah setiap iterasi, jumlah digit akan berkurang secara linear, tetapi ini masih menghasilkan waktu .]n 3 n O ( n ) O ( n 2 ) O ( n 2 )
Sepertinya kita harus bisa mengeksploitasi mengetahui input adalah kekuatan .
sumber
Jawaban:
Pendekatan yang jelas adalah:
(1) Hitung aproksimasi ke . Anda dapat memperkirakannya dalam kesalahan aditif 1 dengan menghitung jumlah bit dalam representasi biner yang diberikan, dan ke dalam kesalahan aditif dengan tambahan melihat bagian atas bit dari input. Seharusnya cukup untuk memilih nilai konstan , sehingga (setelah digabungkan dengan kesalahan pada langkah (2)) hasil akhir berakhir dengan kesalahan aditif dari yang benar.ϵ O ( log 1log2(3n) ϵ ε1/2O(log1ϵ) ϵ 1/2
(2) Hitung aproksimasi ke . Saya tidak terbiasa dengan algoritma untuk ini tetapi saya berharap mereka membutuhkan waktu polinomial dalam jumlah bit yang Anda butuhkan, dan Anda hanya perlu bit presisi.O ( log n )log2(3) O(logn)
(3) Bagi jawaban (1) dengan jawaban (2), dan bulatkan ke bilangan bulat terdekat.
Jadi langkah pertama membutuhkan waktu linier (dalam sebagian besar model perhitungan meskipun mungkin tidak untuk beberapa yang kurang bertenaga seperti mesin Turing satu-kepala ) dan langkah-langkah yang tersisa harus polylogarithmic.
sumber
Untuk bilangan bulat apa pun , menulis 3 n dalam biner membutuhkan tepat L = ⌈ log 2 ( 3 n ) + 1 ⌉ bit. Beberapa aljabar dasar menyiratkan bahwa L - 2n>0 3n L=⌈log2(3n)+1⌉
Untuk setiap panjang bitL≥1, ada paling banyak satu bilangan bulat dalam kisaran ini. Dengan demikian, diberi kekuatan integral3yaitupanjangLbit, eksponen harus bilangan bulat
n=⌊L-1
sumber
Oleh karena itu, dengan menggunakan log diskrit dan pengangkatan Hensel, saya pikir Anda harus dapat menghitung dari angka rendah sangat efisien. Dengan kata lain, Anda mulai dengan menghitung dari digit rendah , dengan mengambil log diskrit ke basis , modulo ; ini mengungkapkan , dan dapat dilakukan dalam waktu. Kemudian, Anda menemukan log diskrit ke basis , modulo ; ini mengungkapkan , dan dapat dilakukan dik 3 n n mod 4 3 n 3 n mod 5 3 5 n mod 4 O ( 1 ) 3 n mod 25nmodφ(5k) k 3n nmod4 3n 3nmod5 3 5 nmod4 O(1) 3nmod25 25 n mod 20 O ( 1 ) n mod 4 5 n mod φ ( 5 k - 1 ) 3 n mod 5 k 5 n mod φ ( 5 k )e 25 nmod20 O(1) waktu (memanfaatkan pengetahuan tentang , hanya ada kemungkinan yang harus Anda coba). Pengulangan. Pada setiap langkah, Anda menggunakan pengetahuan untuk membantu Anda menghitung log diskrit , memanfaatkan fakta bahwa hanya ada nilai yang mungkin untuk .nmod4 5 nmodφ(5k−1) 3nmod5k 5 nmodφ(5k)
Sekarang biarkan menjadi cukup besar, dan ini mengungkapkan .nk n
Anda harus mengetahui apakah waktu yang berjalan adalah , tetapi sepertinya bagi saya sepertinya. Saya kira cukup untuk membiarkan , dan saya curiga Anda dapat melakukan setiap iterasi dalam waktu , untuk total waktu .k = O ( n ) O ( 1 ) O ( n )O(n) k=O(n) O(1) O(n)
sumber