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
mand 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 called2584times 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.