# Dynamic Programming Demonstration Binomial Coefficients

Document Sample

```					                                   Dynamic Programming Demonstration: Binomial Coefficients

/**                                                                            return table[k];   // Save ONE cell from the garbage collector.
* Dynamic Programming Demonstration: Binomial Coefficients                 } // end binom()
*
* Algorithm taken from Brassard and Bratley, "Fundamentals of           /**
* Algorithmics" (1996), pp. 260-61.                                      * Minimal dynamic programming based on c(n,k) = perm(n,k)/perm(k,k):
*                                                                        * Generate c(n-k,0), c(n-k+1,1), c(n-k+2,2) up to c(n,k)
* Methods:                                                               *
*   binom():     dynamic programming implementation                      * "Binomial Coefficient Recursion: The Good, and The Bad and Ugly",
*   bad_news(): Pascal's triangle implementation                         * inroads (bulletin of the ACM SIG on Computer Science Education)
*   c():         Based on c(n,k) = perm(n,k)/perm(k,k)                   * Vol 33, No. 2 (June 2001), pp. 35-36.
*                                                                        */
* Author: Timothy Rolfe                                                    public static MyInt c(int n, int k)
*/                                                                         { long ans, ni, ki;

import java.io.*;                                                              ans = 1;                    // c(n-k, 0)
for ( ni = n-k+1, ki=1; ki<=k; ki++, ni++ )
public class Binom_DP                                                             ans = ( ans * ni ) / ki; // next c in the series
{                                                                              return new MyInt((int)ans);
/**                                                                         } // end c()
* Dynamic programming solution based on Pascal's Triangle
* Note: by computing the rows from right to left, each cell is          /**
* modified after its _second_ use in the formula, thus eliminating       * Recursive implementation of Pascal's Triangle --- BAD news
* the need for a separate vector to avoid side-effects.                  */
*/                                                                         public static MyInt bad_news(int n, int k)
public static MyInt binom(int n, int k)                                  { MyInt ans    = new MyInt(1);
{ MyInt[] table;     // One line from the table of coefficients             if ( k > 0 && k < n )
int     ni,       // Current value of "n" being computed                 { MyInt left = bad_news(n-1, k-1),
ki;       // Current value of "k" being computed                          right = bad_news(n-1, k);
ans.sum(left, right);
// Take advantage of the symmetry in Pascal's Triangle                      }
// This is not required for correctness, though.                            return ans;
// if ( (n - k < k) )                                                    } // end bad_news()
k = n - k;
//For convenience, let constructor failure for Scanner go to the JVM
// Table of partial results                                              public static void main ( String[] args ) throws Exception
table    = new MyInt[k+1];                                            { MyInt answer;
table[0] = new MyInt(1);                                                 int   n, k;
int   nLim = 20, kLim = (nLim+1)/2;
for ( ni = 1; ni <= n; ni++ )                                            java.util.Scanner console = new java.util.Scanner ( System.in );
{
// Growth phase: Add each new cell as the vectors grow                   System.out.println ("Illegal n,k pair exits look; e.g., n < 0\n");
if ( ni <= k )                                                        while (true) // will break with illegal k or n
{ table[ni] = new MyInt(1);                                           { System.out.print ("Value for n: ");
for ( ki = ni-1; ki > 0; ki-- )                                       n = console.nextInt();
table[ki].sum ( table[ki-1], table[ki] );                          if ( n < 0 ) break;
}                                                                        System.out.print ("Value for k: ");
else                                                                     k = console.nextInt();
// Stable phase: note that k <= n/2 from the symmetry correction            if ( k > n || k < 0 )
{ for ( ki = k; ki > 0; ki-- )                                              break;
table[ki].sum ( table[ki-1], table[ki] );                          answer = binom(n, k);
} // end if / else                                                       System.out.print (answer + "(binom) " + MyInt.nAdditions()
} // end for ( ni . . .                                                                        + " adds; ") ;

Printed 2010-Sep-05 at 20:44
+ " adds; ") ;                                      { return Integer.toString(value);     }
answer = c(n, k);                                                       } // end class MyInt
System.out.println( answer + "(c)");                                 } // end class Binom_DP
}                                                                       /* Result of a trial run:
console.nextLine();       // Set up for "Press ENTER...
Illegal n,k pair exits look; e.g., n < 0
System.out.println ("\nSpecimen table --- through n = " + nLim);
Value for n: 20
for ( n = 0; n <= nLim; n++ )                                           Value for k: 10
{ int lim = n > kLim ? kLim : n;                                        184756(binom) 145 adds; 184756(bad_news) 184755 adds; 184756(c)
Value for n: 22
for ( k = 0; k <= lim; k++ )                                         Value for k: 11
System.out.println();                                                Value for n: 24
}                                                                       Value for k: 12
console.nextLine();                                                     Value for n: 26
} // end main()                                                            Value for k: 13
static class MyInt implements Comparable                                   Value for n: 28
{                                                                          Value for k: 14
static int nAdd = 0;                                                    Value for n: 30
int value;                                                              Value for k: 15
MyInt()                                                                 Value for n: -1
{ set(0);    }
MyInt (int value)                                                       Specimen table --- through n = 20
{ set(value); }                                                              1
1      1
void set (int value)                                                         1      2     1
{ this.value = value;      }                                                 1      3     3      1
1      4     6      4      1
void set (MyInt item)                                                        1      5    10     10      5       1
{ this.value = item.value;      }                                            1      6    15     20     15       6       1
1      7    21     35     35      21       7       1
int get ()                                                                   1      8    28     56     70      56      28       8      1
{ return value;     }                                                        1      9    36     84    126     126      84      36      9      1
1     10    45    120    210     252     210     120     45     10      1
public int compareTo(Object r)                                               1     11    55    165    330     462     462     330    165     55     11
{ nCmp++; return this.value - ((MyInt)r).value;        }                     1     12    66    220    495     792     924     792    495    220     66
1     13    78    286    715    1287    1716    1716   1287    715    286
public void sum ( MyInt left, MyInt right )                                  1     14    91    364   1001    2002    3003    3432   3003   2002   1001
{ nAdd++; this.value = left.value + right.value;       }                     1     15   105    455   1365    3003    5005    6435   6435   5005   3003
1     16   120    560   1820    4368    8008   11440 12870 11440     8008
static public int nAdditions()                                               1     17   136    680   2380    6188   12376   19448 24310 24310 19448
{ int rtn = nAdd;                                                            1     18   153    816   3060    8568   18564   31824 43758 48620 43758
nAdd = 0;                                                                 1     19   171    969   3876   11628   27132   50388 75582 92378 92378
return rtn;                                                               1     20   190   1140   4845   15504   38760   77520 125970 167960 184756
}                                                                       */

static public int nCompares()
{ int rtn = nCmp;
nCmp = 0;
return rtn;
}

Printed 2010-Sep-05 at 20:44

```
DOCUMENT INFO
Shared By:
Categories:
Stats:
 views: 5 posted: 9/6/2010 language: English pages: 2
How are you planning on using Docstoc?