Etkin algoritma hesaplamak için


11

Fibonacci sayısı inci aşağıdaki nüks kullanılarak doğrusal bir sürede elde edilebilir:n

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

olarak Fibonacci sayısı inci da hesaplanabilir . Ancak, bu nispeten küçük n bile yuvarlama sorunları ile ilgili sorunlar var . Bunun etrafında muhtemelen yollar var ama bunu yapmamayı tercih ederim.n[φn/5]n

(Değerinde logaritmik etkin var hesaplamak için algoritma ya da daha iyi) n kayar nokta aritmetik dayanmaz Fibonacci sayıda inci? Tamsayı işlemlerinin ( + , - , × , / ) sabit zamanda yapılabileceğini varsayın .nn+×/


5
Bir öneri olarak, Fibonacci sayıları hakkındaki Wikipedia makalesinde birçok yöntem vardır.
Takma isim

bakınız stackoverflow.com/questions/14661633/… ve içerideki ve etrafındaki bağlantılar.
Ness Ness

Yanıtlar:


14

Matris gücünü ve kimliğini kullanabilirsiniz . Hesaplama modelinizde, gücü uygulamak için tekrarlanan kareler kullanıyorsanız , bu bir O ( log n ) algoritmasıdır.

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

1
Bu bir klasik.
dfeuer

8
Bu kimliği, ve F 2 n = F 2 n + 2 F n - 1 F n tekrarlarını türetmek için de kullanabilirsiniz . F2n1=Fn2+Fn12F2n=Fn2+2Fn1Fn
augurar

4

Bu matematiksel makaleyi okuyabilirsiniz: Büyük Fibonacci sayılarını hesaplamak için hızlı bir algoritma (Daisuke Takahashi): PDF .

Daha basit, C ++ (GMP olmadan ve GMP ile) ve Python'da birkaç Fibonacci algoritması uyguladım. Bitbucket ile ilgili tüm kaynaklar . Ana sayfadan aşağıdaki bağlantılara da gidebilirsiniz:

  • C ++ HTML çevrimiçi belgeleri.
  • Biraz matematiksel belge: Fibonacci sayıları - iyi algoritmalar uygulamak için birkaç ilişki

En yararlı formüller:

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

Algoritma konusunda dikkatli olun. Aynı değeri birkaç kez hesaplamamalısınız. Basit bir özyinelemeli algoritma (Python'da):

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)

Karmaşıklığı logaritmiktir (temel işlemler sabit zamanda ise): .O(logn)


2
Bilgisayar Bilimine Hoşgeldiniz . Lütfen cevabınıza daha fazla bilgi ekleyebilir misiniz? Şu anda, iki bağlantıdan başka bir şey değildir, bu yüzden bu bağlantılar ölürse veya bulundukları sunucular kullanılamazsa cevabınız anlamsız hale gelir. Daha fazla bilgiye bağlantılar iyidir ancak buradaki bağlantılar tek bilgidir. Ayrıca, sorunun kesinlikle C ++ uygulamaları hakkında değil, algoritmalar hakkında olduğunu unutmayın. Uygulamalar dile özgü ayrıntıların arkasındaki algoritmaları gizleme eğilimindedir.
David Richerby

David, ilk bağlantı matematiksel bir makalenin bağlantısıdır. Başlık hızlı bir algoritma [...] sorusuna cevaplar "algoritma [...] (n ya da daha iyi değer logaritmik) etkin var mı?" İkinci bağlantı, C ++ ve Python'daki çeşitli uygulamalara ve çeşitli formüllere sahip küçük bir matematiksel belgeye bir bağlantıdır.
Olivier Pirson

2
Hayır, cevabınızın içerdiği makalenin başlığı hiçbir şeyi yanıtlamıyor. Metin muhtemelen soruyu cevaplamak yaptığı gibi cevap, sesleri neredeyse hiçbirini içermeyen, eşyanın. Ancak Stack Exchange bir bağlantı çiftliği değil, bir soru-cevap sitesidir. (Ve hayır, makaleyi cevabınıza kopyalayıp yapıştırmanızı
önermiyorum

Bir özet istiyorsanız, yazın!
Olivier Pirson

0

O(log2n)

Matters Computational adlı ücretsiz kitabı ve pari / gp kodunu kontrol edin.


5
Sadece bağlantı göndermek yerine fikirleri özetlemek daha iyidir.
augurar
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.