So the following is not optimized fibonacci function:
sub fib {
my ( $n ) = @_;
return 1 if( $n == 1 || $n == 2 );
return fib( $n - 1 ) + fib( $n - 2 );
}
I actually printed the number of times fib(3)
was called when we try to find the fibonacci of 20.
It is 2584. fib(2)
is called 4181.
As far as I know this algorithm shows exponential behavior.
My question is how could I calculate that fib(3)
would have been called 2584 times without actually keeping a counter in the code and printing the function calls? How is the exponential part calculated?
fib(i)
gets called directly only fromfib(i+1)
andfib(i+2)
, and once for each call.Thus
calls(i)
(number of calls offib(i)
) equalscalls(i+1) + calls(i+2)
So if we start at
m
and we try to calculatecalls(n)
, we have the following:This is just the Fibonacci sequence where we want to calculate the
m-n+1
-th number(to see why it's exactly
m-n+1
, consider whenn = m
, which should befib(1)
).We can use an optimised Fibonacci function here to efficiently (in linear time) calculate
fib(m-n+1)
, which will be the number of calls offib(n)
there will be in the unoptimised version.For your example,
fib(3)
gets called2584
times if you callfib(20)
.fib(20-3+1) = fib(18) = 2584
.Note:
calls(1) = calls(3)
(sincefib(2)
doesn't callfib(1)
), so that's a special case.