Can memoization be used with an iterative solution in dynamic programming? - recursion

For example, the Fibonacci sequence can be solved with memoization when using recursion. But can solving Fibonacci iteratively (stack + while loop) also take advantage of memoization?

Of course ... start at the base case F(0) and F(1), and compute values. Keep them all in an array, indexed by the functional subscript. When you get an input argument greater than your current array extent, compute more values. When you get one within the current bounds, simply return that value from the array.

Related

Standard ML : Calculating the average of a given set

I recently had the assignment to calculate the average of a set (given by input) in Standard ML.
The idea is to have a function like below in which you input a list of real numbers and receive the average of those numbers (also a real), such that the terminal gives you this as a return answer when you input the function:
average = fn : real list -> real
We discussed this in a tutorial as well but I wanted to know if there was some sort of trick when creating such functions in Standard ML.
Thanks in advance!
Sum the numbers and divide by the length. A simple recursive sum is typically one of the first examples that you would see in any SML tutorial. You would need to have the empty list basis case of sum evaluate to 0.0 rather than 0 to make sure that the return type is real. Once you define a sum function then you can define average in 1 line using sum and the built in length function. A subtlty is that SML doesn't allow a real to be divided by an int. You could use the conversion function Real.fromInt on the length before dividing the sum by it. There is some inefficiency in passing over the same list twice, once to sum it and once to calculate its length, but there is little reason to worry about such things when you are first learning the language.
On Edit: Since you have found a natural solution and shared it in the comments, here is a more idiomatic version which computes the average in one pass over the list:
fun average nums =
let
fun av (s,n,[]) = s/Real.fromInt(n)
| av (s,n,x::xs) = av (s+x,n+1,xs)
in
av (0.0, 0, nums)
end;
It works by defining a helper function which does the heavy lifting. These are used extensively in functional programming. In the absence of mutable state, a common trick is to explicitly pass as parameters quantities which would be successively modified by a corresponding loop in an imperative language. Such parameters are often called accumulators since they typically accumulate growing lists, running sums, running products, etc. Here s and n are the accumulators, with s the sum of the elements and n the length of the list. In the basis case of (s,n,[]) there is nothing more to accumulate so the final answer is returned. In the non-basis case, (s,n,x::xs), s and n are modified appropriately and passed to the helper function along with the tail of the list. The definition of av is tail-recursive hence will run with the speed of a loop without growing the stack. The only thing that the overall average function needs to do is to invoke the helper function with the appropriate initial values. The let ... helper def ... in ... helper called with start-up values ...end is a common idiom used to prevent the top-level of a program from being cluttered with helper functions.
Since only non-empty lists can have averages, an alternative on John Coleman's answer is:
fun average [] = NONE
| average nums =
let
fun av (s,n,[]) = s/Real.fromInt(n)
| av (s,n,x::xs) = av (s+x,n+1,xs)
in
SOME (av (0.0, 0, nums))
end;
Whether a function for calculating averages should take non-empty lists into account depends on whether you intend to export it or only use it within a scope in which you guarantee elsewhere that the input list is non-empty.

Does Memoization improve running time of this algorithm?

"Given an array of n integers, return an array of their factorials."
Instead of the straight forward way of iterating through the array and finding factorial for each, I was thinking of a memoized approach, where I store previously calculated factorials and use them in subsequent ones.
For example: 7! can be calculated much fasted if the result 6! is stored somewhere. However, I noticed the run time of both algorithms is still O(n). (I might be wrong) Does that imply that we're not speeding up the process here? If so, does that mean that memoization is not useful in problems with non-tree recursion? (In Fibonacci, we effectively prune the recursion tree by memoizing the previously found values, in the case of factorial, we don't really have the tree, more like a recursion ladder)
Any comments appreciated.
However, I noticed the run time of both algorithms is still O(n).
O-Notation is hiding the most important characteristic here. It only considers the length of the array and not the size of the numbers which is much much more important when dealing with factorials.
You should implement memoization with a hashtable. If you do then you will get O(1) for each entry asymptotically.
In the case without memoization, the time complexity should be O(n^2) since you would need (i-1) multiplications to calculate factorial(i) without memoization.

New to OCaml: How would I go about implementing Gaussian Elimination?

I'm new to OCaml, and I'd like to implement Gaussian Elimination as an exercise. I can easily do it with a stateful algorithm, meaning keep a matrix in memory and recursively operating on it by passing around a reference to it.
This statefulness, however, smacks of imperative programming. I know there are capabilities in OCaml to do this, but I'd like to ask if there is some clever functional way I haven't thought of first.
OCaml arrays are mutable, and it's hard to avoid treating them just like arrays in an imperative language.
Haskell has immutable arrays, but from my (limited) experience with Haskell, you end up switching to monadic, mutable arrays in most cases. Immutable arrays are probably amazing for certain specific purposes. I've always imagined you could write a beautiful implementation of dynamic programming in Haskell, where the dependencies among array entries are defined entirely by the expressions in them. The key is that you really only need to specify the contents of each array entry one time. I don't think Gaussian elimination follows this pattern, and so it seems it might not be a good fit for immutable arrays. It would be interesting to see how it works out, however.
You can use a Map to emulate a matrix. The key would be a pair of integers referencing the row and column. You'll want to use your own get x y function to ensure x < n and y < n though, instead of accessing the Map directly. (edit) You can use the compare function in Pervasives directly.
module OrderedPairs = struct
type t = int * int
let compare = Pervasives.compare
end
module Pairs = Map.Make (OrderedPairs)
let get_ n set x y =
assert( x < n && y < n );
Pairs.find (x,y) set
let set_ n set x y v =
assert( x < n && y < n );
Pairs.add (x,y) set v
Actually, having a general set of functions (get x y and set x y at a minimum), without specifying the implementation, would be an even better option. The functions then can be passed to the function, or be implemented in a module through a functor (a better solution, but having a set of functions just doing what you need would be a first step since you're new to OCaml). In this way you can use a Map, Array, Hashtbl, or a set of functions to access a file on the hard-drive to implement the matrix if you wanted. This is the really important aspect of functional programming; that you trust the interface over exploiting the side-effects, and not worry about the underlying implementation --since it's presumed to be pure.
The answers so far are using/emulating mutable data-types, but what does a functional approach look like?
To see, let's decompose the problem into some functional components:
Gaussian elimination involves a sequence of row operations, so it is useful first to define a function taking 2 rows and scaling factors, and returning the resultant row operation result.
The row operations we want should eliminate a variable (column) from a particular row, so lets define a function which takes a pair of rows and a column index and uses the previously defined row operation to return the modified row with that column entry zero.
Then we define two functions, one to convert a matrix into triangular form, and another to back-substitute a triangular matrix to the diagonal form (using the previously defined functions) by eliminating each column in turn. We could iterate or recurse over the columns, and the matrix could be defined as a list, vector or array of lists, vectors or arrays. The input is not changed, but a modified matrix is returned, so we can finally do:
let out_matrix = to_diagonal (to_triangular in_matrix);
What makes it functional is not whether the data-types (array or list) are mutable, but how they they are used. This approach may not be particularly 'clever' or be the most efficient way to do Gaussian eliminations in OCaml, but using pure functions lets you express the algorithm cleanly.

Difference between recursion and iteration

What is the difference? Are these the same? If not, can someone please give me an example?
MW:
Iteration - 1 : the action or a process of iterating or repeating: as a : a procedure in which repetition of a sequence of operations yields results successively closer to a desired result b : the repetition of a sequence of computer instructions a specified number of times or until a condition is met
Recursion - 3 : a computer programming technique involving the use of a procedure, subroutine, function, or algorithm that calls itself one or more times until a specified condition is met at which time the rest of each repetition is processed from the last one called to the first
We can distinguish (as is done in SICP) recursive and iterative procedures from recursive and iterative processes. The former are as your definition describes, where recursion is basically the same as mathematical recursion: a recursive procedure is defined in terms of itself. An iterative procedure repeats a block of code with a loop statement. A recursive process, however, is one that takes non-constant (e.g. O(n) or O(lg(n)) space) to execute, while an iterative process takes O(1) (constant) space.
For mathematical examples, the Fibonacci numbers are defined recursively:
Sigma notation is analogous to iteration:
as is Pi notation. Similar to how some (mathematical) recursive formulae can be rewritten as iterative ones, some (but not all) recursive processes have iterative equivalents. All recursive procedures can be transformed into iterative ones by keeping track of partial results in your own data structure, rather than using the function call stack.
[Hurry and trump this!]
One form can be converted to the other, with one notable restriction: many "popular" languages (C/Java/normal Python) do not support TCO/TCE (tail-call-optimization/tail-call-elimination) and thus using recursion will 'add extra data to the stack' each time a method calls itself recursively.
So in C and Java, iteration is idiomatic, whereas in Scheme or Haskell, recursion is idiomatic.
As per the definitions you mentioned, these 2 are very different. In iteration, there is no self-calling, but in recursion, a function calls itself
For example. Iterative algorithm for factorial calculation
fact=1
For count=1 to n
fact=fact*count
end for
And the recursive version
function factorial(n)
if (n==1) return 1
else
n=n*factorial(n-1)
end if
end function
Generally
Recursive code is more succinct but uses a larger amount of memory. Sometimes recursion can be converted to iterations using dynamic programming.
Here's a Lisp function for finding the length of a list. It is recursive:
(defun recursive-list-length (L)
"A recursive implementation of list-length."
(if (null L)
0
(1+ (recursive-list-length (rest L)))))
It reads "the length of a list is either 0 if that list is empty, or 1 plus the length of the sub-list starting with the second element).
And this is an implementation of strlen - the C function finding the length of a nul-terminated char* string. It is iterative:
size_t strlen(const char *s)
{
size_t n;
n = 0;
while (*s++)
n++;
return(n);
}
You goal is to repeat some operation. Using iteration, you employ an explicit loop (like the while loop in the strlen code). Using recursion, your function calls itself with (usually) a smaller argument, and so on until a boundary condition (null L in the code above) is met. This also repeats the operation, but without an explicit loop.
Recursion:
Eg: Take fibonacci series for example. to get any fibonacci number we have to know the previous one. So u will berform the operation (same one) on every number lesser than the given and each of this inturn calling the same method.
fib(5) = Fib (4) + 5
fib(4) = Fib (3) + 4
.
.
i.e reusing the method fib
Iteration is looping like you add 1+1+1+1+1(iteratively adding) to get 5 or 3*3*3*3*3 (iteratively multiplying)to get 3^5.
For a good example of the above, consider recursive v. iterative procedures for depth-first search. It can be done using language features via recursive function calls, or in an iterative loop using a stack, but the process is inherently recursive.
For difference between recursive vs non-recursive;
recursive implementations are a bit easier to verify for correctness; non-
recursive implementations are a bit more efficient.
Algorithms (4th Edition)

Summation notation in Haskell

On the Wikipedia page about summation it says that the equivalent operation in Haskell is to use foldl. My question is: Is there any reason why it says to use this instead of sum? Is one more 'purist' than the other, or is there no real difference?
foldl is a general tail-recursive reduce function. Recursion is the usual way of thinking about manipulating lists of items in a functional programming languages, and provides an alternative to loop iteration that is often much more elegant. In the case of a reduce function like fold, the tail-recursive implementation is very efficient. As others have explained, sum is then just a convenient mnemonic for foldl (+) 0 l.
Presumably its use on the wikipedia page is to illustrate the general principle of summation through tail-recursion. But since the Haskell Prelude library contains sum, which is shorter and more obvious to understand, you should use that in your code.
Here's a nice discussion of Haskell's fold functions with simple examples that's well worth reading.
I don't see where it says anything about Haskell or foldl on that Wikipedia page, but sum in Haskell is just a more specific case of foldl. It can be implemented like this, for example:
sum l = foldl (+) 0 l
Which can be reduced to:
sum = foldl (+) 0
One thing to note is that sum may be lazier than you would want, so consider using foldl'.
As stated by the others, there's no difference. However, a sum-call is easier to read than a fold-call, so I'd go for sum if you need summation.
There is no difference. That page is simply saying that sum is implemented using foldl. Just use sum whenever you need to calculate the sum of a list of numbers.
The concept of summation can be extended to non-numeric types: all you need is something equivalent to a (+) operation and a zero value. In other words, you need a monoid. This leads to the Haskell function "mconcat", which returns the sum of a list of values of a monoid type. The default "mconcat" of course is defined in terms of "mappend" which is the plus operation.

Resources