Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Divide and Conquer

Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

DIVIDE AND CONQUER

Introduction
One general method devised to solve a problem is divide and conquer method. It states that the problem should be divided into various subproblems until it becomes easy enough to solve each of them. After the division, each subproblem is solved. Finally, the solutions of the subproblems are integrated to achieve the final solution. Summarizing, Divide: Get subproblems and solve them Conquer: Integrate the solutions The general algorithm for performing the divide and conquer is:DandQ(P,n) { if Small(P) then return S(P); else divide P into k subproblems P1, P2, P3, ........... Pk, k>1 apply DandQ(P1), DandQ(P2), ........................DandQ(Pk) return combine(DandQ(P1), DandQ(P2), .........DandQ(Pk)) } The above divide and conquer algorithm processes a problem P having 'n' number of elements. First of all it checks whether the problem is simple enough to be solved individually using the function Small() which returns true if the problem is simple and false otherwise. If the problem is simple, its solution S(P) is returned. If the problem is not simple enough to be solved without dividing, it is subdivided into 'k' subproblems. After that, for each of the subproblem, the function DandQ is called recursively. On obtaining the solution of each subproblem, the function combine() is used to integrate the solution of the subproblems. Then the final integrated solution is returned. The time complexity of this algorithm can be specifically wrtten as:-

a & b are known constants n=bk k are the number of subproblems we assume T(1) is known f(n) is the time to divide and then combine the problem

Binary Search
As we know, the binary search logic works on a sorted list of numbers in which the element to be searched is compared with the middle element of the list and then the sublists are chosen depending upon the comparison. As we keep on dividing the list, therefore we categorize this into the divide and conquer problems. We shall first see the traditional algorithm which uses the iterative approach. BinSrc(a,n,x) { l:=1; h:=n; while(l<=h) { mid:=(l+h)/2; if(x>a[mid]) then l:=mid+1; else if(x<a[mid]) then h:=mid-1; else return mid; } return 0; } Consider the array a[7] having the following elements: 14 27 33 35 60 70 99 x=27 l=1 h=7 Iteration:1 Iteration:2 mid=4 mid=2 x<a[mid] x=a[mid] h=3 return 2 Now, we shall see the recursive approach which uses the same logic but the only difference is that instead of loops, recursion is used. BinSrc(a,l,h,x) { if(l==h) then if(x==a[l]) then return l; else return 0; else mid:=(l+h)/2; if(x>a[mid) return BinSrc(a,mid+1,h,x); else if(x<a[mid]) return BinSrc(a,l,mid-1,x); else return mid; }

Now we shall analyze this algorithm. We will see how many comparisons are required to find any number. Consider the array a[14] having the following elements:-9 -2 0 10 15 20 21 34 56 73 81 87 91 140

So, to find any number we will have to do : 1 + (2*2) + (3*4) + (4*7) = 1 + 4 + 12 + 28 = 45 comparisons Average comparisons to find a number : 45/14 = 3.22

In case of failure extra comparisons are required: 4 if x<a[1] 5 if x>a[14] 5 otherwise Therefore in case of failure we have : 45 + 4 + 5 + 5 = 59 comparisons Average comparisons in case of failure : 59/14 = 4.22

The complexity of this algorithm in three different cases is as follows: Best Case O(1) Average Case O(log n) Worst Case (log n)

Maximum & Minimum


Finding the maximum & minimum numbers from a list of numbers is a very common problem that we solve in computer science. Generally we use the following algorithm:MimMax(a,n,max,min) { max:=min:=a[0]; for i:=1 to n-1 by 1 do { if(max<a[i]) then max:=a[i]; if(min>a[i]) then min:=a[i]; } } In the above algorithm we can see that the loop will run for (n-1) times and every time the loop runs, two comparisons are being made. Therefore, in total, we have 2(n-1) comparisons. Therefore, T(n) = 2(n-1)

To further optimize the algorithm, we make use of the fact that if a number is the maximum, it definitely cannot be the minimum. So, while making the comparisons we include this logic by making the min comparison as an alternative to the max comparison. Therefore, if a number is greater than max, we do not compare that number with min. MinMax(a,n,max,min) { max:=min:=a[0]; for i:=1 to n-1 by 1 do { if(max<a[i]) then max:=a[i]; else if(min>a[i]) then min:=a[i]; } } For this algorithm, T(n) = (n-1) T(n) = 2(n-1)

if all numbers are greater than max(best case) if all numbers are smaller than max(worst case)

Let us solve this problem of finding the maximum and minimum by using the divide and conquer approach. Consider the following list:12 25 19 -6 5 91 61 115 198 201 We keep on dividing the list into sublists until we have 2 numbers in each sublist. Then we find the max and min from the sublist and forward it to the larger sublist consisting of two sublists. Each sublist is denoted by the following notation:-

where,

si denotes the starting index of the sublist ei denotes the ending index of the sublist max denotes the maximum number of the sublist min denotes the minimum number of the sublist

The following figure clearly explains the logic:-

Now we shall develop the algorithm for this logic. While doing so, we consider three different cases, Case 1: If there is only element in the list Case 2: If there are two elements in the list Case 3: If there are more than two elements in the list If there are more than two elements in the list, we use recursion in which we call the algorithm for the sublists and then combine the results obtained from the sublists.

MaxMin(a,n,max,min) { i:=1; j:=n; if(i==j) then { max:=min:=a[i]; } else if(i==j-1) then { if(a[i]>a[j]) then { max:=a[i]; min:=a[j]; } else { max:=a[j]; min:=a[i]; } } 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; } } In this algorithm, the time complexity(T(n)) is: T(n/2) + T(n/2) + 2 if n>2 (T(n/2) for each sublist and 2 for comparisons done between max-max1 and min-min1) 1 if n=2 (only 1 comparison is done) 0 if n=1 (no comparison) Now, T(n) = 2T(n/2) + 2 T(n/2) = 2T(n/4) + 2 Therefore, T(n) = 22T(n/22) + 22 + 21 Implies that, T(n) = 2k-1T(n/2k-1) + 2k-1 + 2k-2 + ........... + 21 Now, 2k-1 + 2k-2 + ........... + 21 is a Geometric Progression. for 2 steps for k-1 steps

Therefore, 2k-1 + 2k-2 + ........... + 21 = a(rn-1) = 2(2k-1-1) = 2k-2 r-1 2-1 T(n) = 2k-1T(n/2k-1) + 2k - 2 Let n = 2k Therefore, T(2k) = 2k-1T(2k/2k-1) + 2k - 2 = 2k-1T(2) + 2k - 2 = 2k-1(1) + 2k - 2 = 2k-1 + 2k - 2 = 2k + 2k - 2 2 = 3.2k - 2 2 We know, 2k = n Therefore, T(n) = 3n 2 2 Comparing the divide and conquer algorithm with the traditional iterative approach. Without divide and conquer, T(n) = 2(n-1) for n=10 T(n) = 18 Using divide and conquer, T(n) = 3n 2 2 for n = 10 T(n) = 13 Increase in performance = 18-13 * 100 18 = 5 * 100 18 = 27.78% Therefore it is very clear that the algorithms using divide and conquer approach are way more efficient than the traditional iterative algorithms.

* The algorithms of sorting and searching have been given in the Sorting & Searching file.

You might also like