Algorithms and OOD (CSC 207 2013F) : EBoards

CSC207.01 2013F, Class 52: Dynamic Programming


Overview

Preliminaries

Admin

Questions on the Homework

Fibonacci

The Fibonacci function:

Code?

public static int fib(int n) {
    if ((n == 0) || (n == 1)) {
        return 1;
    } else {
        return fib(n-1) + fib(n-2);
    } // else
} // fib(int)

What are the problems with this solution?

How inefficient?

$ java Fib 5
fib(5) = 8
   took 15 calls.
$ java Fib 8
fib(8) = 34
   took 67 calls.
$ java Fib 9
fib(9) = 55
   took 109 calls.
$ java Fib 20
fib(20) = 10946
   took 21891 calls.

Problem: Lots of repeated work

fib(16) = fib(15) + fib(14)
        = fib(14) + fib(13) + fib(14)
        = fib(13) + fib(12) + fib(13) + fib(14)

Solution 1: Change the formula

fib(n) = 2*fib(n-2) + fib(n-3)
fib(16) = 2*fib(14) + fib(13)
        = 2*(2*fib(12) + fib(11)) + fib(13)
        = 2*(2*fib(12) + fib(11)) + 2*fib(11) + fib(10)

Whoops! Still likely to be slow.

Solution 2: Remember our old results

// FIB[n] is -1 if we haven't computed it yet, and something else if we
// have computed it.
private static int[] FIB[?]= { 1, 1, -1, -1, -1 .... }
public static int fib(int n) {
    if (FIB[n] != -1) {
       return FIB[n];
    } else
       FIB[n] = fib(n-1) + fib(n-2);
       return FIB[n];
    }
} // fib(int)

Hand waving argument: "This is now O(n)"

Solution 3: Why do we like tail recursion? Because we avoid the stack. So, let's do it by hand: Write it iteratively from left to right.

public static int fib(int n) {
    int values[] = new int[n+1];
    values[0] = 1;
    values[1] = 1;
    for (i = 2; i <= n; i++) {
       values[i] = values[i-1] + values[i-2];
    }
    return values[n];
} // fib(n)

Solution 4: Drop the array

public static int fib(int n) {
    int prev = 1;
    int current = 1;
    int next;
    for (i = 2; i <= n; i++) {
        next = prev+current;
        prev = current;
        current = next;
    }
    return current;
} // fib(n)

Generalizing the Idea

The Stamps Problem

Code

 public static int smallest(n) {  
    if (n == 0)
        return 0;
    else {
        return 1 + "the min of smallest[n-value], for all values"
    }

A better solution:

Edit Distance in Strings

Terminology

Copyright (c) 2013 Samuel A. Rebelsky.

Creative Commons License

This work is licensed under a Creative Commons Attribution 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/ or send a letter to Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA.