I'm currently learning dynamic programming with Python to write a rather simple Branch & Bound algorithm. I found this video on Youtube with kind of good explanations in the first place. The examples there are written in JavaScript. Only few changes were necessary to make in run in Python also.
But when I came along to the part with "bestSum" (1:52:26 in video), as soon as I bring the memoization in there comes the problem:
My code doesn't seem to save correct keys with the values in the "memo" dictionary. In the forwarded parts of the videos it worked fine every time but in this case not.
What's the difference here? I tried putting the "memo" code snippet to different parts in the code section but nothing worked.
Here a working Python code with memoization for how to make out possibilities to add up a number from different other numbers:
def howSum(targetSum, numbers, memo={}):
# print("new howSum")
if targetSum in memo:
# print("memo returned")
return memo[targetSum]
if targetSum == 0:
return []
if targetSum < 0:
return 0
for num in numbers:
remainder = targetSum - num
remainderResult = howSum(remainder, numbers, memo)
if remainderResult != 0:
remainderResult.append(num)
memo[targetSum] = remainderResult
return remainderResult
memo[targetSum] = 0
return 0
print(howSum(7, [2, 3], memo={}))
print(howSum(7, [5, 3, 4, 7], memo={}))
print(howSum(7, [2, 4], memo={}))
print(howSum(8, [2, 3, 5], memo={}))
Correct result:
[3, 2, 2]
[4, 3]
0
[2, 2, 2, 2]
And the not working code for how to get the smallest amount of available numbers to add up for a target number.
def bestSum(targetSum, numbers, memo={}):
if targetSum in memo:
return memo[targetSum]
if targetSum == 0:
return []
if targetSum < 0:
return 0
shortestCombination = 0
for num in numbers:
remainder = targetSum - num
remainderCombination = bestSum(remainder, numbers, memo)
if remainderCombination != 0:
remainderCombination.append(num)
combination = remainderCombination
if shortestCombination == 0 or len(combination) < len(shortestCombination):
shortestCombination = combination
memo[targetSum] = shortestCombination
memo[targetSum] = shortestCombination
return shortestCombination
print(bestSum(7, [5, 4, 3, 7]))
print(bestSum(8, [2, 3, 5]))
print(bestSum(8, [1, 4, 5]))
Incorrect results:
[7]
[5, 3]
[5, 3]
To safe place here: if you print out the "memo" dictionary for the function
print(bestSum(8, [1, 4, 5]))
you will get
{..., 8: [4,1,4]}
Telling me the best/shortest possibility to add up 8 out of [1,4,5] is [4,1,4] instead of [4,4]. If I run the code without the memoization section if works absolutely correct, so it's something about the memoization (I guess).