Earlier quoted context omitted.
In "traditional" recursion, each recursive call is pushed onto the function call stack. This means that your recursive solution will eventually run out of memory when the number of recursive calls is more than what the function call stack can handle. e.g., consider the following recursive solution for calculating the sum of all positive integers up to a given `n`: fn sum(n): if n == 0: return 0 else: return n + sum(n…
Thanks for the great explanation of tail recursion. But I still don't see how tail recursion implements memoisation? One might even argue that tail recursion is the opposite of memoisation; while tail recursion saves memory because it eliminates the need to remember previous results of function calls, memoisation on the other hand uses extra memory to save results of earlier function calls.
Dynamic Progamming: First Principles
71–80 of 102 posts
Re: Dynamic Progamming: First Principles
#72Why use monospace font?????
Re: Dynamic Progamming: First Principles
#73Earlier quoted context omitted.
Obscure words are very well suited to esoteric subject matter where precision is needed. A particular brand of function optimization is exactly that.
What precise meaning does "memorize" denote that "memorize" wouldn't? Sometimes jargon is just jargon.
So if you see the word, you instantly know that this is the context. You wouldn't know that if you see "memorization".
Re: Dynamic Progamming: First Principles
#74Earlier quoted context omitted.
Honestly though, we should just switch to using "memorization". It's a less obscure word that communicates the intended meaning better, IMHO.
Obscure words are very well suited to esoteric subject matter where precision is needed. A particular brand of function optimization is exactly that.
Re: Dynamic Progamming: First Principles
#75Re: Dynamic Progamming: First Principles
#76Earlier quoted context omitted.
In "traditional" recursion, each recursive call is pushed onto the function call stack. This means that your recursive solution will eventually run out of memory when the number of recursive calls is more than what the function call stack can handle. e.g., consider the following recursive solution for calculating the sum of all positive integers up to a given `n`: fn sum(n): if n == 0: return 0 else: return n + sum(n…
Thanks for the great explanation of tail recursion. But I still don't see how tail recursion implements memoisation? One might even argue that tail recursion is the opposite of memoisation; while tail recursion saves memory because it eliminates the need to remember previous results of function calls, memoisation on the other hand uses extra memory to save results of earlier function calls.
The crux of the misunderstanding is here: [tail recursion] eliminates the need to remember previous results of function calls.
Emphasis: results. The thing is: tail call recursion essentially means "finish all intermediate computations and pass the results of these to the next function call".
In the non-tail call version, the sum function has no results until you hit the deepest level of recursion; it is the equivalent of writing the sum out in full, which causes all that extra overhead:
sum = n + (n-1) + (n-2) + ... + 0
You have to recurse until you reach n == 0, and only then does the whole sum "collapse".The `pre_sum + n` bit in the second example is what fixes this. All intermediate calculations are finished and then "stored" by passing them as arguments to recursive calls. This gives the functional equivalent of a for loop:
sum = 0
for i in n..0:
sum += i
This is why it can be considered memoization: each recursive call builds on the "stored" finished result of the previous call.Re: Dynamic Progamming: First Principles
#77Earlier quoted context omitted.
When I took Algorithms II in college at a top 10 CS program, our entire class involved ZERO coding or programming of any sort.
All our classes required delivering some kind of working code, either at the end of semester, or throughout it. It was also the class that introduced us to unit tests, by having the code delivered as C library, that the teacher would link against to run her tests.
Re: Dynamic Progamming: First Principles
#78Re: Dynamic Progamming: First Principles
#79Earlier quoted context omitted.
All our classes required delivering some kind of working code, either at the end of semester, or throughout it. It was also the class that introduced us to unit tests, by having the code delivered as C library, that the teacher would link against to run her tests.
They're now using Mooshak to upload and run the tests automatically. The algorithms class is now mostly taught in Java, though.
Re: Dynamic Progamming: First Principles
#80Earlier quoted context omitted.
Although there is a lot of merit in implementing an algorithm and not just writing pseudo code, doing it on paper has some advantages. - Its a lot quicker to sketch an algorithm on paper ( you can ignore some details which are either trivial, or irrelevant to the problem ) - At a certain level you are expected to be able to convert pseudo code into actual code - The most important part of an algorithm is knowing abou…
> you can ignore some details which are either trivial, or irrelevant to the problem The most important insight of the old saw that teaching someone builds your understanding, but being able to code it ensures you have actual, deep understanding is this: the details you ignore as "trivial" or "irrelevant to the problem" are quite likely the crucial details to understand it and make it work. You can't safely handwave…