tags:

views:

521

answers:

6

Consider the following code snippet:

int fib(int N)
{
   if(N<2) return 1;
   return (fib(N-1) + fib(N-2));
}

Given that fib is called from main with N as 10,35,67,... (say), how many total calls are made to fib?

Is there any relation for this problem?

PS: This is a theoretical question and not supposed to be executed.

EDIT:

I am aware of other methods for the faster computation of Fibonacci series.

I want a solution for computing number of times fib is invoked for fib(40),fib(50) ,.. without the aid of compiler and in exam condition where you are supposed to answer 40 question similar to this one in a stipulated of time ( about 30 mints).

Thanks,

+3  A: 

0 as find_fib will never be called.

dalle
Sorry,It was a typo.
nthrgeek
+6  A: 

Let f(n) be the number of calls made to calculate fib(n).

  • If n < 2 then f(n) = 1.
  • Otherwise, f(n) = 1 + f(n - 1) + f(n - 2).

So, f is at least O(fib(n)). In fact, f(n) is 2 * fib(n) - 1. We show this by induction:

  • Base cases (n < 2, that is, n = 0 or n = 1):
    • f(n) = 1 = 2 * 1 - 1 = 2 * fib(n) - 1.
  • Induction step (n >= 2):
    • f(n + 1) = f(n) + f(n - 1) + 1
    • f(n + 1) = 2 * fib(n) - 1 + 2 * fib(n - 1) - 1 + 1
    • f(n + 1) = 2 * fib(n + 1) - 1

There exist efficient ways to calculate any Fibonacci term. Thus the same holds for f(n).

Stephan202
You show too much, sir.
outis
Thanks,I know this Recurrence relation.I was inquisitive to solve it by some direct formula.In the paper it is given to find the value for Fib(40) which is actually 331160281.I wonder how will any solve it in about 30 secs (without compiler of-course)
nthrgeek
@nthrgeek: I hope that my update of the answer helps you answer that question.
Stephan202
@Stephan202:Thanks,as I stated already I am aware of the faster algorithms for generating nth Fibonacci numbers.Your induction steps are correct but still not possible for computing f(40) manually within very short time.
nthrgeek
@nthrgeek: you're not supposed to apply the induction, but instead go with the formula *f(n) = 2 \* fib(n) - 1*. Since, as you state, you *do* have a fast algorithm to calculate Fibonacci numbers, this solves the problem. Right?
Stephan202
+4  A: 

Is there any relation for this problem ?

There is a close-form equation for the nth fibonacci number: http://en.wikipedia.org/wiki/Fibonacci%5Fnumber#Closed%5Fform%5Fexpression

In the pseudocode you posted, the number of calls satisfies the recurrence relation

x(n) = x(n-1) + x(n-2) +1   # for n>=2
x(1) = 1
x(0) = 1

This is almost same as the Fibonacci recurrence relation. Proof by induction can show that the number of calls to fib made by fib(n) is equal to 2*fib(n)-1, for n>=0.

Of course, the calculation can be sped up by using the closed form expression, or by adding code to memorize previously computed values.

unutbu
Shouldn't that be `x(n) = x(n-1) + x(n-2) + 1`?
Stephan202
no. seq = 1,1,2,3,5,8,13,... there is no +1 necessary.
David Lively
@David: we're talking about the number of *function calls*, not the actual Fibonacci sequence. E.g. `fib(0)` and `fib(1)` require 1 call, but `fib(2)` requires 3 calls (not 2!): the call itself, and two recursive calls.
Stephan202
Stephan202, thanks for pointing that out. I've corrected my answer.
unutbu
@~unutbu: did you actually perform the proof by induction? I think that formula is incorrect (see my answer).
Stephan202
Thanks again Stephan202. That was sloppy of me. I would up-vote your answer some more if I could.
unutbu
+1  A: 

This is a classic problem for solving with Recurrence Relations.

Specifically, the fibonacci problem has the following parameters:

f(0) = 1
f(1) = 1
f(n) = f(n-1) + f(n-2)

Once you master solving recurrences, you'll have no problem reaching the solution (which, incidently, is exactly the same as fib(n)).

Yuval A
Explain the -1.
Yuval A
+3  A: 

As mentioned above, you need to solve the following recurring equation: K(n)=K(n-1)+K(n-2)+1

Let's write it for n-1: K(n-1)=K(n-2)+K(n-3)+1

Now, subtract the second one from the first one: K(n)-K(n-1) = K(n-1) - K(n-3),

or

K(n) - 2*K(n-1) + K(n-3) = 0.

The respective characteristic equation will be: x^3 - 2*x^2 + 1 = 0.

It has the following roots: 1, (1+sqrt(5))/2, (1-sqrt(5))/2

Thus for any real A,B,C the following function K(n) = A*(1)^n + B*((1+sqrt(5))/2)^n + C*((1-sqrt(5))/2)^n

will be a solution for your equation.

To find A,B,C you need to define several initial values K(0), K(1), K(2) and solve the system of equations.

I liked your approach.
nthrgeek
+1  A: 

Interesting question, I can't give you a formula, but I wrote a Ruby program to do it, it works on numbers I figured out on paper, and it should work for any.

#!/usr/bin/ruby
#find out how many times fib() would need to be called

def howmany(n)
    a = [ ]
    a.push n-1
    a.push n-2
    while a.select{|n| n > 2}.length > 0
        a.map! do |n|
            n > 2 ? [n-1,n-2] : n
        end
        a.flatten!
    end
    a.length
end

.

>> howmany(10)
=> 55

It's slow.. I'm figuring out 35 right now, I'll edit when it finishes.

Edit:

>> howmany(35)
=> 9227465
Jeffrey Aylesworth