Python Altın Oran Matematik Problemi

Merhabalar herkese. Kafama takılan bir python problemi var. Şekilde görüldüğü üzere Python ile fibonacci dizisi tanımlanabiliyor.

def fibonacci(n):

    if n == 0:

        return 0

    elif n == 1:

        return 1

    else:

        return fibonacci(n-2) + fibonacci(n-1)

Bu recursive fonksiyonu kullanarak altın oranında yaklaşık değeri tam olmasada şekildeki gibi bulunur.

fibonacci(23) / fibonacci(22)

Ancak ben görselleştirmede kullanıp görselde göze daha çekici gelmesi için altın oranın tam değerini bu fonksiyona bağlı kullanabilmek istiyorum. Yani bu dizinin son indisini sondan bi önceki indisine bölersem elimde altın oran tam olarak olacak. Sizce ne yapmalıyım ?

dizinin son indisi derken tam olarak neyi kastettin anlamadım. altın oran yakınsayan bir sayı. dizi sonsuza doğru gider.

ayrıca bana sorarsan fibonacci dizisi için rekürsif yerine basit bir liste kullanırsan program daha hızlanacaktır. her sayı için kendine gönderme yapmana gerek yok.

  fibo = [0,1]
  fibo.append(fibo[i-1]+fibo[i-2])

şeklinde i ye bağlı bir döngüde kullanabilirsin.

1 Beğeni

Merhaba.

Sanırım fibonacci fonksiyonuna verilen değerin büyümesi ile altın orana yakınsamadaki doğru orantıyı iki boyutlu bir tabloda göstermek istiyorsunuz. Bunu hangi kütüphane ile görselleştireceksiniz?

Bu arada fibonacci fonksiyonunun özyinelemeli halden döngü kullanan bir hale getirilmesini, hatta her fibonacci sayısını en baştan hesaplamamak için her seferinde bir sonraki sayıyı döndüren bir generatore dönüştürülmesini şiddetle tavsiye ediyorum.

3 Beğeni

Aslında amacım turtle kütüphanesi ile birkaç geometrik şekil çizerek estetiği görmek. Ama güzel şeyler çıkarsa ileri görsel programlama modüllerinede geçmeyi düşünürüm. :grinning:

Görselleştirme kısmını da siz yaparsınız:

import math
from decimal import Decimal

def fibonacci():
    x = 1
    y = 0
    while True:
        yield x
        x, y = x + y, x

i = fibonacci()

altın_oran = (Decimal(5).sqrt() + 1) / 2

print("Altın oran:", altın_oran)

j, k = next(i), next(i)
while True:
    print(Decimal(k) / Decimal(j))
    j = k
    k = next(i)

1 Beğeni

Merhabalar,

Fibonacci serileriyle alakalı alternatif bir yöntemden bahsedeyim.

Bu serisinin fonksiyonel ifadesini Jacques Philippe Marie Binet 1843’te şöyle vermiş:

Fibonacci serisinde n. sırada yer alan sayı, altın oranın köklerinin n. kuvvetlerinin farkının, köklerin kendilerinin farkına olan bölümüne eşittir.

Yani, altın oran (Φ) diye bir irrasyonel sayı ve bu irrasyonel sayının x1 ve x2 diye iki tane kökü var. Bu kökleri bulup, istenen fonksiyonu f(n) = (x1 ** n - x2 ** n) / (x1 - x2) cinsinden yazıp, n. sırada yer alan fibonacci sayısını bulabiliriz.

Altın oran ne diyordu bize?

a > b > 0 durumunda; a'nın b'ye olan oranı, a+b'nin a'ya olan oranına eşitse, a ve b arasında altın oran vardır. Yani;

Φ = a/b = (a+b)/a

Yukardaki formüldeki (a+b)/a ifadesini açacak olsak, şöyle yazamaz mıydık?

(a/a) + (b/a)

a/a da 1'e eşit olur bu durumda. Formül de şöyle değişmez mi?

Φ = a/b = 1+b/a

Madem a/b, altın orana eşit o halde b/a için 1/Φ yazıp formülü yeniden düzenleyelim:

Φ = 1 + 1/Φ

İşte bir denklem elde ettik. Bu denklemi biraz daha değiştiriyorum.

Φ ** 2 - Φ - 1 = 0

Evet, lise zamanlarından aşina olduğumuz bir denkleme benzettik.

Hatırlarsanız, bir denklemin köklerini bulmak için deltayı (Δ) bulmamız lazımdı. Δ'nın formülünü hatırlayalım:

ax^2 + bx + c = 0 denklemi için Δ:

delta = b ** 2 - 4 * a * c

Bir denklemin kökleri nasıl bulunuyordu hatırlayalım:

x1 = (-b + delta ** 0.5) / (2 * a)
x2 = (-b - delta ** 0.5) / (2 * a)

Son elde ettiğimiz denklem şuydu: Φ ** 2 - Φ - 1 = 0. Bu ifadedeki a, b ve c değerleri şöyledir:
a = 1, b = -1, c=-1.

Bu değerleri yerlerine koyarsanız kökler şu sayılara eşit oluyor. x1 = ((1 + 5 ** 0.5) / 2) ve x2 = ((1 - 5 ** 0.5) / 2).

Yukardaki ifadeleri hesaplayacak olursak, x1'in 1.618033988749895... sayısına, x2'nin de -0.6180339887498949... sayısına eşit olduğunu buluruz.

O halde f(n) fonksiyonunu yeniden düzenleyelim:

f(n) = (x1 ** n - x2 ** n) / (x1 - x2) fonksiyonunda yer alan x1 ve x2 parametreleri yerine yeni bulduğumuz değerleri yazarsak, formül şu hale gelir.

f(n) = (((1 + 5 ** 0.5) / 2) ** n - ((1 - 5 ** 0.5) / 2) ** n) / (((1 + 5 ** 0.5) / 2) - ((1 - 5 ** 0.5) / 2))

Bu ifadenin Python dilindeki karşılığı aşağıdaki gibidir:

def nth_fib(n): return (x1 ** n - x2 ** n) / (x1 - x2) if (x1 := (1 + 5 ** 0.5) / 2, x2 := (1 - 5 ** 0.5) / 2) else 0


print(nth_fib(2) / nth_fib(1))
print(nth_fib(3) / nth_fib(2))
print(nth_fib(4) / nth_fib(3))
print(nth_fib(5) / nth_fib(4))
print(nth_fib(100) / nth_fib(99))
print(nth_fib(1000) / nth_fib(999))

İyi çalışmalar.

Binet’in f(n) = (x1n - x2n) / (x1 - x2) formülünü aşağıdaki adımları takip ederek elde edebiliriz:

Yukardaki mesajda, Φ sayısıyla alakalı bir denklem türetmiştik:

Φ2 - Φ - 1 = 0

Bu denklemin köklerini bulmuştuk sonra:

x1 = ((1 + √5) / 2)
x2 = ((1 - √5) / 2)

Şimdi genel bir f fonksiyonu nasıl tanımlarız buna bakalım.

Böyle durumlarda, eldeki bilgileri tekrar gözden geçirmekte yarar var. Bu mevcut bilgileri kullanıp, bazı yer değiştirme esasları uygulayarak genel geçer bir formül elde edebiliyor muyuz araştırmak lazım.

Örneğin, Φ2 - Φ - 1 = 0 denkleminden başlayalım.

Burada, Φ gördüğümüz yere x yazarsak herhangi bir değişiklik yapmamış oluruz.

O halde x2 - x - 1 = 0 ise

x1 = x
x2 = x + 1 olmaz mı?

x3'ü de şu şekilde yazabiliriz değil mi?

x3 = x * x2

Şimdi buradaki x2 ifadesini ortadan kaldırıp, x’e göre bir yazım yapabiliriz. Çünkü x2'ın ne olduğunu biliyoruz. O halde:

x3 = x * (x + 1) olur. Bu da aşağıdaki ifadeye eşittir.

x3 = x2 + x

x2 yerine x + 1 yazmaya devam ediyorum.

x3 = x + 1 + x = 2 * x + 1

Evet x4'e geçelim.

x4 = x * x3

x3 yerine 2 * x + 1 yazıyorum.

x4 = x * (2 * x + 1)
x4 = 2 * x2 + x

x2 yerine x + 1 yazıyorum.

x4 = 2 * (x + 1) + x
x4 = 3 * x + 2

Bu yaklaşımı devam ettirirsek, x5'in değerinin 5 * x + 3, x6'nın 8 *x + 5, x7'nin 13 * x + 8 olduğunu buluruz.

Sonuçları alt alta bir daha yazalım.

x1 = x
x2 = x + 1
x3 = 2 * x + 1
x4 = 3 * x + 2
x5 = 5 * x + 3
x6 = 8 * x + 5
x7 = 13 * x + 8

Burada sizin de gözünüze bir örüntü çarpmış olmalı. x’in üssü 1, 2, 3, 4, 5 … diye artıkça, x’in katsayıları da fibonacci serisinin 1. 2. 3. 4. … indislerinde yer alan değerleri alıyorlar. Öte yandan denklemdeki sabit ise Fibonacci serisini 1 adım geriden takip ederek değerler alıyor.

Biz fibonacci serisini bulan fonksiyona f ismini vermiştik. Yani:

x7 = 13 * x + 8 ise

f(7)'nin bize 13 değerini, f(6)'nın da 8 değerini vermesi gerekir.

O halde, xn ifadesini yazacak olursak şöyle yazamaz mıyız?

xn = f(n) * x + f(n - 1)

Fibonacci denkleminin köklerini bu denklemlere yazalım.

x1n = f(n) * x1 + f(n - 1)

x2n = f(n) * x2 + f(n - 1)

Şimdi bu iki ifadeyi birbirinden çıkartabiliriz.

x1n - x2n = f(n) * x1 + f(n - 1) - f(n) * x2 - f(n - 1)

f(n - 1)'ler birbirini götürür, elimizde şöyle bir formül kalır:

x1n - x2n = f(n) * x1 - f(n) * x2

Yukardaki ifadeyi f(n) parantezine alabiliriz.

x1n - x2n = f(n) * (x1 - x2)

f(n)'i yalnız bırakalım.

f(n) = (x1n - x2n) / (x1 - x2)

Gördüğünüz gibi son adımda fibonacci dizisinin fonksiyonel formülünü elde ettik. Fibonacci sayısının köklerini de bulmuştuk zaten. Bu kökleri, son elde ettiğimiz formüldeki yerlerine koyarak Fibonacci serisinin n. basamağındaki değeri O(1) hızında bulabiliriz.