Effizienter Algorithmus zur Berechnung der


11

Die te Fibonacci-Zahl kann in linearer Zeit unter Verwendung der folgenden Wiederholung berechnet werden:n

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

Die - te Fibonacci - Zahl kann auch wie folgt berechnet werden [ φ n / n. Dies hat jedoch Probleme mit Rundungsproblemen für selbst relativ kleinen. Es gibt wahrscheinlichMöglichkeiten, dies zuumgehen, aber ich würde das lieber nicht tun.[φn/5]n

Gibt es einen effizienten (logarithmischen im Wert oder besser) Algorithmus, um die n- te Fibonacci-Zahl zu berechnen , die nicht auf Gleitkomma-Arithmetik beruht? Nehmen Sie an, dass Ganzzahloperationen ( + , - , × , / ) in konstanter Zeit ausgeführt werden können.nn+×/


5
Der Wikipedia-Artikel über Fibonacci-Zahlen enthält viele Methoden.
Pseudonym

vgl. stackoverflow.com/questions/14661633/… und Links darin und in der Umgebung.
Will Ness

Antworten:


14

Sie können Matrix-Powering und die Identität In Ihrem Berechnungsmodell ist dies ein O ( log n ) -Algorithmus, wenn Sie das Powering durch wiederholtes Quadrieren implementieren.

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

1
Es ist ein Klassiker.
dfeuer

8
Sie können diese Identität auch verwenden, um die Wiederholungen und F 2 n = F 2 n + 2 F n - 1 F n abzuleiten . F2n1=Fn2+Fn12F2n=Fn2+2Fn1Fn
Augurar

4

Sie können diesen mathematischen Artikel lesen: Ein schneller Algorithmus zur Berechnung großer Fibonacci-Zahlen (Daisuke Takahashi): PDF .

Einfacher ausgedrückt, habe ich mehrere Fibonacci-Algorithmen in C ++ (ohne und mit GMP) und Python implementiert. Komplette Quellen auf Bitbucket. Auf der Hauptseite können Sie auch Links folgen zu:

  • Die C ++ HTML Online-Dokumentation.
  • Ein kleines mathematisches Dokument: Fibonacci-Zahlen - verschiedene Relationen, um gute Algorithmen zu implementieren

Die nützlichsten Formeln sind:

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

Seien Sie vorsichtig beim Algorithmus. Sie dürfen nicht mehrmals denselben Wert berechnen. Ein einfacher rekursiver Algorithmus (in 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)

Seine Komplexität ist logarithmisch (wenn die Grundoperationen in konstanter Zeit ablaufen): .O(logn)


2
Willkommen in der Informatik . Können Sie Ihrer Antwort weitere Informationen hinzufügen? Momentan sind es nicht mehr als zwei Links, sodass Ihre Antwort bedeutungslos wird, wenn diese Links sterben oder die Server, auf denen sie sich befinden, nicht verfügbar sind. Links zu weiteren Informationen sind in Ordnung, aber die Links hier sind die einzigen Informationen. Beachten Sie auch, dass es sich bei der Frage eindeutig um Algorithmen handelt, nicht um C ++ - Implementierungen. Implementierungen tendieren dazu, die Algorithmen hinter sprachspezifischen Details zu verschleiern.
David Richerby

David, der erste Link ist ein Link zu einem mathematischen Artikel. Der Titel Ein schneller Algorithmus [...] beantwortet die Frage "Gibt es einen effizienten (logarithmischen im Wert n oder besser) Algorithmus [...]?" Der zweite Link ist ein Link zu meinen verschiedenen Implementierungen in C ++ und Python sowie ein kleines mathematisches Dokument mit mehreren Formeln.
Olivier Pirson

2
Nein, der Titel des Artikels, den Ihre Antwort enthält, beantwortet nichts. Der Text des Artikels, von dem Ihre Antwort so gut wie keinen enthält, scheint die Frage wahrscheinlich zu beantworten. Stack Exchange ist jedoch eine Frage- und Antwortsite, keine Linkfarm. (Und nein, ich schlage nicht vor, dass Sie den Artikel kopieren und in Ihre Antwort einfügen. Es wird jedoch eine Zusammenfassung benötigt.)
David Richerby

Wenn Sie eine Zusammenfassung wünschen, schreiben Sie sie!
Olivier Pirson

0

Grundlegende Theorie und Code zur Berechnung linearer Wiederholungen mit konstanten Koeffizienten in Ö(Log2n)ist abrufbar unter http://www.jjj.de/ .

Überprüfen Sie das kostenlose Buch Matters Computational und den Pari- / GP-Code.


5
Es ist besser, die Ideen zusammenzufassen, als nur Links zu posten.
26.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.