Fibonacci genap angka

Terinspirasi oleh komentar di bawah pos Fibonacci untuk wawancara . Pengguna pavellyzhin menyebutkan tugas wawancara berikut ( komentar ):
Lebih dari setahun yang lalu, "php-programmer" merespons lowongan itu, mereka mengirim TK dan ada tugas dari Fibonacci: pilih semua bahkan angka Fibonacci dalam kisaran 1 hingga 10.000 . Memutuskan menggunakan loop (untuk). Di sana, juga diperlukan untuk membuat kueri SQL untuk memilih ulang tahun pengguna terdekat, untuk membuat sesuatu, saya tidak ingat dan menulis semacam fungsi. Saya melakukan segalanya, mengirimkannya. Mereka mengirim jawaban: "sesuai dengan hasil tugas tes Anda tidak diterima." Apa yang sebenarnya tidak mereka sukai tidak tertulis. Sekarang saya duduk dan berpikir, mungkin karena Fibonacci saya terbang ... :)
Dalam posting ini saya akan menunjukkan bagaimana mungkin untuk menyelesaikan masalah ini secara efektif, dan mungkin bahkan secara efisien, tetapi ini tidak akurat. Pada saat yang sama saya akan menunjukkan beberapa ribuan fakta yang terbukti tentang angka Fibonacci.


Berteori



Cara terbaik untuk memulai adalah melihat melalui mata angka Fibonacci N pertama dan mencoba menemukan pola dalam pengaturan angka genap.

1.1, bf2,3.5, bf8,13.21, bf34,55.89, bf144, ldots


Angka genap ditandai dalam urutan, karena Anda dapat melihat setiap angka Fibonacci ke-3 genap dan, mungkin, semua angka genap berada di posisi kelipatan 3. Ini akan menjadi perkiraan kami, sekarang kami perlu mengonfirmasinya dan menyusun algoritma perhitungan.

Bukti terbaik adalah sederhana, jadi terima kasih kepada AllexIn untuk ide sederhana yang awalnya saya lewatkan. Setiap angka Fibonacci berikutnya adalah jumlah dari dua sebelumnya, jika dua angka sebelumnya ganjil, maka yang berikutnya akan genap, jika dalam dua angka sebelumnya satu ganjil dan yang lain genap, maka yang berikutnya akan ganjil. Pada prinsipnya, ide ini saja sudah cukup untuk "secara intuitif meraba-raba" fakta yang telah terbukti. Buktinya dengan induksi sudah jelas, tapi saya tidak bisa menolak, agar tidak membawanya

Kami membuktikan bahwa "setiap angka Fibonacci ketiga adalah genap, dan dua yang mendahului setiap angka tersebut adalah ganjil."
  • Induksi dasar . Dua angka fibonacci pertama 1,1 - aneh, nomor ketiga 2 - bahkan
  • Hipotesis . Misalkan hingga beberapa angka Fibonacci kelipatan 3, memang benar bahwa setiap sepertiga adalah genap, dan dua angka sebelumnya adalah aneh.
  • Langkah induksi . Angka yang mengikuti angka genap terakhir dari hipotesis adalah ganjil, karena itu diperoleh dari jumlah ganjil dengan genap, mengikuti angka yang sudah juga ganjil, karena itu diperoleh dari jumlah genap dengan yang ganjil, dan selanjutnya setelah genap, karena dua yang sebelumnya baru saja diterima untuknya aneh, dengan konstruksi nomornya adalah kelipatan 3, itu genap, dan dua yang sebelumnya aneh.


Ini adalah bagaimana kita dapat membuktikan dugaan kita tanpa menggunakan perhitungan matematis. Anda dapat memformalkan ide ini, pada saat yang sama mendapatkan formula untuk menghitung setiap angka Fibonacci ketiga Fn+3 dari Fn dan Fn+1 . Menggunakan hubungan rekursif Fn+2=Fn+1+Fn kami mendapatkan:

Fn+3=Fn+2+Fn+1=2Fn+1+Fn


Jadi jika Fn - bahkan saat itu Fn+3 juga bahkan berdasarkan formula ini. Mengingat itu F3=2 , maka setiap angka Fibonacci ketiga benar-benar genap, yang menegaskan bagian dari perkiraan kami. Di sini Anda perlu memastikan bahwa kami tidak kehilangan nomor genap lainnya, yaitu bahwa mereka semua memiliki kelipatan 3. Terima kasih kepada janatem untuk idenya yang sederhana, karena dari rumus di atas untuk Fn+3 itu juga mengikuti bahwa jika Fn - aneh kalau begitu Fn+3 juga aneh, jadi kami mendapatkan angka itu dengan angka 3kβˆ’2,3kβˆ’1,k in mathbbN - aneh (dengan induksi, mulai dengan F1=F2=1 - aneh), dan 3k,k in mathbbN - even, yang mencakup semua angka Fibonacci, yang artinya kita benar-benar mencakup semua angka genap.

Ada cara lain, karena mungkin untuk menunjukkan bahwa tidak ada angka genap lainnya. Misalkan ada nomor Fm - bahkan dan 0 tidak equivm mod3 lalu m=3kβˆ’1 atau m=3k+1 dimana k - semacam alami.

Mari kita beralih ke representasi matriks angka Fibonacci dari pos asli

\ begin {pmatrix} 0 & 1 \\ 1 & 1 \ end {pmatrix} ^ n = \ begin {pmatrix} F_ {n-1} & F_n \\ F_n & F_ {n + 1} \ end {pmatrix}

\ begin {pmatrix} 0 & 1 \\ 1 & 1 \ end {pmatrix} ^ n = \ begin {pmatrix} F_ {n-1} & F_n \\ F_n & F_ {n + 1} \ end {pmatrix}


Menghitung penentu kedua bagian, kita dapatkan

(βˆ’1)n=Fn+1Fnβˆ’1βˆ’F2n


Oleh karena itu pembagi angka Fn+1,Fn dan Fnβˆ’1,Fn pembagi pertandingan (βˆ’1)n , yaitu angka-angka Fibonacci tetangga saling sederhana. Ini juga berarti kesederhanaan dan angka yang saling menguntungkan F3k,F3kβˆ’1 dan F3k,F3k+1 , yaitu F3k dan Fm . Tetapi dengan asumsi Fm - bahkan, dan F3k - bahkan seperti yang telah dibuktikan sebelumnya. Jadi nomor genap lainnya F3k dimana k in mathbbN dalam deret Fibonacci tidak ada. Dan kami juga menetapkan fakta menarik bahwa angka-angka Fibonacci yang berdekatan saling sederhana.

Akhirnya, kami menunjukkan setidaknya satu cara lagi untuk membuktikan dugaan kami: gunakan teorema Lukas.

Teorema Lukas . Membagi bilangan bulat Fm , dan Fn , jika dan hanya jika itu adalah pembagi Fd dimana d= gcd(m,n) khususnya

 gcd(Fm,Fn)=F gcd(m,n)


Di sini  gcd Merupakan faktor umum terbesar. Jika dimasukkan m=3 lalu  gcd(2,Fn)=F gcd(3,n) . Jika Fn - bahkan, maka sisi kiri adalah 2, sehingga sisi kanan juga sama dengan 2, perlu itu n dibagi 3 dan pada saat yang sama kebalikannya benar. Jadi, kita mendapatkan apa yang ingin kita buktikan.

Jadi, setiap angka Fibonacci ketiga adalah genap, dan setiap angka genap memiliki kelipatan tiga. Kami telah membuktikan ini dengan hati-hati dan tidak ada yang berani meragukannya sekarang.

Algoritma


Dan sekarang masih muncul dengan sebuah algoritma. Anda tentu saja dapat melakukan apa yang pavellyzhin awalnya lakukan, tetapi bukannya memeriksa 0 equivFn mod2 kita bisa periksa 0 equivn mod3 , ini memelintir! Benar, ini tidak mempengaruhi jumlah iterasi dari algoritma, karena kami baru saja mengubah filter urutan. Lebih baik segera menghasilkan nomor Fibonacci berikutnya dengan properti yang kita butuhkan (paritas), jadi cara lain yang jelas adalah dengan menggunakan rumus Binet

F_n = \ kiri \ lfloor \ frac {\ varphi ^ n} {\ sqrt {5}} \ kanan \ rceil, \ qquad n \ dalam \ {3,6, \ ldots, 3k \ ldots \}

F_n = \ kiri \ lfloor \ frac {\ varphi ^ n} {\ sqrt {5}} \ kanan \ rceil, \ qquad n \ dalam \ {3,6, \ ldots, 3k \ ldots \}


Ada kesulitan dengan efisiensi perhitungan, lebih lanjut tentang ini di pos asli. Karena itu, saya mengusulkan yang terbaik, menurut saya, metode - perhitungan iteratif Fn+3 , ini bisa dilakukan, seperti yang kami tunjukkan sebelumnya, dengan formula Fn+3=2Fn+1+Fn . Untuk membangun transisi berulang dalam algoritma, kita perlu menghitung Fn+4 Semuanya serba sederhana

Fn+4=Fn+3+Fn+2=2Fn+1+Fn+Fn+1+Fn=3Fn+1+2Fn


Ngomong-ngomong, secara umum, mudah untuk membuktikannya

Fn+m=FmFn+1+Fmβˆ’1Fn


Kemudian secara formal algoritma ditulis sebagai berikut (angka Fibonacci bahkan saat ini Fn diikuti oleh angka Fibonacci Fn+1 , M Apakah batas atas untuk angka yang diberikan dalam kondisi masalah):

  1. Fn leftarrowF3=2, quadFn+1 leftarrowF4=3
  2. Jika Fn>M , lalu selesaikan, jika tidak tambahkan hasilnya Fn
  3. (Fn,Fn+1) leftarrow(2Fn+1+Fn,3Fn+1+2Fn) lanjut ke langkah 2.

Algoritma ini cukup sepele - kita cukup melompat ke setiap nomor Fibonacci ketiga dan mencetaknya (jika tidak lebih M ) Kompleksitas algoritma masih linier, tetapi jumlah pengulangan langkah 2 persis sama dengan jumlah angka Fibonacci bahkan dalam kisaran 1 ldotsM , untuk perbandingan, algoritma sederhana dengan penyaringan membutuhkan iterasi 3 kali lebih banyak (untuk setiap yang ditemukan, akan ada 2 yang dibuang).

Algoritma ada di atas kertas, apa wawancara, PHP? Nah, akhirnya mengungkap berarti PHP

function evenfibs($ubound) { $result = []; [$evenf, $nextf] = [2, 3]; while($evenf <= $ubound) { array_push($result, $evenf); [$nextf, $evenf] = [ 3 * $nextf + 2 * $evenf, 2 * $nextf + $evenf]; } return $result; } 


Catatan : Metode ini selalu dapat ditingkatkan, seperti, misalnya, pengguna hunroll menunjukkan. Idenya adalah bahwa untuk perhitungan kita tidak perlu sesuatu yang berlebihan, kecuali untuk hasil yang diperoleh sebagian, yaitu kita bisa menghitung bilangan genap hanya dengan menggunakan bilangan Fibonacci genap sebelumnya.

Fn+3=2Fn+1+Fn=3Fn+2Fnβˆ’1=3Fn+Fnβˆ’1+Fnβˆ’1=3Fn+(Fnβˆ’1+Fnβˆ’2)+Fnβˆ’3=4Fn+Fnβˆ’3



 function evenfibs($ubound) { if($ubound < 2) return []; $evens = [2]; $next = 8; for($i = 1; $next <= $ubound; $i++) { $evens[$i] = $next; $next = $evens[$i]*4 + $evens[$i-1]; } return $evens; } 


Generalisasi


Kami menyebutkan di sini teorema Lukas, yang menyatakan itu  gcd(Fm,Fn)=F gcd(m,n) . Sebagai akibatnya, kita bisa mendapatkan angka Fibonacci Fn kelipatan dari Fm , jika dan hanya jika jumlahnya n beberapa ke nomor m . Yaitu setiap angka 4 Fibonacci dibagi 3, setiap 5 dengan 5, setiap 6 dengan 8, dll.

Kemudian, dengan cara yang sederhana, kita memperoleh algoritma untuk menghitung urutan Fibonacci, di mana unsur-unsurnya adalah kelipatan dari beberapa angka yang diberikan Fm . Menggunakan fakta itu

Fn+m=FmFn+1+Fmβˆ’1FnFn+m+1=Fm+1Fn+1+FmFn


Algoritma sebelumnya berubah menjadi

  1. Fn leftarrowFm, quadFn+1 leftarrowFm+1
  2. Jika Fn>M , lalu selesaikan, jika tidak tambahkan hasilnya Fn
  3. (Fn,Fn+1) leftarrow(FmFn+1+Fmβˆ’1Fn,Fm+1Fn+1+FmFn) lanjut ke langkah 2.

Dimana Fmβˆ’1,Fm,Fm+1 dapat diatur sebagai konstanta.

Ringkasan catatan . Seperti yang benar-benar diperhatikan oleh pengguna, dalam kasus umum, juga dimungkinkan untuk membuat algoritma yang hanya menggunakan angka dari hasil sebagian.

Fn+1=Fn+Fnβˆ’1Fn+2=3Fnβˆ’Fnβˆ’2Fn+3=4Fn+Fnβˆ’3Fn+4=7Fnβˆ’Fnβˆ’4Fn+5=11Fn+Fnβˆ’5 cdotsFn+t=(Ft+2Ftβˆ’1)Fn+(βˆ’1)tβˆ’1Fnt



Mari kita buktikan dengan metode induksi matematika, untuk t = 1 dan t = 2, pemenuhannya jelas. Misalkan tahan hingga beberapa t; lalu

Fn+t+1=Fn+t+Fn+tβˆ’1=(Ft+2Ftβˆ’1)Fn+(βˆ’1)tβˆ’1Fnt+(Ftβˆ’1+2Ftβˆ’2)Fn+(βˆ’1)tβˆ’2Fnβˆ’t+1=(Ft+Ftβˆ’1+2(Ftβˆ’1+Ftβˆ’2))Fn+(βˆ’1)tβˆ’1(Fntβˆ’Fnβˆ’t+1)=(Ft+1+2Ft)Fn+(βˆ’1)tβˆ’1(Fntβˆ’Fntβˆ’Fntβˆ’1)=(Ft+1+2Ft)Fn+(βˆ’1)tFntβˆ’1



Sesuatu seperti total


Tugas tentu saja sepenuhnya sintetik, jumlah iterasi sangat kecil (untuk M=$10.00 jawabannya hanya berisi 6 angka, mis. 6 iterasi akan selesai, dan algoritma "head-on" yang asli akan membutuhkan 18), tetapi dengan cara ini pengguna yang menemukan sesuatu yang baru di sini sekarang dapat menunjukkan sedikit pengetahuan matematika yang lebih dalam pada angka-angka Fibonacci pada wawancara.

Sunting: Terima kasih kepada pengguna janatem dan AllexIn untuk bukti sederhana, saya memasukkannya ke dalam β€œTeoriisasi”, serta hunroll untuk algoritme hanya dengan menggunakan angka genap yang telah diperoleh dalam perhitungan dan kepada pengguna yang tidak tahu untuk menggeneralisasikannya.

Source: https://habr.com/ru/post/id450594/


All Articles