อัลกอริทึมที่มีประสิทธิภาพในการคำนวณหมายเลขฟีโบนักชีที่


11

จำนวนที่ Fibonacci สามารถคำนวณในเวลาเชิงเส้นโดยใช้การเกิดซ้ำดังต่อไปนี้:n

def fib(n):
    i, j = 1, 1
    for k in {1...n-1}:
        i, j = j, i+j
    return i

หมายเลขที่ Fibonacci สามารถคำนวณได้ด้วย[ φ n / n. แต่นี้มีปัญหากับการปัดเศษปัญหาแม้มีขนาดค่อนข้างเล็กn อาจมีวิธีการรอบนี้แต่ฉันไม่อยากทำอย่างนั้น[φn/5]n

มีอัลกอริทึม(ลอการิทึมในค่าหรือดีกว่า) ที่มีประสิทธิภาพเพื่อคำนวณจำนวนฟีโบนักชีที่nที่ไม่พึ่งพาเลขคณิตจุดลอยตัวหรือไม่? สมมติว่าการดำเนินการจำนวนเต็ม ( + , - , × , / ) สามารถดำเนินการได้ในเวลาคงที่nn+×/


5
เป็นข้อเสนอแนะบทความ Wikipedia เกี่ยวกับหมายเลข Fibonacci มีวิธีการมากมาย
นามแฝง

cf เลย stackoverflow.com/questions/14661633/…และลิงก์ในนั้นและรอบ ๆ
Will Ness

คำตอบ:


14

[1110]n=[Fn+1FnFnFn1].
O(logn)

1
มันคลาสสิก
dfeuer

8
F2n1=Fn2+Fn12F2n=Fn2+2Fn1Fn

4

คุณสามารถอ่านบทความทางคณิตศาสตร์นี้: ขั้นตอนวิธีการอย่างรวดเร็วสำหรับการคำนวณตัวเลข Fibonacci ขนาดใหญ่ (ไดสุเกะทากาฮาชิ): รูปแบบไฟล์ PDF

ง่ายกว่านี้ฉันได้ติดตั้งอัลกอริทึมของฟีโบนักชีหลายรูปแบบใน C ++ (โดยไม่ต้องและด้วย GMP) และ Python แหล่งข้อมูลที่สมบูรณ์บน Bitbucket จากหน้าหลักคุณสามารถติดตามลิงค์ไปยัง:

  • เอกสารออนไลน์ C ++ HTML
  • เอกสารทางคณิตศาสตร์เล็กน้อย: หมายเลขฟีโบนักชี - ความสัมพันธ์หลายอย่างที่จะใช้อัลกอริธึมที่ดี

สูตรที่มีประโยชน์ที่สุดคือ:

  • F2n=Fn+12Fn12=2FnFn1+Fn2
  • F2n+1=Fn+12+Fn2

ระวังอัลกอริทึม คุณต้องไม่คำนวณค่าเดียวกันหลาย ๆ ครั้ง อัลกอริทึมแบบเรียกซ้ำง่าย ๆ (ใน Python):

def fibonacci_pair(n):
    """Return (F_{n-1}, F_n)"""
    if n != 0:
        f_k_1, f_k = fibonacci_pair(n//2)  # F_{k-1},F_k with k = n/2

        return ((f_k**2 + f_k_1**2,
                 ((f_k*f_k_1)*2) + f_k**2) if n & 1 == 0  # even
                else (((f_k*f_k_1)*2) + f_k**2,
                      (f_k + f_k_1)**2 + f_k**2))
    else:
        return (1, 0)

O(logn)


2
ยินดีต้อนรับสู่วิทยาการคอมพิวเตอร์ โปรดเพิ่มข้อมูลลงในคำตอบของคุณได้ไหม? ในขณะนี้ไม่มีอะไรมากไปกว่าสองลิงก์ดังนั้นคำตอบของคุณจะไม่มีความหมายหากลิงก์เหล่านั้นตายหรือเซิร์ฟเวอร์ที่ใช้งานไม่พร้อมใช้งาน ลิงก์ไปยังข้อมูลเพิ่มเติมนั้นใช้ได้ แต่ลิงค์ที่นี่เป็นเพียงข้อมูลเท่านั้น นอกจากนี้โปรดทราบว่าคำถามนี้เกี่ยวกับอัลกอริธึมอย่างแน่นอนไม่ใช่เกี่ยวกับการใช้งาน C ++ การใช้งานมีแนวโน้มที่จะปิดบังอัลกอริทึมที่อยู่เบื้องหลังรายละเอียดเฉพาะภาษา
David Richerby

David ลิงก์แรกคือลิงก์ไปยังบทความทางคณิตศาสตร์ ชื่ออัลกอริทึมที่รวดเร็ว [... ]ตอบคำถาม "มีอัลกอริทึมที่มีประสิทธิภาพ (ลอการิทึมในค่า n หรือดีกว่า) [... ] หรือไม่" ลิงค์ที่สองคือลิงค์ไปสู่การใช้งานที่หลากหลายของฉันใน C ++ และ Python และเอกสารทางคณิตศาสตร์เล็กน้อยที่มีหลายสูตร
Olivier Pirson

2
ไม่ชื่อของบทความซึ่งเป็นคำตอบของคุณมีอะไรตอบไม่มีอะไร ข้อความของบทความซึ่งคำตอบของคุณมีเกือบไม่มีเสียงเหมือนมันอาจจะไม่ตอบคำถาม แต่ Stack Exchange เป็นเว็บไซต์คำถามและคำตอบไม่ใช่ฟาร์มลิงก์ (และไม่ฉันไม่ได้บอกว่าคุณคัดลอกวางบทความลงในคำตอบของคุณ แต่สรุปเป็นสิ่งจำเป็น..)
เดวิด Richerby

หากคุณต้องการข้อมูลสรุปเขียนมัน!
Olivier Pirson

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.