Comp 210 Lab 10

Review, and Memoization

Review

Some topics covered since last exam: Some study questions:

Memoization (optional)

The following won't be on any tests or homework, but is a nice technique to be aware of. Recall our original implementation of fib:
(define fib
  (lambda (n)
    (if (< n 2)
        1
        (+ (fib (- n 1)) (fib (- n 2))))))
The problem with this implementation is that it takes a long, long time for even moderately small values of n. We can observe this with a slightly more automated version of hw08's ``instrument'':
(define counter 0)
(define instrumentize
  (lambda (f)
    (lambda (n)
       (begin (set! counter (add1 counter))
              (f n)))))
(define call
  (lambda (f n)
     (begin (set! counter 0)
            (f n)
            counter)))

(set! fib (instrumentize fib))
(call fib 5)
(call fib 20)
(call fib 30)
Why does (fib 5) more than around five recursive calls? Try evaluating (fib 5) by hand, and you'll see there's a lot of repeated work being done.

We saw one solution to this predicament in the homework, using two accumulators. This worked fine for fib, but not all functions can be patched in that same way. (Besides, calling (fib 30) twice in a row takes twice as long as it would if computers were smart.) What is a general approach we can take?

Yes, memoization! MemoiWhation, you ask? The idea is simple: every time you compute a result, write down the answer. Later, when you are asked to compute something, before doing the "real" work, first check whether you've solved this exact problem before.

Association Lists

All we need is a way to store questions and their previously-computed answers. What is an appropriate type of data to store this information?

A common idea in Scheme programs is that of an association list, which is just a list of ``key/entry'' pairs. For example, a program might keep a list which associates month-symbols with their numeric counterparts:

(('jan 1) ('Jan 1) ('feb 2) ('Feb 2) ... )
Write a function assq which takes a key k and an association list a, and returns a key/entry pair in a whose key is k, or #f if there isn't such a pair. (The q in the name means that keys are compared using eq?.)

Now, back to memoization: write a function fib-memo which has a persistent local variable prev-results, an association list of argument/result pairs.

If you instrumentize this version of fib, how many calls are made for (call fib-memo 20)? How about for (call fib-memo 19)?


Back to Comp 210 Home