简体   繁体   中英

Python recursive fibonacci function doesn't process large values

I wrote a simple recursive fibonacci function:

def recursive_fibonacci(n):
    if n == 0:
        return 0
    if n == 1:
        return 1
    if n > 1:
        return recursive_fibonacci(n-1) + recursive_fibonacci(n-2)

and tried to run a large value in it:

print(recursive_fibonacci(100))

Nothing came out of the console and the fan on my mac started spinning violently

Can someone explain what is going on. What is happening internally in the stack frame?

A call to your routine with argument N makes on the order of phi^N total calls. For N=100, this is on the order of 10^20 calls. Don't wait for the output at N=100; you won't live that long.

However, you can memoize the function. Look up the term; there's also a Python package to do that for you automatically. The idea is to store the result of each value call; for any N , you compute f(N) only once; thereafter, you just look up the value in a table.

Building on Prune's nice answer you can easily memoize the function calls so that each value of n is only computed once by passing a mutable argument (a dict) in the function definition and storing already computed values in the dict:

def recursive_fibonacci(n, mem={}):
    if n == 0 or n == 1:
        return n
    else:
        if n-1 not in mem:
            mem[n-1] = recursive_fibonacci(n-1)
        if n-2 not in mem:
            mem[n-2] = recursive_fibonacci(n-2)
        return mem[n-1] + mem[n-2]


print(recursive_fibonacci(100))
# 354224848179261915075

Already computed values are looked up the dict and would not require further recursive calls.

The primitive recursive solution takes a lot of time. The reason for this is that for each number calculated, it needs to calculate all the previous numbers more than once. Take a look at the following image.

Tree representing fibonacci calculation

It represents calculating Fibonacci(5) with your function. As you can see, it computes the value of Fibonacci(2) three times, and the value of Fibonacci(1) five times. That just gets worse and worse the higher the number you want to compute.

What makes it even worse is that with each fibonacci number you calculate in your list, you don't use the previous numbers you have knowledge of to speed up the computation – you compute each number "from scratch." The easiest way is to just create a list of fibonacci numbers up to the number you want. If you do that, you build "from the bottom up" or so to speak, and you can reuse previous numbers to create the next one. If you have a list of the fibonacci numbers [0, 1, 1, 2, 3], you can use the last two numbers in that list to create the next number and return the last number of the listwhich is your final answer.

def fib_to(n):
    fibs = [0, 1]
    for i in range(2, n+1):
        fibs.append(fibs[-1] + fibs[-2])
    return fibs[-1]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM