问题
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