Fibonacci'nin naif özyineleme sürümü, hesaplamadaki tekrarlama nedeniyle tasarımla üsteldir:
Kökte hesaplıyorsunuz:
F (n), F (n-1) ve F (n-2) 'ye bağlıdır
F (n-1) tekrar F (n-2) ve F (n-3) 'e bağlıdır
F (n-2) tekrar F (n-3) ve F (n-4) değerlerine bağlıdır
hesaplamada çok fazla veri harcayan her düzeyde 2 özyinelemeli çağrı yapıyorsunuz, zaman işlevi şu şekilde görünecektir:
T (n) = T (n-1) + T (n-2) + C, C sabiti ile
T (n-1) = T (n-2) + T (n-3)> T (n-2) sonra
T (n)> 2 * T (n-2)
...
T (n)> 2 ^ (n / 2) * T (1) = O (2 ^ (n / 2))
Bu sadece analizin amacı için yeterli olması gereken bir alt sınırdır, ancak gerçek zamanlı fonksiyon aynı Fibonacci formülü tarafından sabit bir faktördür ve kapalı formun altın oranın üstel olduğu bilinmektedir.
Ayrıca, aşağıdaki gibi dinamik programlama kullanarak optimize edilmiş Fibonacci sürümlerini bulabilirsiniz:
static int fib(int n)
{
/* memory */
int f[] = new int[n+1];
int i;
/* Init */
f[0] = 0;
f[1] = 1;
/* Fill */
for (i = 2; i <= n; i++)
{
f[i] = f[i-1] + f[i-2];
}
return f[n];
}
Bu optimize edilmiş ve sadece n adım yapmak ama aynı zamanda üstel.
Maliyet fonksiyonları, Giriş boyutundan sorunu çözmek için adım sayısına kadar tanımlanır. Fibonacci'nin dinamik sürümünü ( tabloyu hesaplamak için n adım) veya bir sayının asal olup olmadığını bilmek için en kolay algoritmayı (sayının geçerli bölenlerini analiz etmek için sqrt (n)) gördüğünüzde. bu algoritmaların O (n) veya O (sqrt (n)) olduğunu düşünebilirsiniz, ancak bu aşağıdaki nedenden dolayı doğru değildir: Algoritmanıza giriş bir sayıdır: n , bir tam sayı n, bir log 2 (n) daha sonra değişken bir değişiklik yaparak
m = log2(n) // your real input size
giriş boyutunun bir fonksiyonu olarak adım sayısını öğrenelim
m = log2(n)
2^m = 2^log2(n) = n
giriş boyutunun bir fonksiyonu olarak algoritmanızın maliyeti:
T(m) = n steps = 2^m steps
ve bu yüzden maliyet üsteldir.