Data Structures and Algorithms for Information Processing

38
90-723: Data Structures and Algorithms for Information Processing Lecture 8: Recursion Copyright © 1999, Carnegie Mellon. All Rights Reserved. Data Structures and Algorithms for Information Processing Lecture 8: Recursion

description

Data Structures and Algorithms for Information Processing. Lecture 8: Recursion. Recursion. We’ve seen several examples of the use of recursion We’ll take a closer look at recursion as a style of programming Lends itself to analytical methods; proving program properties. - PowerPoint PPT Presentation

Transcript of Data Structures and Algorithms for Information Processing

Page 1: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Data Structures and Algorithms for Information

Processing

Lecture 8: Recursion

Page 2: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Recursion

• We’ve seen several examples of the use of recursion

• We’ll take a closer look at recursion as a style of programming

• Lends itself to analytical methods; proving program properties

Page 3: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Verifying Program Properties

• How can we be sure that a program is correct?– Debug– Test cases– Make sure output matches another

program– ...

• None of these give absolute assurance

Page 4: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Imperative Programming

• The “usual” style in Java, using commands

• Programs are written by create data (“state”) and storing it in variables

• Flow of control insures that correct sequence of assignments is executed

Page 5: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Applicative Programming• No references to other objects• No side effects (assignments, output...)• Some advantages:

– Functions only return values– No need for loops– Easier to prove properties

• A different programming style, and a different way to think about programming

Page 6: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

RecursionRecursion General pattern:

recursive_fn(params) { if (…) return some_value; else ... recursive_fn(new_params) ...}

A recursive function call is made somewhere in the body of the function

Page 7: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Tail RecursionTail Recursion General pattern:

tail_recursive_fn(params) { if (…) return some_value; else return tail_recursive_fn(new_params)}

Tail recursive: the function does no work after the recursive call

Page 8: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Tail RecursionTail Recursion

“Usual” recursive factorial

// Precondition: n >= 0

static int fact1(int n) {

if (n==0) return 1;

else return n*fact1(n-1);

}

Page 9: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Tail RecursionTail Recursion

Tail recursive factorial

static int fact2(int n) { // Invariant: n >= 0

return fact2_aux(n, 1);

}

static int fact2_aux(int n, int accum) {

if (n==0) return accum;

else return fact2_aux(n-1, n*accum);

}

Page 10: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Execution Trace

fact1(5)5*fact1(4)

5*4*fact1(3)5*4*3*fact1(2)

5*4*3*2*fact1(1)5*4*3*2*1*fact1(0)

5*4*3*2*1*1 => 120

Page 11: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Execution Trace

fact2(5)fact2_aux(5,1)

fact2_aux(4,5)fact2_aux(3,20)

fact2_aux(2,60)fact2_aux(1,120)

fact2_aux(0,120)=> 120

Page 12: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Example of Non-Tail Recursion

// Precondition: y > 0static int mult (int x, int y) { if (y==1) return x; else return x + mult(x, y-1);

}

• Addition operation carried out after the recursive call

Page 13: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Tail Recursion (cont)

• Tail recursive functions can be more

efficient

• Often easier to prove properties of tail recursive functions

– correctness, termination, cost– technique: induction

Page 14: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Example: fact2

Want to prove using induction that fact2(n) => n!

• We do this by proving an appropriate property of the auxiliary function:

fact2_aux(n, p) => n! * p

Page 15: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Example: fact2 (cont)

• Base case: n=0– for all p

fact2_aux(0, p) => p = 0! * p

• Inductive step: n > 0:– Assume true for n-1– For all p

fact2_aux(n-1, p) =>(n-1)! * p

Page 16: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Example: fact2 (cont)

• Inductive step: n > 0:– Assume true for n-1– For all p

fact2_aux(n-1, p) =>(n-1)! * p– So:

fact2_aux(n, p) => fact2_aux(n-1, n*p) =>(n-1)! * (n*p) = (n*(n-1)!)*p = n!*p

Page 17: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Example: fact2 (cont)

• Proving termination by induction:

– Base case:

fact2_aux(0, p) => return p

– Inductive case: terminates if operator * terminates

Page 18: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Proving Properties of Programs that use ListsProving Properties of

Programs that use Lists

• List concatenation: A^B

10

7

nullhead

15

-1

null

5head

Page 19: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Append

• Input: Two lists x and y

• Output: x ^ y

List append (List x, List y) { if (x == null) return y; else return new List(x.value(), append(x.next(),

y));}

Page 20: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Append (cont)

• Want to prove:

– Terminates

– Returns x^y

– Cost is O(n)

Page 21: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Termination• Base case: x.length()=0

– append(x,y) => append(null, y)

=> y

• Inductive case: x.length()=k-1>0

– append(x’,y) terminates for x’ with x’.length() < k

– append(x.next(),y) terminates

– constructor terminates

Page 22: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Correctness of append• Base case: x.length()=0

– append(x,y) => append(null, y)

= empty list ^ y = x ^ y

• Inductive case: x.length()=k-1>0

– assumption: append(x.next(), y) => (list referred to by x.next) ^ y

– new List(x.value(), append(x.next(), y)) => x ^ y

Page 23: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Cost of append

• Let Cost[n,m] be the number of operations for append(x,y) with x.length()=n and y.length() = m

• Cost[0,m] = A (constant)

• For n>0, Cost[n,m] = Cost[n-1,m] + B

• Thus, Cost[n,m] = A + nB = O(n)

Page 24: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Reversing ListsReversing Lists

• List reversal: Rev[x]

10

7

nullhead

15

7 10

nullhead

15

Page 25: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Reversing Lists: first implementation

List reverse1 (List l) { if (l == null) return null; else { return append(reverse(l.next()), new List(l.value())); }}

Page 26: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Cost of reverse1

• Cost[n] is cost of reversing list with

length n

• Cost[0] = A (constant)

• Cost[n] = B + Cost[n-1] + (n-1)C

• Solving the recurrence gives

Cost[n] = O(n^2)

Page 27: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Tail recursive reverse

• We can easily get an O(n) implementation using tail recursion:

List rev2_aux(List x, List y) { if (x==null) return y; else return rev2_aux(x.next(), new List(x.value(),

y))}List reverse2(x) { return rev2_aux(x,

null); }

Page 28: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Cost of rev2_aux

• Let Cost[n,m] be the number of operations for rev2_aux(x,y) with x.length()=n and y.length() = m

• Cost[0,m] = A (constant)

• n>0, Cost[n,m] = Cost[n-1,m+1] + B

• Thus, Cost[n,m] = A + nB = O(n)

Page 29: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Fibonacci Numbers

• Want fib(0)=1, fib(1)=1, fib(n) = fib(n-1) + fib(n-2) if n>1

• Simple recursive implementation:

// Precondition: n>=0int fib(int n) { if (n < 2) return 1; else return fib(n-1)+fib(n-2);}

Page 30: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Fibonacci Numbers

• Cost is the same as the Fibonacci numbers themselves!

• fib(n) rises exponentially with n:– fib(n) > (1.618)^n / 2

Page 31: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Imperative version

int i=1;int a=1, b=1;while (i<n) { int c = a+b; // fib(i+1) a = b; b = c; i++;}

Page 32: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Recursive Version

• Define an auxiliary function fib_aux

• Use two accumulator variables, one set to fib(i-1), the other to fib(i)

Page 33: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Recursive Version

int fib_aux (int n, int i, int x, int y) { if (i==n) return y; else return fib_aux(n, i+1, y, x+y);}int fib(int n) { if (n==0) return 1; else return fib_aux(n, 1, 1, 1);}

Page 34: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Backtracking Search

General pattern:

• Test if current position satisfies goal

• If not, mark current position as visited and make a recursive call to search procedure on neighboring points

• Exhaustive search, terminates as soon

as goal is found

Page 35: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Backtracking search: simple example

The “bear game”:

• Start with initial number of bears

• Need to reach goal number within a certain number of steps

• Possible moves:– Add incr number of bears– Divide current number in half

Page 36: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Backtracking search: simple example

Public static boolean bears (int initial, int goal, int incr, int n) { if (initial == goal) return true; else if (n==0) return false; else if (bears(initial+incr, goal, incr, n-1)) return true; else if (initial % 2 == 0) return bears(initial/2, goal, incr, n-1); else return false;}

Page 37: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Backtracking search: simple example

• Why does this program

terminate?

• What if we remove the restriction

on the number of steps?

Page 38: Data Structures and Algorithms for Information Processing

90-723: Data Structuresand Algorithms for

Information ProcessingLecture 8: Recursion

Copyright © 1999, Carnegie Mellon. All Rights Reserved.

Benefits of Recursion

• Recursion can often be implemented efficiently

• Requires less work (programming and computation)

• Tail recursive versions require less stack space

• The code is typically much cleaner than imperative versions