Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Parallel

Dynamic Programming In Action


We can achieve nearly the same result with a technique called "memoization." We use the same recursive approach that we used for rcomplex-multiplications to compute the minimum, but instead of blindly recomputing Mi,j, we use an array to store already computed values. To do this task, we modify rcomplex-multiplications by creating a temporary array (Listing Seven). Before considering any computations, the array is checked to see whether the result already exists. If so, that value is returned. If not, it is computed and stored in the array. We use the fact that the array can hold elements of any type to use nil as the marker for an uncomputed value.

(defun rcomplex-multiplications-memo (p)
  (let* ((n (- (length p) 1))
       (m (make-array (list n n) :initial-element nil)))
  (labels ((rmin (start end)
       (cond ((= start end) 0)
           ((not (null (aref m start end)))
                       (aref m start end))
      ((= (+ start 1) end)
       (setf (aref m start end)
             (* (aref p start)
                (aref p (1+ start))
                (aref p (1+ end)))))
       (t (let ((min most-positive-fixnum))
           (loop for 1 from start to (1- end) do
               (let ((v (+ (rmin start 1)
                           (rmin (1+ 1) end)
                           (* (aref p start)
                              (aref p (1+ 1))
                              (aref p (1+ end))))))
                (when + v min) (setq min v;)))
          (setf (aref m start end) min))))))
   (rmin 0 (- (length p) 2;))))
Listing Seven: Temporary array.

When we compare this function to the dynamic-programming function that also computes the cut points, we see that the memoized recursive one is about 11% slower so our complex algorithm is slightly better. The difference comes from the slight extra overhead for recursion vs. iteration and the more complex array management -- testing for nil.

What are the criteria for applying dynamic programming? First, solving the problem in a divide-and-conquer or recursive manner must involve solving the same subproblems over and over. Computing the factorial requires solving independent subproblems, while computing the optimum matrix-multiplication order requires solving the same subproblem many times.

Second, the structure of a solution must be derived from optimal solutions to subproblems. This criterion is not so obvious. The optimum parenthesization of the matrix product A0...An is based on a cut point k with which we multiply the prefix chain A0...Ak using some parenthesization by the multiplication of the suffix chain Ak+1...An by some other parenthesization. The question is whether the parenthesizations of the prefix and suffix that lead to the optimum parenthesization is necessarily the optimal parenthesizations of the prefix and suffix. Suppose that the optimum full product does not use the optimal parenthesization of the prefix. If we replace that parenthesization by the optimum one, the full product will use fewer scalar multiplications, which is a contradiction. Therefore, the parenthesization of the prefix that gives rise to the optimum product must also be optimal. The same reasoning applies to the suffix. Therefore, the structure of the full solution is derived from optimal solutions of the subproblems.

It's important to know techniques like this one, or to know what sorts of problems can be attacked by what means. You'll be a better programmer this way.


(Adapted from Introduction to Algorithms by Thomas H. Cormen, Charles E. Leiserson, and Ronald L. Rivest, McGraw-Hill, 1990. Courtesy AI Expert.)


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.