Part two Divide & Conquers Divide and Conquer: (Divide, Conquer, Combine) - The idea is to divide the problem into smaller but similar sub problems (divide), solve it (conquer), and (combine) these solutions to create a solution to the original problem. Problem: Finding the maximum and minimum elements in a set of (n) elements using the straightforward algorithm. Algorithm straightforward (a, n, max, min) Input: array (a) with (n) elements Output: max: max value, min: min value max = min = a(1) for i = 2 to n do begin if (a(i)>max) then max=a(i) if (a(i)<min) then min=a(i) end end best= average =worst= 2(n-1) comparisons If we change the body of the loop as follows: max=min=a(1) for i=2 to n do begin if (a(i)>max) then max=a(i) else if (a(i)<min) then min=a(i) end 1 of 15 Part two Divide & Conquers best case: elements in increasing order No. of comparisons = (n-1) Worst case: elements in decreasing order No. of comparisons = 2(n-1) Average case: a(i) is greater than max half the time No. of comparisons= 3n/2 – 3/2 ½ ((n-1)+(2n-2)) Problem: is to find the maximum and minimum items in a set of (n) elements. Algorithm MaxMin(i, j, max, min) input: array of N elements, i lower bound, j upper bound output: max: largest value min: smallest value. if (i=j) then max=min=a(i) else if (i=j-1) then if (a(i)<a(j)) then max= a(j) min= a(i) else max= a(i) min= a(j) else mid= (i+j)/2 maxmin(i, mid, max, min) maxmin(mid+1, j, max1, min1) if (max<max1) then max = max1 if (min>min1) then min = min1 end 2 of 15 Part two Divide & Conquers n n C C 2 2 2 Cn 1 0 When n is a power of 2, n 2 for n 2 n 2 n 1 k C n 2C n 2 2 2 2C n 2 2 4 4C n 4 2 4 2 k 1 k 1 C2 2i i 1 2 k 1 2 k 2 3n 2 2 Note: No algorithm based on comparison can do less than this. Example Given a set of n elements. Write an algorithm using divide and conquer, to find the summation of its elements. 3 of 15 Part two Divide & Conquers A lg orithm sum(a, i, j ) Input : a : array of n elements; i : lower index; j : upper index output : s : su of elements if (i j ) then return( s a(i )) else if (i j 1) then return( s a(i ) a ( j )) else i j m 2 s1 sum(a, i, m) s 2 sum(a, m 1, j ) return( s s1 s 2 ) end . 4 of 15 Part two Divide & Conquers 2C n 1 2 C n 1 0 for n 2 n 2 n 1 C n 2C n 1 2 4C n 2 1 4 2 k 1 k 2 C2 2i i 0 n 2 k 1 1 2 n n 1 2 2 n 1 O ( n) {stopping condition n 2} OR k 1 2 C1 2 i k i 0 0 n 1 O(n) {stopping condition n 1} 5 of 15 Part two Divide & Conquers The Maximum Contiguous Subsequence Sum “Given (possibly negative) integers A1, A2 , , An , find (and identify the sequence corresponding to) the j maximum value of Ak . The maximum contiguous k i subsequence sum is zero if all the integers are negative.” Suppose we are given the following input {-2, 11, -4, 13, -5, 2} The maximum contiguous subsequence sum is (20), which encompassing items 2 through 4. Divide and Conquer approach Let consider a divide and conquer algorithm: We divide the input into two halves. The max contiguous subsequence sum can occur in one of 3 ways: Case1: It resides entirely in the 1st half. Case2: It resides entirely in the 2nd half. Case3: It begins in the 1st half but ends in the 2nd half. 1) Recursively compute the max contiguous subsequence sum that resides entirely in the 1st half. 2) Recursively compute the max contiguous subsequence sum that resides entirely in the 2nd half. 3) Compute via two consecutive loops the max contiguous subsequence sum that begins in the 1st but ends in the 2nd. 4) Choose the largest of the 3 sums. 6 of 15 Part two Divide & Conquers A lg orithm MaxSubSum(a, l , r ) Input : a : array of n elements; l : lower index r : upper index Output : max : max contiguous subsequence sum mlbs 0; mrbs 0; lbs 0; rbs 0 l r c 2 if (l r ) then if (a (l ) 0) then return a(l ) else return 0 x1 MaxSubSum(a, l , c) x2 MaxSubSum(a, c 1, r ) for i c to l step 1 { lbs lbs a (i ) if (lbs mlbs ) then mlbs lbs } for j c 1 to r step1 { rbs rbs a ( j ) if (rbs mrbs) then mrbs rbs } max max sequence( x1 , x2 , mlbs mrbs) return max end . 7 of 15 Part two Divide & Conquers 2C n n Cn 2 1 for n 1 n 1 C n 2C n n 2 4C n n n 4 k 2 C1 n k i 1 O(n n lg n) Quick Sort Algorithm (Divide & Conquer) Given the following set of data: 42 23 74 11 65 58 94 36 99 87 1st pass {11 23 36} 42 {65 58 94 74 99 87} 2nd pass 11 {23 36} 42 {65 58 94 74 99 87} Last pass 11 23 36 42 58 65 74 87 94 99 8 of 15 Part two Divide & Conquers A lg orithm QuickSort (k , lb , ub) Input : k : array with n elements lb : lower bound ; ub : upper bound Output : k : sorted flag true if lb ub then { i lb; j ub 1; key k (lb ) while flag i i 1 while k i key i i 1 j j 1 while k j key j j 1 if i j then swap k i , k j else flag false swap k lb , k j QuickSort k , lb , j 1 QuickSort k , j 1, ub end . 9 of 15 Part two Divide & Conquers 2C n n Cn 2 0 for n 2 n 1 C n O(n lg n) Note The best thing that could happen in Quick Sort would be that each partitioning stage divides the file exactly in half. Quick Sort uses about (1.38nlgn) comparisons on the average. The precise recurrence formula for the number of comparisons used by Quick Sort for a random permutation of n elements is: 1 n C n n 1 C k 1 C n k n k 1 With C1 C 0 0 for n 2 Worst Case C n1 n Cn 0 for n 2 n 1 This is equal to: n(n 1) k 1 ( n 2 ) n k 2 2 There is a simple solution to the problem of poor performance instead of using the 1st element of the array 10 of 15 Part two Divide & Conquers as the partitioning element; we could generate a random number (r), where r is in the range of 1 to the number of elements in the partition. Although the worst case is still O(n 2 ) , it is extremely unlikely that we will encounter it. 1 The probability of encounter the worst case is n! , where n is the number of elements in the file. Another method is the median-of-three. We choose the median of the left element, the right element, and the one halfway between them. Unless this median is already the left element, we exchange it with left. Space Usage Quick Sort is not working in-place sort. While the algorithm is working on one sublist, the beginning and ending indexes (borders) of all the other sublists must be saved on a stack. The size of the stack depends on the no. of sublists into which the list will be split. The worst case amount of space used by stack is (n) . Merge Sort (Divide & Conquer) We use the merge procedure as the basis for merge sort. If we have two sets of numbers that are already sorted, we can merge them together with one scan. Let the 1st set be a1 , a2 ,, an , and the 2nd set be b1 , b2 ,, bm . Assume that both sets are sorted in increasing order. Scan the 1st set until the right place to 11 of 15 Part two Divide & Conquers insert b1 is found, and insert it, then continue the scan from that place until the right place to insert b2 is found and so on. The total number of comparisons, in the worst case is the sum of the sizes of the sets. Data movements: we copy them to a temporary array; each element is copied exactly once. The overall: merging two sorted sequences of size (n), and (m) can be done with O(n+m) comparisons and data movements (provided that additional storage is available). MergeSort algorithm works as follows: 1) The sequence is divided into two equal or close-toequal (in case of an odd size) parts. 2) Each part is sorted separately recursively 3) The two sorted parts are merged into one sorted sequence. Complexity: 2C n n 2 C n 1 0 for n 2 n 2 n 1 C n O(n lg n) It is not working in-place algorithm, since it requires additional storage to copy the merged set. 12 of 15 Part two Divide & Conquers A lg orithm MergeSort (l , r ) Input : x : array with n elements; l : lower index; r : upper index Output : x : sorted if l r then retrun xl else if r l 1 then if xl xr then swapxl , xr else { l r m 2 MergeSort l , m 1 MergeSort m, r // we merge the two sorted sequences int o one sorted i l ; j m; k 0 while (i m 1 and j r ) {k k 1 if xi x j then { tempk xi ; i i 1} else {tempk x j ; j j 1} } if j r then // movethe rest of the left side to the end of the array // if i m, then the right side is already in the right place for t 0 to m 1 i xr t xm 1 t // we copy temp back int o x for t 0 to k 1 xl t tempt 1 end . 13 of 15 Part two Divide & Conquers ex: 36 20 17 13 28 14 2315 20 36 13 17 13 17 20 36 14 28 15 23 14 15 23 28 13 14 15 17 20 23 28 36 Notes: The running time of merge sort does not depend on the arrangement of the input values, thus it does not have poor worst case performance. It has the advantage that it sorts a file of n elements in time proportional to (nlgn) even in the worst case. The disadvantage is the extra space proportional to n. Binary Search Let ai , 1 i n , be a list of elements that are sorted in nondecreasing order. Consider the problem of determining whether a given element x is present in the list. If x is present, we are to determine a value j such that a j x. If x is not in the list, then j is set to be zero. 14 of 15 Part two Divide & Conquers A lg orithm BinSrch (a, i, n, x) Input : a : array with n elements in nondecrea sin g order i : lower index , n : upper index , x item sought Output : return (index j ) if x a ( j ), else return zero if i n then if x a i then return i else return 0 else i n mid 2 if x a (mid then return mid else if x a mid then return BinSrch a, i, mid 1, x else return BinSrch a, mid 1, n, x end Cn C n 1 for n 2 2 with C1 1 15 of 15