Recursion as a Problem-Solving Technique Chapter 5
Chapter 5 -- Recursion as a Problem-Solving Technique Chapter 2 presented the basic concepts of recursion. This chapter introduces you to two new concepts, backtracking and formal grammars. Backtracking is a problem-solving technique that involves guesses at a solution. Formal grammars enable you to define, for example, syntactically correct algebraic expressions. This chapter concludes with a discussion of the close relationship between recursion and mathematical induction. CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique Backtracking This section considers an organized way to make successive guesses at a solution. If a particular guess leads to a dead end, you back up to that guess and replace it with a different guess. You can combine recursion and backtracking to solve the following problem CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique The Eight Queens Problem Given: a chessboard (8x8 grid) Problem: Place 8 queens on the board in a non attacking fashion. Remember: a Queen can attack in her row, column, or along her diagonal. CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique One strategy is to guess at a solution. However there are 4,426,165,368 ways to arrange 8 queens on a chessboard. I think you might get tired trying all of these! A simple observation can eliminate many arrangements: No queen can reside on a row or column that contains another queen, Or each row and column can contain exactly one queen. This leaves 8! Arrangements to evaluate (8!=40,320) Let’s try something else CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique Let’s provide some organization for the guessing strategy Place 1 Queen per column (beginning with the first square of column 1) Next you consider column 2, you eliminate its first square (because column 1 has a Queen on row 1) you eliminate its second square (because of a diagonal attack) you finally place the queen on the third square Now consider column 3 ……… CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique After placing 5 Queens you end up at this configuration: And you are stuck So, what should you do? You can’t place a queen in column 6, so back up to column 5 and go to the next possible solution. CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique The next possible location in Column 5 is the last row. When you consider column 6, there are still no solutions available, so you back up… 5 has no more options, so you back up to column 4. CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique So, let’s write the code for bool placeQueens(int currColumn) CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique bool placeQueens(int currColumn) { if (currColumn > BOARD_SIZE) return true; else{ bool queenPlaced = false; int row = 1; while (!queenPlaced && ( row < BOARD_SIZE){ if (isUnderAttack(row,currColumn) row++; setQueen(row,currColumn) queenPlaced=placeQueens(currColumn+1) if(!queenPlaced){ removeQueen(row,currColumn); row++ } return queenPlaced; CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique Here is one solution CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique Defining Languages What is a language? A language is nothing more than a set of strings of symbols. C++Programs = {strings w: w is a syntactically correct C++ program} Note: all programs a re strings, BUT not all strings are programs. Now we need to discuss the rules for forming the strings in a language This is a Grammar. CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique The Basics of Grammars A grammar uses several special symbols x | y means x or y xy means x followed by y <word> means any instance of word that definition defines. Example: C++Ids C++Ids = {w: w is a legal C++ Identifier} So, what makes a legal identifier? A letter, followed by 0 or more letters or digits. Remember that _ is a letter. CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique Example: C++Ids (cont) There are many ways to represent this. One is a Syntax Diagram A syntax Diagram is easy for people to use, but a grammar is a better starting point if you want to write a function that will recognize an identifier CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique Example: C++Ids (cont) A grammar for the language C++Ids is <identifier> = <letter> | <identifier> <letter> | <identifier><digit> <letter> = a|b|...|z|A|B|...|Z|_ <digit> = 0|1|...|9 This definition reads as follows: An identifier is a letter, or an identifier followed by a letter, or an identifier followed by a digit. Note that this grammar is recursive, as are many grammars. CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique So, now we need to write code to recognize strings in this language. bool isId(string w) This function is recursive, so what is the base case. How is the recursive call done? CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique Here is a trace of this function for the string A2B CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique Two Simple Languages Now we want to consider two more simple examples of languages, their grammars, and the resulting recognition algorithms The first one is Palindromes First, what is a palindrome? Palindromes = {w : w reads the same left to right as right to left} Specifically, w is a palindrome if and only if: The first and last characters of w are the same AND w minus its first and last characters is a palindrome CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique Palindromes (cont) So the grammar is.... <pal> = empty_string | <ch> | a<pal>a | b<pal>b | ... | Z<pal>Z <ch> = a|b|...|z|A|B|...|Z Now, we need to write the code: bool isPal(string w) CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique The second example is strings of the form AnBn This is the set of strings of n consecutive A’s followed by n consecutive B’s This grammar is actually very similar to the grammar for palindromes. You strip away both the first and last characters and check to see that the first is an A and the last is a B <legal-word> = empty_string | A<legal-word>B Now we need to write the code: bool isAnBn(string w) CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique Algebraic Expressions One of the tasks a compiler must perform is to recognize and evaluate algebraic expressions Consider the following: y = x+z*(w/k+z*(7*6)); First: is the RHS a syntactically legal algebraic expression? If so, the compiler must then indicate how to compute the expressions value. There are several common definitions for “syntactically legal” some definitions require an expression to be fully parenthesized: ((a*b)*c) This section presents 3 different languages for algebraic expressions. CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique Infix, Prefix, and postfix notation Definitions: Infix: operator appears between its operands 3 + 2 We need associativity rules (precedence) and the use of parentheses to avoid ambiguity: a + b * c ten there is a / b * c Prefix: operator precedes its operands + 3 2 Postfix: operator follows its operands 3 2 + We will come back to more Infix discussions later (Chapter 6) CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique Prefix expressions A grammar that defines the language of all prefix expressions is: <prefix> = <identifier> | <operator><prefix><prefix> <operator> = + | - | * | / <identifier> = a | b | ... | z Now you can write a recursive algorithm that recognizes whether a string is a prefix expression What is the base case? What is the recursive call? bool isPre( string w) CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique Postfix expressions A grammar that defines the language of all postfix expressions is: <postfix> = <identifier> | <postfix><postfix><operator> <operator> = + | - | * | / <identifier> = a | b | ... | z Now you can write a recursive algorithm that converts from postfix to prefix. What is the base case? What is the recursive call? string convertPost2Pre(string w) CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
The Relationship between Recursion and Mathematical Induction A very strong relationship exists between recursion and mathematical induction. Given the similarities, it should not be surprising that induction is often employed to prove properties about recursive algorithms CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique The Correctness of the Recursive Factorial Function The proof is by induction on n Basis show the property is true for n=0 fact(0)= 1; Inductive Hypothesis assume that the property is true for an arbitrary k Inductive Conclusion show it is true for n=k+1 fact(k+1) = (k+1) * fact(k) CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique The Cost of Towers of Hanoi If you begin with N disks, how many moves does it take? When N = 1 this is easy --- 1 move When N > 1 the number is not so apparent Moves(N) = Moves(N-1) + Moves(1) + Moves(N-1) Moves(N) = 2*Moves(N-1) + Moves(1) This is a recurrence relationship. You can compute a closed form algebraic formula for this, but the techniques are not relevant to this course (they are covered in CS 465-Algorithms) The solution is moves(N)=2N-1 The proof of this is by induction on N CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique Basis show true for N=1, here 21-2=1 Inductive hypothesis assume it is true for N=K Inductive conclusion show that it is true for N=K+1 moves(k+1) = 2*moves(k)+1 = 2*(2k-1)+1 = 2k+1-1 CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique
Chapter 5 -- Recursion as a Problem-Solving Technique CS 308 Chapter 5 -- Recursion as a Problem-Solving Technique