Recursion Recursion 递归) 1 Introduction to Recursion Principles of by yurtgc548

VIEWS: 4 PAGES: 76

									         Recursion (递归)

1. Introduction to Recursion
  -- Principles of recursion
  -- Recursion trees
2. How recursion is implemented on the machine
  -- Stacks and recursion
3. Analyzing Recursion
  -- when to use recursion
4. Backtracking (回溯法)– a method to try all
    possibilities using recursion
An algorithm is recursive (递归的) if it calls
itself (directly or indirectly) to do part of its
work.
  Factorials: A recursive definition
• In Mathematics:



                                    Base case
                                   (递归基)




                             General case that
                            reduces to simpler
                             case(递归步)
+: concise and elegant
-: can require keeping track of many
partial computations
The process of recursive call
Every recursive process consists of two parts:
1. A smallest, base case that gives a solution;
2. A general method that reduces a particular case
   to one or more of the smaller cases, reducing
   the problem all the way to the base case
   eventually.
The tower of Hanoi




Task: move the tower from 1 to 3 using 2 as
temporary storage.
Rules: 1. move only one disk at one time;
       2. No larger disk can be placed on a
          smaller disk.
Divide and conquer(分治法)
     1                     2                      3




         We have to get to this state and then move
                     the bottom disk
 1                  2   3




A similar problem
1    2          3




    Solved by
    recursion
      The Solution
典故:
古印度有一個傳說,婆羅賀摩(Brahma,眾生地方的廟宇安置了一
個含有64個金盤的婆羅賀摩塔,婆羅門教的憎侶們,奉命依遊戲規
則要不停移動這些金盤,傳說中還說,當重排完成時,就是世界末
日的到來,而經過計算,這64個金盤的遊戲至少要經過 264-1次才會
完成,如果移動一次以1秒鐘計算,還要經過
184467440737095551615天才能完成,照這樣看來,這世界還算蠻
安全的。

       Our goal: move(8, 1, 3, 2)
 Our goal: move(8, 1, 3, 2)

Steps to solve the problem:
 move(7, 1, 2, 3); /*move 7 disks from tower 1
to 2 */
cout << “move disk 8 from tower 1 to
3.”<<endl;
move(7, 2, 3, 1); /* move 7 disks from tower
2 to 3 */
Recursive Function




    The base case is
      count == 0
Designing recursive algorithms
   Tree of function calls(函数调用树)
Tree of function calls is a tool to analyzing the process of
  function calls.
• A node(结点) denotes a function call with the function
  name;
• A function may invokes other functions, which are
  denoted as children;
• Different recursive calls appear as different vertices
  with the same name;
• Recursion tree: the recursive part of the tree of function
  calls.
invoke the
 function
                  Meaning of the tree of
                    function calls: the
                  traversal of the tree is
                 the trace of the function
                           calls

  Return from
  the function
Tree of function calls and the
execution order




                                 Recursive call



Execution
  order
Recursion tree for three disks
                                 Number of nodes is
                                 the number of disk
                                    movements.
The number of moves to solve Hanoi for
64 disks?
The number of inner nodes:
1+2+22+ … +263 = 264 – 1 ≈ 1.6 × 1019
It will take more than 500 billion (五千亿年)years to
finish the task suppose one can move one disk every
second.


Note also that our program also produces the best
possible solution.
          Recursion (递归)

1. Introduction to Recursion
  -- Solving problems using recursion
  -- Recursion trees
2. How recursion is implemented on the machine
  -- Stacks and recursion
3. Analyzing Recursion
  -- when to use recursion
4. Backtracking (回溯法)– a method to try all
    possibilities using recursion
         Recursion and Stacks



• Recursive calls are implemented by using stacks;
• Recursion can be replaced by stacks and
  iteration (迭代);
    Function A calls B, B calls C:
Save returning
 address and        A     B
 parameters                            C




   Start from the
   saved address
                               First started, last
                                    finished
Computation process of factorial (4)
Factorial(4) = 4*factorial(3)
                   3*factorial(2)
                           2*factorial(1)
                                 1*factorial(0)
                                 1*1
      Stack Frames for Subprograms
When a program calls a subprogram, the system:
• Store returning location and parameters;
• Allocate storage for all the local variables.
• Then the control is passed to the subprogram.

The information about the returning address and
parameters is stored in the activation record(活
动记录) for the function call.
When the subprogram is finished,
• Return the result of the subprogram;
• Release the storage allocated for the subprogram;
• the control is passed to the caller and execution
  starts at the returning address.
Temporary storage areas for use by functions would
be allocated in a list with the property last in, first
out.
So, stack is the data structure to manage function
call mechanism.
When a function call is made:
• the activation record is pushed into the stack, and
• when the function is finished, the activation record
for the function is popped off.
                                                               D calls itself




Activation record for
the main program M
 Stack frames(运行栈): each column shows the stack contents at a given time:
• A function may call itself. There is no difference
  between this recursive call and other function calls.
• For each recursive call, an activation record for the
  instance of the call is pushed into the stack.
  L1:
  L2:

  L3:


L4:

        int main() {
              move(2,1,3,2);
        L0:   : ….;
Stack frames for move(2, 1, 3, 2)
Activation record:
(address, n, start, finish, tempt)




  L2, 0, 1, 3, 2
 L2, 1, 1, 2, 3
 L0, 2, 1, 3, 2
                        Return, Pop(), goto L2

L2, 0, 1, 2, 3
L2, 1, 1, 2, 3
L0, 2, 1, 3, 2



    Starting from L2,
   move disk 1 from 1
           to 2




 L2, 1, 1, 2, 3
 L0, 2, 1, 3, 2
                            Recursive call at L3, so push()
           L4, 0, 3, 2, 1
         L2, 1, 1, 2, 3
         L0, 2, 1, 3, 2



Return, pop(), then
     goto L4




          L2, 1, 1, 2, 3
          L0, 2, 1, 3, 2
                      Starting at L4, so pop() again,
                               and goto L2

     L2, 1, 1, 2, 3
    L0, 2, 1, 3, 2



Do L2: move disk 2
   from 1 to 3



     L0, 2, 1, 3, 2
                  Recursive call
                  Recursive call
                     at L1
                      at L3

 L2, 0, 2, 1, 3
L4, 1, 2, 3, 1
L0, 2, 1, 3, 2
                            Pop(), goto L2


 L2, 0, 2, 1, 3
L4, 1, 2, 3, 1
L0, 2, 1, 3, 2


                  Moving disk 1 from 2 to 3



L4, 1, 2, 3, 1
L0, 2, 1, 3, 2
                 Recursive call at L3, push()

L4, 0, 1, 3, 2
L4, 1, 2, 3, 1
L0, 2, 1, 3, 2
L4, 0, 1, 3, 2
L4, 1, 2, 3, 1
L0, 2, 1, 3, 2


                 Pop(), goto L4, so pop() again, goto L4
                               pop() again
  Final state when
move(2, 1,3,2) is done
         Recursion (递归)

1. Introduction to Recursion
  -- Solving problems using recursion
  -- Recursion trees
2. How recursion is implemented on the machine
  -- Stacks and recursion
3. Analyzing Recursion
  -- when to use recursion
4. Backtracking (回溯法)– a method to try all
    possibilities using recursion
Analyzing space and time complexity




     What correspond to time
          complexity?
                                         3 time units +
                                     A’s and D’s time units



                                      3
     The time
   complexity is
  proportional to
  the number of                  3
      nodes.                                       2


                             1                     2

time complexity: count the
   total time units in the
                                                   1
     function call tree.
           Complexity of factorial




空间复杂度:变量占用空间+
 递归工作栈占用空间 = O(n)

时间复杂度:
T(0) = 1
 T(n)= 1 + T(n-1) = O(n)
(recurrence relation 递推关系)
    Complexity of Hanoi




空间复杂度:            时间复杂度:
变量占用空间+           T(n)= T(n-1) + 1+T(n-1)
递归工作栈占用空间         T(0) = 0
 = O(n)           T(n) = O(2n)
 Complexity and recursive trees

根据递归调用树可以估算递归算法的空间复
  杂度和时间复杂度:
• 空间复杂度与递归树的高度成正比;
• 时间复杂度与函数的调用次数有关,与递
  归树的结点总数正比。
       What we learn about recursion
• A recursive algorithm must have a base case, which gives a
  direct solution, and a method which reduces general cases to
  simpler cases.
• Recursion is done by using stacks:
   – When a call is made, the activation record is pushed into the
     stack and control is passed to the called function;
   – When the call is finished, the activation record is popped off
     the stack and execution starts from the address in the popped
     record.
• The recursive tree of a recursive algorithm can be used to
  analyze the algorithm:
   – The space complexity is proportional to the height of the
     recursive tree;
   – The time complexity is proportional to the number of nodes.
        Recursive or Nonrecursive
Factorials             Recursive version




                                 Nonrecursive
                                   version
The recursive version is
more expensive in space
       and time
Recursion tree for F7                     F5 is repeated




                 F3 is repeated 5 times
  Nonrecursive
    version




Using Iteration
  (迭代)
• Space complexity for recursive version is linear in n.
• Time complexity for the recursive version is
  exponential with n (>= 2n/2).
• Time complexity for the nonrecursive version is linear
  in n.
• The space complexity for the nonrecursive version: it
  uses only 4 variables.
Hanoi with tail recursion




             Last executed statement is a
                    recursive call
Hanoi without tail recursion
          When to use recursion
• If time and space is not an issue, then
  recursive version is much easier to understand
  and preferred.
• If duplicate tasks are involved, then data
  structure other than stacks will be appropriate.
• Recursion can always be replaced by iteration
  and stacks. But no point to do it if not
  necessary.
         Recursion (递归)

1. Introduction to Recursion
  -- Solving problems using recursion
  -- Recursion trees
2. How recursion is implemented on the machine
  -- Stacks and recursion
3. Analyzing Recursion
  -- when to use recursion
4. Backtracking (回溯法)– a method to try all
    possibilities using recursion
           Backtracking(回溯)
A method to try all possibilities using recursion.

When there are several possibilities,
• take one and go on;
• go back to the most recent choice, and try another
  possibility when a dead end is reached.
Eight Queens Puzzle
          Four Queens Solution
                    Take 1 of the 4 legitimate positions




guarded

                                                  backtrack
               Dead end



                                                 backtrack
               backtrack
                 Backtracking
• Backtracking is a recursive method that goes back to
  the most recent choice and tries another possibility.
• In (b), we go back to row 2 and put the queen in
  column 4 instead.
• In (c) , there is no other possibilities in row two. We go
  back to row 1 and put the queen in column 2.
            Outline of the solution

• Imagining using a class called Queens to represent a
  partial configuration(格局, 状态) of queens;
• Add a queen in the configuration and continue the
  search from the new configuration;
• If this does not lead to a solution, then remove the
  newly added queens and try another position and
  continue the search until a solution is reached.
                           Exit: a solution is
                                 found




                  When it is returned here, the
                  queen added at p is removed
Exit: dead end   and try next possible position.
The main program
The Queen Class

           (count, col) denotes a
             possible position
The position is
    empty
count is modified    Occupied
  after insertion.
It is not necessary to check the lower
                part. (?)
The Backtracking Function
                                       Guarded positions are
                                         not investigated



                                         Effectively pruning
                                           a recursion tree
                Dead end




Part of the recursion tree for eight queens problem
        Analysis of Backtracking
• Effectiveness of backtracking: positions that are
  discovered impossible prevent the later
  investigation of fruitless paths.
• Number of configurations that there is only one
  queen in each row: 88
• Number of configurations that there is only one
  queen in each column: 8!
• Backtracking cut this number further: it does not
  investigate impossible paths. See the recursion
  tree.
               Lower Bounds
However, the amount of work done by backtracking
  still grows rapidly with n.
To place a queen on the first n/4 rows, the minimum
  positions to investigate:
 n(n-3)(n-6)…(n-3n/4) > (n/4)n/4 > 2n



     The queen guards at most three
       positions in the next row
             Task: Improvement
• The loops in function unguarded takes
  considerable time when checking if a position is
  guarded in three directions.
• An improvement is to keep track which columns
  are guarded using an one dimension bool array,
  which diagonals are guarded using two bool
  arrays. This make the function unguarded much
  simpler.
                    Upward_free:
                    row+col:0--6



    Downward_free:
board_size-1+row-col:0--6
New Queens




Number of
diagonals
Modify the column and two
diagonals that are guarded
           now.
bool Queens::unguarded(int col)const
/*Post: Return true if the position (count, col)
is unguarded, false else. */
{
    return col_free(col)
         && upward_free[count+col]
      && downward_free[count-col+board_size-1];
}
                Summary
• Recursion: concept and recursion trees
• Principles of designing recursive algorithms;
• Divide and conquer, a method to solve problems
  using recursion;
• How recursion is implemented in machine;
• Complexity analysis using recursion trees.

								
To top