Recursive : Divide and Conquer(meta-algo II)

  • Assume you have an algorithm that works.
  • Use it to write an algorithm that works.
  • till use brute force to get into the smallest problem(base case).

 meta-recursive algorithm

def recursiveAlgo(a,b,c){
//pre-cond: a,b,c
//post-cond: x,y,z

    if((a,b,c) is sufficently small instance) return (0,0,0)
    else{
        (asub1,bsub1,csub1) =a smaller part of (a,b,c)
        (xsub1,ysub1,zsub1) = recursiveAlgo(asub1,bsub1,csub1)

        (asub2,bsub2,csub2) =a diff smaller part of (a,b,c)
        (xsub2,ysub2,zsub2) = recursiveAlgo(asub2,bsub2,csub2)

        (x,y,z) = combine((xsub1,ysub1,zsub1),(xsub2,ysub2,zsub2))

        return (x,y,z)
    }

}

 

Trust your friends to solve sub-instances.

The sub-instance must be smaller and the same problem.

Combine solution given by friend to construct your own solution for your instance.

Focus on only one step.

Do not trace out the entire computation.

Consider your input instance:

Remember that you know nothing other than what is given to you by the precondition.

Be sure each path in your code returns what is required by the postcondition.

Do not worry about who your boss is OR how your friends solve their instance.

No global variable or effects.

From you instance, construct one or more subinstances.

Prove that the subinstances that you give to your friends are in some way "smaller" than your instance.

And you instance has a finite size.

Assume by magic (strong induction) your friends give you a correct solution for each of these.

If your instance is sufficiently small, sovle it yourself as a base case.

Your solution for the base case meets the postcondition.

T(n) = aT(n/b) + f(n)

evaluating: T(n) = a T(n/b) + f(n)

Level   Instance Size work in stack frame #stack frames work in Level
0 . n f(n) 1 1 * f(n)
1 .... n/b f(n/b) a a * f(n/b)
2   n/b2 f(n/b2) a2 a2 * f(n/b2)
           
i ................ n/bi f(n/bi) ai  
           
h=logn/logb ................................. n/bh=1 T(1) ah=alogbn=nlogba nlogba * T(1)

 Total work: T(n) = Σi=0..h ai * f(n/bi)

 

Pros Cons
Worry about one step at a time Student resist it.

An abstraction within which to develop, think about,and describe algorithms

in such way that their correctness is transparent.

expect too much from their friends.
expect too much from their boss.

 

T(1)=1

T(2)=2

T(n)=T(n-1)+T(n-2)+3

//TowersOfHanoi
towersOfHanoi(n,source,dest,spare){
//pre-cond: the n smallest disks are on pole source
//post-cond: they are moved to pole dest

if(n==1)
move the single disk from source to dest

else{
towersOfHanoi(n-1,source,spare,dest);
towersOfHanoi(1,source,dest,spare);
towersOfHanoi(n-1,spare,dest,source);
}

//T(n)=2T(n-1)+1
//exponential
}

Four Recursive sorts

  Size of sublists
  n/2,n/2 n-1,1

Minimal effort splitting

Lots of effort recombining

merge sort insertion sort

Lots of effort splitting

Minimal effort recombining

Quick sort selection sort

  

Quick Sort

Best Time: T(n)=T(n/2)+T(n/2)+O(n):O(nlogn)

Worst Time: T(n)=T(0)+T(n-1)+O(n):O(n2)

Expected Time: T(n)=T(n/3)+T(2n/3)+O(n):O(nlogn)

 

Kth element problem

partition set into two using randomly chosen pivot, left OR right?

Best Time: T(n)=T(n/2)+O(n):O(n)

Worse Time:T(n)=T(n-1)+O(n):O(n2)

Expected Time: T(n)=T(2n/3)+O(n):O(n)

 

T(n)=T(n/2)+1:O(logN)


Recursion on Trees

a binary tree:

  • the empty tree
  • a node with a right and a left sub-tree

Most programmers don't use empty tree as a base case, This causes a lot more work.

Empty tree is cool as zero or -∞, to provide a base state.

3+4+8+2+...

              | Sum so far is 17

3+4+8+2+...

| Sum so far is 0

NewSum=OldSum+nextValue

            = 0        +3

            =3

 

 3*4*2*3...

           |Product so far is 72

3*4*2*3...

|Product so far is 1

NewProd=OldProd*newValue 

            =1 * 3

True and True and False...

               | So far is True

|So far is True 

 

new = Old and next

       =True and True

       =True 

 max(3,4,2...)

              | max so far is 4

       |max so far is -∞           

max(tree)=max(left,right)+1 
   

 

Time: T(n)=2T(n/2)+O(n)=O(nlogn)

                =2T(n/2)+O(n1)=O(nlognn)

 

def isBSTTree(tree,[min,max]):

"""pre-cond: tree is a binary tree. In addition,[min,max] is a range of values.
"""post-cond: the output indicates whether it is a binary search tree with values within this range.

    if(tree=emptyTree):
        return YES;
    elseif(rootkey(tree) in [min,max] and isBSTTree(leftSubTree(tree,[min,rootkey(tree)]) and isBSTTree(rightSubTree(tree),[rootkey(tree),max])):
        return YES;
    else:
        return NO;

 

posted on 2012-02-24 21:49  grep  阅读(296)  评论(0编辑  收藏  举报