Recursion chapters 3 - PowerPoint PPT Presentation

1 / 18
About This Presentation
Title:

Recursion chapters 3

Description:

{ tentatively place queen in square ... if queen can not be captured, than insert ... row ; try another row (if a queen could not be placed at the ... – PowerPoint PPT presentation

Number of Views:75
Avg rating:3.0/5.0
Slides: 19
Provided by: foxr
Category:

less

Transcript and Presenter's Notes

Title: Recursion chapters 3


1
Recursion (chapters 3 6)
  • Concept defining a solution in terms of a
    simpler version of the solution
  • Recursion is often used instead of iteration
  • The Benefits
  • often your code will be shorter
  • it is usually easier to define the solution
    recursively
  • and writing the code is just a matter of
    implementing the definition
  • more elegant solution
  • you may not need local variables to implement
    your solution
  • some solutions are only expressible recursively
    (or at least are only easily expressible
    recursively)
  • this is true of some tree and graph operations,
    and search problems that require backtracking
  • The Cost
  • recursive solutions are often harder to debug
  • recursion requires numerous function calling
  • this can lead to much poorer run-time
    performance
  • takes up more memory space (on the run-time
    stack)
  • in a few cases, solution may be much less
    efficient than an iterative solution

2
Writing Recursive Solutions
  • Four questions for construction recursive
    solutions
  • how can you define the problem in terms of a
    smaller problem?
  • how does each recursive call diminish the size of
    the problem?
  • what instance of the problem can serve as the
    base case?
  • as the problem size diminishes, will you reach
    this base case?
  • Factorial
  • fact(n) if(n
  • Fibonacci
  • fib(n) if (n 2)
  • Finding largest item in an array
  • largest(a, n) if (n 0) return a0 else
    return max(an, largest(a, n-1))
  • We can also find the largest using a binary
    search like strategy
  • largest(a, low, high)
  • if(low high) return alow
  • else return max(largest(a, low, (lowhigh)/2)),
    largest(a, (lowhigh)/21, high))
  • Writing elements backwards
  • output_backward(S, n) if(n0)
  • output_backwards(S, n-1)
  • output character in S at position (n)

3
Mr. Spocks Dilemma
  • To see how to set up a definition recursively, we
    will consider selecting k things (in any order)
    out of n items
  • if k n, then there is only one choice, you
    select all k items
  • if k n, then there are no choices
  • if k 0, then there is only 1 choice (choose
    nothing)
  • these 3 conditions represent our base cases
  • otherwise, you must make some choices
  • lets consider some arbitrary element, i
  • you can either choose i or not choose i
  • if you choose i, then there are n-1 things left
    to choose between and k-1 choices to make
  • if you do not choose i, then there are n-1 things
    left to choose between and k choices to make
  • Our recursive definition for C(n, k) C(n-1,
    k-1) C(n-1, k)
  • Our base cases are
  • C(n, k) 1 if k 0 or k n
  • C(n, k) 0 if k n
  • writing a method to compute C(n, k) is now
    trivial!

4
A Function to Compute c(n, k)
public static int c(int n, int k)
// how many combinations of k items can
be chosen out of a set of n? // this func
tion determines this value recursively
// Precondition n and k are non-negative
integer values // Postcondition returns
c(n, k) if ( (k 0) (k n) ) r
eturn 1 else if (k n) return 0
else return c(n 1, k 1) c(n 1, k)

c(5, 3) c(4, 2) c(4, 3) c(3, 1) c(3, 2)
c(3, 2) c(3, 3) c(2, 0) c(2, 1) c(2
, 1) c(2, 2) c(2, 1) c(2, 2) 1
1 c(1, 0) c(1, 1) c(1, 0) c(1, 1)
1 c(1, 0) c(1, 1) 1 1 10
How would you implement this iteratively? Since
we have defined c(n, k) in terms of itself, it i
s not easily apparent how to compute c(n, k)
through an iterative-based formula
5
Towers of Hanoi
  • The Emperor of Hanoi (a city in Vietnam) invented
    this problem to find the wisest person to succeed
    him
  • given n disks and 3 poles (we will call them A, B
    and C) where each disk is of a different
    weight/size such that only a smaller disk can sit
    on top of a heavier/bigger disk
  • find a pattern of movements to move the n disks
    from pole A to pole B using pole C as an
    intermediate, moving 1 disk at a time

towers(int n, char a, char b, char c)
if(n 1) System.out.println(move from
tower a to tower b)
else towers(n-1, a, c, b)
System.out.println(move from
tower a to tower b)
towers(n-1, c, b, a)

Run-trace of the recursive calls for n 3
6
Finding the Kth Smallest Item
  • Rather than searching for the largest int in an
    array, what if you wanted to find the kth largest
    or smallest?
  • You could sort the array and then return ak-1
    (kth largest) or an-k1 (kth smallest)
  • However, sorting is generally reserved for a
    situation where you want all of the items in
    order, here you only want to find a particular
    item
  • You could also solve this by implementing part of
    the selection sort algorithm
  • for(i0i
  • find the smallest item and swap it with ai
  • when done, the kth smallest item is in ak-1
  • As straight-forward as both of these approaches
    are, a recursive solution might be more efficient

  • or it may not be more efficient, but it will not
    be less efficient

7
Partitioning an Array
  • Imagine that you have an array of int values in
    no particular order
  • Select the element at the beginning, we will call
    this the pivot value
  • Work your way through the array moving all
    elements pivot to the right side of the array
    and all elements
    array
  • Place the pivot in the space between those those
  • Now the array is partitioned so that the pivot is
    in its proper place (no other values are in their
    proper place though)
  • Now, if the pivot is in ak-1 then the pivot is
    the kth smallest value
  • But if the pivot is in some position am where m
    k-1 then we recursively repeat the partitioning
    with the upper half of the array
  • and if m partitioning with the lower half of the array

8
Example
  • If you have learned the quick sort algorithm, the
    partition routine is the same
  • If not, we will cover this in chapter 10
  • We will find that this routine of finding the kth
    smallest can work in as little as n instructions,
    but may take as many as sorting the whole array
    depending on the order of the data

Array 4, 7, 3, 6, 8, 1, 9, 2
We want to find the 3rd smallest value
pivot 4, partition array to become 2, 1, 3,
4, 8, 6, 9, 7 The pivot value was inserted at
a3 (the 4th smallest item) So we continue with
the lower part of the array 2, 1, 3, p
ivot 2, partition the lower part of the array
to become 1, 2, 3, The pivot value was in
serted into a1 (the 2nd smallest item)
So we continue with the upper part of what were
just working on , 3, The pivot is 3 at
position a2, so this is the 3rd smallest value,
we are done, third smallest a2 3
9
Recursive Definition and Solution
Assume A is an array, first is initially 0, last
is initially n-1 pivotIndex is the location whe
re the pivot has been inserted
after performing partition, p is the pivot value
kSmall(k, A, first, last) kSmall(k, A, firs
t, pivotIndex-1) if k p if k pivotIndex first 1
kSmall(k (pivotIndex first
1), A, pivotIndex 1, last) if k piv
otIndex first 1
  • Notice how easy it is to go from the recursive
    definition to the Java code
  • Partition will be covered in chapter 10
  • Partition itself is implemented iteratively

public int kSmall(int k, int a, int first, int
last) // choose pivot p from afirst..la
st and partition array // around p with p
ivotIndex being the location p was inserted
if(k kSmall(k, a, first, pivotIndex 1)
else if (k pivotIndex first 1)
return p else return kSmall(k (pivotIndex
first 1), a, pivotIndex 1, last)
10
8 Queens Problem
  • We continue our examination of recursion (in
    chapter 6) with a class search problem that
    requires backtracking
  • The idea of backtracking is that if you have made
    a wrong selection in your search, back up to the
    point of your latest decision and try a new
    choice
  • in the 8 queens problem, you want to position 8
    queens on a chessboard so that no queen can
    capture any other
  • where do you place them?

How many possible choices are there?
Using c(n, k), n 64 (64 places for queens) and
k 8 (8 queens to place), c(64, 8) 4 billion
! We could try every possible board configurati
on of c(64, 8) but many are irrelevant (we wont
place a queen in a column that already has a que
en)
11
8-Queen Solution
  • A better solution is to work column-by-column
  • For the first column, place a queen in a row
  • Now expand the solution
  • expansion requires that you move onto the next
    column and iterate through each row until you
    find a row where the newly placed queen cannot be
    captured by any previous queen, then you expand
  • the expand part is recursive
  • if you reach a column and search all 8 rows and
    cant find a place for your queen, then you must
    backtrack go back to a previous recursive level
    and continue searching

This strategy requires at most 8! boards before
it has a solution and determines that there isn
t one
(8! 40,320)
12
8-Queens Solution Pseudocode
placeQueens(column) if(column 8) problem is
solved, print solution and return that
the problem has been solved else
row 1 while(row yet solved) tentatively place
queen in square de
termine if queen can be captured at this
position if queen can not be cap
tured, than insert
into board and call
placeQueens(column1) else remov
e queen from and
continue searching by doing
row try another row (if a queen could
not be placed at the next column, recursion r
eturns us here where we backtrack by removing
the queen from the board, adding 1 to row, an
d trying again
see pages 295-299 for a partial implementation in
Java
13
Defining a Language
  • A language is a set of symbols (from some finite
    alphabet) and rules (called a grammar) for
    combining the symbols
  • A recognition algorithm is an algorithm that,
    given a string of symbols, determines if the
    string is part of that language or not
  • Example positive twos complement is a language
    composed of 1s and 0s such that the leading digit
    is not a 1
  • We can write a program that given an input String
    can determine if the String is an element of the
    positive twos complement language
  • Most commonly, languages are more complex than
    binary
  • so we need more complex grammars that might
    entail dozens or more rules
  • to recognize whether a String is part of the
    language or not, our recognition algorithm will
    commonly be implemented recursively because of
    the complexity
  • Example The blue can was used to hold 20
    gallons of paint.
  • When parsing this sentence and you reach can,
    is it a noun, verb or auxiliary verb?
  • Assume you select verb. You will discover that
    can is not the verb since was used to hold is
    the verb, so you have to backtrack and revise
    your choice of can from verb to noun

14
Language Recognizers
  • Consider a language to recognize legal Java
    identifiers (identifiers must contain only
    letters, digits, _ and and must start with a
    letter, _, )
  • isLegal(String s)
  • if s.length( ) 1 and s.charAt(0) is a letter,
    _ or then return true
  • else if s.length( ) 1 then return false
  • else if s.charAt(s.length( )-1) is a letter, _,
    or digit then return isLegal(s) where s is s
    without the last character
  • else return false
  • Another recognizer might look for palindromes
    (something of the form abcdcba) and for languages
    of the form AnBn

isAnBn(w) if(length of w is 0) return true
else if(w.charAt(0) A
and w.charAt(last) B) return isA
nBn(w) where w is w without first and last c
haracters else return false
isPal(w) if(w is the empty string or w is of
length 1) return true else if(w.charAt(0
) w.charAt(last)) return isPal(w) where w
w without the first and last characters
else return false
15
Prefix Notation Recognizer
  • You have most likely covered pre and postfix
    notation in 262
  • This is also covered here in part in chapter 5
    and in more detail in chapter 6
  • Given a string S, is it in legal prefix
    notation?
  • Our grammar can be written as follows


  • this notation is known as BNF grammar
  • Notice how it is defined recursively
  • a prefix notation is either an identifier, or it
    is an operator (, -, , /) followed by two
    prefix expressions, which themselves are either
    identifiers or operators followed by two prefix
    expressions, etc
  • so A / B C E F is a legal prefix expression

  • and A / B C E F is not

16
Prefix Recognizer Pseudocode
isPre( ) size length of expression strEx
p lastChar endPre(0, size 1) if
(lastChar 0 lastChar size 1)
return true else return false en
dPre(first, last) if(first
last) return -1 ch character at position
first of strExp if (ch is an identifier) r
eturn first else if (ch is an operator)
firstEnd endPre(first1, last)
if (firstEnd -1) return
endPre(firstEnd1, last) else return
-1 else return -1
  • A prefix expression is either an identifier or an
    operator followed by two prefix expressions
  • If, when parsing the expression, we find an
    operator, then we will recursively seek two
    prefix expressions
  • If there are two expressions such that the first
    starts right after the operator (at first) and
    the second ends at the end of the string, then we
    have a legal prefix expression
  • Finding the end of the two prefix expressions may
    require that we seek prefix expressions
    recursively such that the first starts at first
    and the second ends at last
  • A more complete explanation is given in the
    textbook on pages 308-312

17
Postfix Expressions
  • Below are two sets of code to evaluate a postfix
    expression and to convert an expression from a
    prefix to a postfix expression

convert(String prefix) ch first char
of prefix delete first char of prefix
if(ch is identifier) return ch else
item1 convert(prefix)
delete next char of prefix
item2 convert(prefix)
return item1 item2 ch

postfix(String expr) if(exp is a sing
le value) return expr.getValue( ) else
return item1 expr0 i
tem2 expr1 operator expr2
if(operator )
return(postfix(item1) postfix(item2))
else if(operator )
return(postfix(item1) postfix(item2))
else if(operator -) return(postfix(item
2) postfix(item1)) else return(postifx(item2
) / postfix(item1))
18
Cost of Hanoi and Fibonacci
  • If you examine the Hanoi algorithm, you can
    easily identify the recurrence
  • H(n) H(n-1) 1 H(n-1)
  • 2H(n-1) 1
  • That is, to perform Hanoi with n disks, you must
    solve the problem of Hanoi with n-1 disks, do one
    move, and then solve the problem of Hanoi with
    n-1 disks
  • Lets try this out for n 4
  • H(4) 2H(3) 1
  • H(3) 2H(2) 1
  • H(2) 2H(1) 1
  • H(1) 1
  • H(2) 211 3
  • H(3) 23 1 7
  • H(4) 27 1 15
  • In general, the solution for n is twice the
    solution for n-1 plus 1 extra step
  • The Towers of Hanois solution is 2n-11
  • for n 64, this is a LARGE number!
  • The Fibonacci algorithm has the recurrence
  • F(n) F(n-1) F(n-2)
  • This is not quite the same as Hanoi, but in
    essence, to solve the problem for F(n), we need
    two more solutions that are close to F(n)
  • Both of these problems have recursive solutions
    that are known as intractible it takes too much
    time to solve them when n is large
Write a Comment
User Comments (0)
About PowerShow.com