Dynamic Programming - Fibonacci

断了今生、忘了曾经 提交于 2021-02-19 04:59:05

问题


So basically, I am a learning programmer and this week I was introduced to dynamic programming. Our task was to find the Fibonacci sequence using dynamic programming. This pseudo code was supplied which would obviously be in a function:

init table to 0s
if n ≤ 1
   return n
else
   if table[n-1] = 0
      table[n-1] = dpFib(n-1)
   if table[n-2] = 0
      table[n-2] = dpFib(n-2)
   table[n] = table[n-1] + table[n-2]
return table[n]

The majority of this was simple to change to code but I'm not sure how to initialise the table of 0s. I know it should be a list but I'm not sure if it should be inside the function or outside or how many zeros I should initialise it with. This is what I wrote, nothing complicated:

def dynamicFibo(n):
   # initialise table of 0s
   #base case
   if n <= 1:
       return n
   #recursive case
   else:
       if table[n-1] ==  0:
           table[n-1] = dynamicFibo(n-1)

       if table[n-2] ==  0:
           table[n-2] = dynamicFibo(n-2)

       table[n] = table[n-2] + table[n-2]
   return table[n]

I would be thankful if someone could show me the way to go with this. Also, in general I struggle to understand the basis of dynamic programming so if there are any good resources you could suggest I would be delighted, or even if you could give a good explanation.


回答1:


you can initialize your table with:

table = [0 for _ in range(n+1)]

since you want to have at least n+1 items in your table to allow to access table[n] (remember that lists are zero-indexed so the nth item is accessed with (n-1))

However, you would want to ensure that you are not creating new lists every time since that would defeat the purpose of dynamic programming. So you can have table as what I call an "invisible" parameter, ie a parameter with a default parameter that is used at every recursive call. Your function would then look like this:

>>> def dynamicFibo(n,table = []):
   while len(table) < n+1: table.append(0) #this does the same thing except it doesn't change the reference to `table`
   #base case
   if n <= 1:
       return n
   #recursive case
   else:
       if table[n-1] ==  0:
           table[n-1] = dynamicFibo(n-1)

       if table[n-2] ==  0:
           table[n-2] = dynamicFibo(n-2)

       table[n] = table[n-2] + table[n-1]
   return table[n]
>>> dynamicFibo(12)
144
>>> dynamicFibo(300)
222232244629420445529739893461909967206666939096499764990979600

reference

as you can see, I used a while loop instead of a list comprehension. This is essentially the same thing except we cannot be changing the reference of table or else the recursive calls will create a new table each time unless you pass it in as a paramater. This also allows the table to expand as necessary if you call dynamicFibo more than once with increasing numbers, but maintain all the old numbers. This is clearly seen by adding a print(table) line in the function:

>>> dynamicFibo(12)
[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 1, 2, 3, 5, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 1, 2, 3, 5, 8, 0, 0, 0, 0, 0, 0]
[0, 1, 1, 2, 3, 5, 8, 13, 0, 0, 0, 0, 0]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 0, 0, 0, 0]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 0, 0, 0]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 0, 0]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 0]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
144
>>> dynamicFibo(14)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 0]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]
377

I added the print(table) right before return table[n]




回答2:


There is a simple solution that worked for every one...

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


来源:https://stackoverflow.com/questions/34055512/dynamic-programming-fibonacci

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!