Solving recurrence equations

Slides:



Advertisements
Similar presentations
AVL Trees1 Part-F2 AVL Trees v z. AVL Trees2 AVL Tree Definition (§ 9.2) AVL trees are balanced. An AVL Tree is a binary search tree such that.
Advertisements

A simple example finding the maximum of a set S of n numbers.
Data Structures Lecture 9 Fang Yu Department of Management Information Systems National Chengchi University Fall 2010.
Comp 122, Spring 2004 Divide and Conquer (Merge Sort)
1 Divide & Conquer Algorithms. 2 Recursion Review A function that calls itself either directly or indirectly through another function Recursive solutions.
September 12, Algorithms and Data Structures Lecture III Simonas Šaltenis Nykredit Center for Database Research Aalborg University
ADA: 4. Divide/Conquer1 Objective o look at several divide and conquer examples (merge sort, binary search), and 3 approaches for calculating their.
Divide and Conquer Chapter 6. Divide and Conquer Paradigm Divide the problem into sub-problems of smaller sizes Conquer by recursively doing the same.
Algorithms Recurrences. Definition – a recurrence is an equation or inequality that describes a function in terms of its value on smaller inputs Example.
CS Section 600 CS Section 002 Dr. Angela Guercio Spring 2010.
Divide-and-Conquer1 7 2  9 4   2  2 79  4   72  29  94  4.
Divide-and-Conquer1 7 2  9 4   2  2 79  4   72  29  94  4.
Data Structures, Spring 2004 © L. Joskowicz 1 Data Structures – LECTURE 3 Recurrence equations Formulating recurrence equations Solving recurrence equations.
Data Structures, Spring 2006 © L. Joskowicz 1 Data Structures – LECTURE 3 Recurrence equations Formulating recurrence equations Solving recurrence equations.
Analysis of Recursive Algorithms
Recurrence Relations Connection to recursive algorithms Techniques for solving them.
Unit 1. Sorting and Divide and Conquer. Lecture 1 Introduction to Algorithm and Sorting.
1 Divide and Conquer Binary Search Mergesort Recurrence Relations CSE Lecture 4 – Algorithms II.
Analyzing Complexity of Lists OperationSorted Array Sorted Linked List Unsorted Array Unsorted Linked List Search( L, x ) O(logn) O( n ) O( n ) Insert(
Divide-and-Conquer1 7 2  9 4   2  2 79  4   72  29  94  4.
Project 2 due … Project 2 due … Project 2 Project 2.
10/14/ Algorithms1 Algorithms - Ch2 - Sorting.
File Organization and Processing Week 13 Divide and Conquer.
DR. NAVEED AHMAD DEPARTMENT OF COMPUTER SCIENCE UNIVERSITY OF PESHAWAR LECTURE-5 Advance Algorithm Analysis.
The Selection Problem. 2 Median and Order Statistics In this section, we will study algorithms for finding the i th smallest element in a set of n elements.
+ David Kauchak cs312 Review. + Midterm Will be posted online this afternoon You will have 2 hours to take it watch your time! if you get stuck on a problem,
Foundations II: Data Structures and Algorithms
Introduction to Complexity Analysis. Computer Science, Silpakorn University 2 Complexity of Algorithm algorithm คือ ขั้นตอนการคำนวณ ที่ถูกนิยามไว้อย่างชัดเจนโดยจะ.
2IS80 Fundamentals of Informatics Fall 2015 Lecture 6: Sorting and Searching.
Merge Sort 1/12/2018 5:48 AM Merge Sort 7 2   7  2  2 7
Advanced Sorting 7 2  9 4   2   4   7
Chapter 11 Sorting Acknowledgement: These slides are adapted from slides provided with Data Structures and Algorithms in C++, Goodrich, Tamassia and Mount.
Analysis of Algorithms CS 477/677
Introduction to Algorithms
Subject Name: Design and Analysis of Algorithm Subject Code: 10CS43
UNIT- I Problem solving and Algorithmic Analysis
Divide-and-Conquer 6/30/2018 9:16 AM
Unit 1. Sorting and Divide and Conquer
CS 3343: Analysis of Algorithms
Algorithm Design & Analysis
Chapter 4 Divide-and-Conquer
Divide and Conquer.
CS 3343: Analysis of Algorithms
More on Merge Sort CS 244 This presentation is not given in class
CS 3343: Analysis of Algorithms
CS 3343: Analysis of Algorithms
CS 3343: Analysis of Algorithms
Recurrences.
Algorithms and Data Structures Lecture III
Divide-and-Conquer 7 2  9 4   2   4   7
Lecture No 6 Advance Analysis of Institute of Southern Punjab Multan
CSE 373 Data Structures and Algorithms
CS200: Algorithms Analysis
Divide and Conquer (Merge Sort)
Divide-and-Conquer 7 2  9 4   2   4   7
Ch. 2: Getting Started.
Trevor Brown CS 341: Algorithms Trevor Brown
Merge Sort 4/10/ :25 AM Merge Sort 7 2   7  2   4  4 9
Divide & Conquer Algorithms
Introduction To Algorithms
Algorithms Recurrences.
Recurrences.
The Selection Problem.
Algorithms CSCI 235, Spring 2019 Lecture 6 Recurrences
Divide-and-Conquer 7 2  9 4   2   4   7
Merge Sort 5/30/2019 7:52 AM Merge Sort 7 2   7  2  2 7
Divide-and-conquer approach
Divide and Conquer Merge sort and quick sort Binary search
Divide-and-Conquer 7 2  9 4   2   4   7
Presentation transcript:

Solving recurrence equations 5 techniques for solving recurrence equations: Recursion tree Iteration method Induction (Guess and Test) Master Theorem (master method) Characteristic equations We concentrate on the recursion tree method (others in the book) 5/13/2019 cutler: divide & conquer

Deriving the count using the recursion tree method Recursion trees provide a convenient way to represent the unrolling of recursive algorithm It is not a formal proof but a good technique to compute the count. Once the tree is generated, each node contains its “non recursive number of operations” t(n) or DirectSolutionCount The count is derived by summing the “non recursive number of operations” of all the nodes in the tree For convenience we usually compute the sum for all nodes at each given depth, and then sum these sums over all depths. 5/13/2019 cutler: divide & conquer

Building the recursion tree The initial recursion tree has a single node containing two fields: The recursive call, (for example Factorial(n)) and the corresponding count T(n) . The tree is generated by: unrolling the recursion of the node depth 0, then unrolling the recursion for the nodes at depth 1, etc. The recursion is unrolled as long as the size of the recursive call is greater than DirectSolutionSize 5/13/2019 cutler: divide & conquer

Building the recursion tree When the “recursion is unrolled”, each current leaf node is substituted by a subtree containing a root and a child for each recursive call done by the algorithm. The root of the subtree contains the recursive call, and the corresponding “non recursive count”. Each child node contains a recursive call, and its corresponding count. The unrolling continues, until the “size” in the recursive call is DirectSolutionSize Nodes with a call of DirectSolutionSize, are not “unrolled”, and their count is replaced by DirectSolutionCount 5/13/2019 cutler: divide & conquer

Example: recursive factorial Factorial(n) T(n) Initially, the recursive tree is a node containing the call to Factorial(n), and count T(n). When we unroll the computation this node is replaced with a subtree containing a root and one child: The root of the subtree contains the call to Factorial(n) , and the “non recursive count” for this call t(n)= (1). The child node contains the recursive call to Factorial(n-1), and the count for this call, T(n-1). 5/13/2019 cutler: divide & conquer

After the first unrolling depth nd T(n) Factorial(n) t(n)= (1) 0 1 (1) 1 1 T(n-1) Factorial(n-1) T(n-1) nd denotes the number of nodes at that depth 5/13/2019 cutler: divide & conquer

After the second unrolling depth nd T(n) Factorial(n) t(n)= (1) 0 1 (1) Factorial(n-1) t(n-1)= (1) 1 1 (1) Factorial(n-2) T(n-2) 2 1 T(n-2) 5/13/2019 cutler: divide & conquer

After the third unrolling depth nd T(n) Factorial(n) t(n)= (1) 0 1 (1) Factorial(n-1) t(n-1)= (1) 1 1 (1) Factorial(n-2) t(n-2)= (1) 2 1 (1) Factorial(n-3) T(n-3) 3 1 T(n-3) For Factorial DirectSolutionSize = 1 and DirectSolutionCount= (1) 5/13/2019 cutler: divide & conquer

cutler: divide & conquer The recursion tree depth nd T(n) Factorial(n) t(n)= (1) 0 1 (1) Factorial(n-1) t(n-1)= (1) 1 1 (1) Factorial(n-2) t(n-2)= (1) 2 1 (1) Factorial(n-3) t(n-3)= (1) 3 1 (1) Factorial(1) T(1)= (1) n-1 1 T(1)= (1) The sum T(n)=n* (1) = (n) 5/13/2019 cutler: divide & conquer

cutler: divide & conquer Divide and Conquer Basic idea: divide a problem into smaller portions, solve the smaller portions and combine the results. Name some algorithms you already know that employ this technique. D&C is a top down approach. Often, you use recursion to implement D&C algorithms. The following is an “outline” of a divide and conquer algorithm 5/13/2019 cutler: divide & conquer

cutler: divide & conquer Divide and Conquer procedure Solution(I); begin if size(I) <=smallSize then {calculate solution} return(DirectSolution(I)) {use direct solution} else {decompose, solve each and combine} Decompose(I, I1,...,Ik); for i:=1 to k do S(i):=Solution(Ii); {solve a smaller problem} end {for} return(Combine(S1,...,Sk)); {combine solutions} end {Solution} 5/13/2019 cutler: divide & conquer

cutler: divide & conquer Divide and Conquer Let size(I) = n DirectSolutionCount = DS(n) t(n) = D(n) + C(n) where: D(n) = count for dividing problem into subproblems C(n) = count for combining solutions 5/13/2019 cutler: divide & conquer

cutler: divide & conquer Divide and Conquer Main advantages Simple code Often efficient algorithms Suitable for parallel computation 5/13/2019 cutler: divide & conquer

cutler: divide & conquer Binary search Assumption - the list S[low…high] is sorted, and x is the search key If the search key x is in the list, x==S[i], and the index i is returned. If x is not in the list a NoSuchKey is returned Book’s version: returns an index i where x would be inserted into the sorted list 5/13/2019 cutler: divide & conquer

cutler: divide & conquer Binary search The problem is divided into 3 subproblems: x=S[mid], xÎ S[low,..,mid-1], xÎ S[mid+1,..,high] The first case x=S[mid]) is easily solved The other cases xÎ S[low,..,mid-1], or xÎ S[mid+1,..,high] require a recursive call When the array is empty the search terminates with a “non-index value” 5/13/2019 cutler: divide & conquer

cutler: divide & conquer BinarySearch(S, k, low, high) if low > high then return NoSuchKey else mid  floor ((low+high)/2) if (k == S[mid]) return mid else if (k < S[mid]) then return BinarySearch(S, k, low, mid-1) return BinarySearch(S, k, mid+1, high) 5/13/2019 cutler: divide & conquer

cutler: divide & conquer Worst case analysis A worst input (what is it?) causes the algorithm to keep searching until low>high We count number of comparisons of a list element with x per recursive call. Assume 2k  n < 2k+1 k = ëlg nû T (n) - worst case number of comparisons for the call to BS(n) 5/13/2019 cutler: divide & conquer

Recursion tree for BinarySearch (BS) BS(n) T(n) Initially, the recursive tree is a node containing the call to BS(n), and total amount of work in the worst case, T(n). When we unroll the computation this node is replaced with a subtree containing a root and one child: The root of the subtree contains the call to BS(n) , and the “nonrecursive work” for this call t(n). The child node contains the recursive call to BS(n/2), and the total amount of work in the worst case for this call, T(n/2). 5/13/2019 cutler: divide & conquer

cutler: divide & conquer After first unrolling depth nd T(n) BS(n) t(n)=1 0 1 1 BS(n/2) T(n/2) 1 1 T(n/2) 5/13/2019 cutler: divide & conquer

After second unrolling depth nd T(n) BS(n) t(n)=1 0 1 1 BS(n/2) t(n/2)=1 1 1 1 BS(n/4) T(n/4) 2 1 T(n/4) 5/13/2019 cutler: divide & conquer

cutler: divide & conquer After third unrolling depth nd T(n) BS(n) t(n)=1 0 1 1 BS(n/2) t(n/2)=1 1 1 1 1 1 1 BS(n/4) t(n/4)=1 BS(n/8) T(n/8) T(n/8) For BinarySearch DirectSolutionSize =0, 1 and DirectSolutionCount=0 for 0, and 1 for 1 5/13/2019 cutler: divide & conquer

Terminating the unrolling Let 2k n < 2k+1 k= lg n When a node has a call to BS(n/2k), (or to BS(n/2k+1)): The size of the list is DirectSolutionSize since   n/2k  = 1, (or  n/2k+1  = 0) In this case the unrolling terminates, and the node is a leaf containing DirectSolutionCount (DFC) = 1, (or 0) 5/13/2019 cutler: divide & conquer

cutler: divide & conquer The recursion tree depth nd T(n) BS(n) t(n)=1 0 1 1 BS(n/2) t(n/2)=1 1 1 1 BS(n/4) t(n/4)=1 2 1 1 BS(n/2k) DFC=1 k 1 1 T(n)=k+1=lgn +1 5/13/2019 cutler: divide & conquer

cutler: divide & conquer Merge Sort Input: S of size n. Output: a permutation of S, such that if i > j then S[ i ]  S[ j ] Divide: If S has at least 2 elements divide into S1 and S2. S1 contains the the first  n/2  elements of S. S2 has the last  n/2 elements of S. Recurs: Recursively sort S1 , and S2. Conquer: Merge sorted S1 and S2 into S. 5/13/2019 cutler: divide & conquer

cutler: divide & conquer Merge Sort: Input: S 1 if (n  2) 2 moveFirst( S, S1, (n+1)/2))// divide 3 moveSecond( S, S2, n/2) // divide 4 Sort(S1) // recurs 5 Sort(S2) // recurs 6 Merge( S1, S2, S ) // conquer 5/13/2019 cutler: divide & conquer

Merge( S1 , S2, S ): Pseudocode Input: S1 , S2, sorted in nondecreasing order Output S is a sorted sequence. 1. while (S1 is Not Empty && S2 is Not Empty) 2. if (S1.first()  S2.first() ) 3. remove first element of S1 and move it to the end of S 4. else remove first element of S2 and move it to the end of S 5. move the remaining elements of the non-empty sequence (S1 or S2 ) to S 5/13/2019 cutler: divide & conquer

Recurrence Equation for MergeSort. The implementation of the moves costs Q(n) and the merge costs Q(n). So the total count for dividing and merging is Q(n). The recurrence relation for the run time of MergeSort is T(n) = T( n/2 ) + T( n/2 ) + Q(n) . T(1) = Q(1) 5/13/2019 cutler: divide & conquer

Recursion tree for MergeSort (MS) MS(n) T(n) Initially, the recursive tree is a node containing the call to MS(n), and total amount of work in the worst case, T(n). When we unroll the computation this node is replaced with a subtree: The root of the subtree contains the call to MS(n) , and the “nonrecursive work” for this call t(n). The two children contain a recursive call to MS(n/2), and the total amount of work in the worst case for this call, T(n/2). 5/13/2019 cutler: divide & conquer

After first unrolling of mergeSort MS(n) depth nd T(n) t(n)=(n) 0 1 (n) MS(n/2) T(n/2) MS(n/2) T(n/2) 2T(n/2) 5/13/2019 cutler: divide & conquer

After second unrolling depth nd T(n) MS(n) (n) 0 1 (n) MS(n/2) (n/2) MS(n/2) (n/2) 1 2 (n) + MS(n/4) T(n/4) MS(n/4) T(n/4) MS(n/4) T(n/4) 4T(n/4) 5/13/2019 cutler: divide & conquer

cutler: divide & conquer After third unrolling depth nd T(n) MS(n) (n) 0 1 (n) MS(n/2) (n/2) MS(n/2) (n/2) 1 2 (n) + MS(n/4) (n/4) MS(n/4) (n/4) MS(n/4) (n/4) MS(n/4) (n/4) 2 4 (n) + + + MS(n/8) T(n/8) MS(n/8) T(n/8) MS(n/8) T(n/8) 8T(n/8) 5/13/2019 cutler: divide & conquer

Terminating the unrolling For simplicity let n = 2k lg n = k When a node has a call to MS(n/2k): The size of the list to merge sort is DirectSolutionSize since n/2k = 1 In this case the unrolling terminates, and the node is a leaf containing DirectSolutionCount = (1) 5/13/2019 cutler: divide & conquer

The recursion tree (excluding the calls) d nd T(n) Q (n/20) Q (n/ 21) Q (n / 21) Q (n/ 22) Q (n / 22) Q (n / 8) Q (n/ 8) Q (n / 23) Q (1) 0 1 Q (n) 1 2 Q (n) 2 4 Q (n) 3 8 Q (n) k 2k Q (n) T(n)= (k+1) Q (n) = Q( n lg n) 5/13/2019 cutler: divide & conquer

cutler: divide & conquer The sum for each depth d=0 nd=1: 21 22 . Q (n ) ´ Q n æ è ç ö ø ÷ = Q (n) d=1 nd=2: d=2 nd=22: d=k nd=2k: 5/13/2019 cutler: divide & conquer