G DAA-Unit-II

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

Unit -II

Divide and conquer: General method,


Applications:
Binary search,
Quick sort,
Merge sort,
Strassen’s matrix multiplication
Divide and Conquer Technique
General Method:
 The Divide and Conquer Technique splits n inputs into
k subsets , 1< k ≤ n, resulting k subproblems.

 These subproblems will be solved and then combined


by using a separate method to get a solution to the
whole problem.

 If the subproblems are large, then the Divide and


Conquer Technique will be reapplied.

 Generally, subproblems coming from a Divide and


Conquer Technique are of the same type as the original
problem.
 The reapplication of the Divide and Conquer
Technique is naturally expressed by a recursive
algorithm.

 Now smaller and smaller problems of the same kind


are generated until subproblems that are small enough
to solve without splitting further.
Control Abstraction / General Method for Divide
and Conquer Technique
Algorithm DAndC(p)
{
if Small(p) then return s(p);
else
{
divide p into smaller problems p1,p2,…….,pk, k≥1;
Apply DAndC to each of these subproblems;
return Combine(DAndC(p1), DAndC(p2),……,DAndC(pk));

}
}
 The Time Complexity of many divide-and-conquer
algorithms is given by recurrences of the form

c n small
T(n) = aT(n/b)+f(n) Otherwise

 Where T(n) is the time for DAndC on any input of size n


 The function f(n) is the time for dividing p and combining
the solutions of subproblems
 Where a, b and c are known constants, and n is a power of
b (i.e., n = bk)
Applications
1.Binary search Algorithm
Recursive Algorithm ( Divide and Conquer Technique)
Algorithm BinSrch (a, low, high, x)
//Given an array a [ low : high ] of elements in increasing
//order,1≤low≤high,determine whether x is present, and
//if so, return j such that x=a[j]; else return 0.
{
if( low = high ) then // If small(P)
{
if( x=a[low] ) then return low;
else return 0;
}
else
{
//Reduce p into a smaller subproblems.
mid:= (low+high)/2
if( x = a[mid] ) then return mid;
else if ( x<a[mid] ) then
return BinSrch(a, low, mid-1, x);
else
return BinSrch(a, mid+1, high, x);
}
}
Time complexity of Binary Seaych
 If the time for diving the list is a constant, then the
computing time for binary search is described by the
recurrence relation

T(n) = c1 n=1, c1 is a constant


1*T(n/2) + c2 n>1, c2 is a constant

Assume n = 2k, then


T(n) = T(n/2) + c2
=T(n/4)+c2+c2
=T(n/8) +c2+c2+c2
…..
…..
= T( n / 2k) + c2+c2+c2+ ………..k times
= T(1)+ kc2
= c1+kc2 =c1+ logn*c2 = O(logn)
Time Complexity of Binary Search
Successful searches:
best average worst
O(1) O(log n) O(log n)

Unsuccessful search:
O(log n)
2. Merge Sort
1. Base Case, solve the problem directly if it is
small enough(only one element).

2. Divide the problem into two or more similar and


smaller subproblems.

3. Recursively solve the subproblems.

4. Combine solutions to the subproblems.


Merge Sort: Idea
Divide A into
two halves A FirstPart SecondPart
Recursively Recursively
sort sort
FirstPart SecondPart

Merge

A is sorted!
Merge-Sort(A, 0, 7)
Divide A 6 2 8 4 3 7 5 1

A: 6 2 8 4 3 7 5 1
Merge-Sort(A, 0, 7)
Merge-Sort(A, 0, 3) , divide
A: 3 7 5 1

6 2 88 4
4
Merge-Sort(A, 0, 7)
Merge-Sort(A, 0, 1) , divide
A: 3 7 5 1

8 4

6 2
2
Merge-Sort(A, 0, 7)
Merge-Sort(A, 0, 0) , base case
A: 3 7 5 1

8 4

6
Merge-Sort(A, 0, 7)
Merge-Sort(A, 0, 0), return
A: 3 7 5 1

8 4

6 2
Merge-Sort(A, 0, 7)
Merge-Sort(A, 1, 1) , base case
A: 3 7 5 1

8 4

2
Merge-Sort(A, 0, 7)
Merge-Sort(A, 1, 1), return
A: 3 7 5 1

8 4

6 2
Merge-Sort(A, 0, 7)
Merge(A, 0, 0, 1)
A: 3 7 5 1

8 4

2 6
Merge-Sort(A, 0, 7)
Merge-Sort(A, 0, 1), return
A: 3 7 5 1

2 6 8 4
Merge-Sort(A, 0, 7)
Merge-Sort(A, 2, 3) , divide
A: 3 7 5 1

2 6

8 4
Merge-Sort(A, 0, 7)
Merge-Sort(A, 2, 2), base case
A: 3 7 5 1

2 6

8
Merge-Sort(A, 0, 7)
Merge-Sort(A, 2, 2), return
A: 3 7 5 1

2 6

8 4
Merge-Sort(A, 0, 7)
Merge-Sort(A, 3, 3), base case
A:

2 6

4
Merge-Sort(A, 0, 7)
Merge-Sort(A, 3, 3), return
A: 3 7 5 1

2 6

8 4
Merge-Sort(A, 0, 7)
Merge(A, 2, 2, 3)
A: 3 7 5 1

2 6

4 8
Merge-Sort(A, 0, 7)
Merge-Sort(A, 2, 3), return
A: 3 7 5 1

2 6 4 8
Merge-Sort(A, 0, 7)
Merge(A, 0, 1, 3)
A: 3 7 5 1

2 4 6 8
Merge-Sort(A, 0, 7)
Merge-Sort(A, 0, 3), return
A: 2 4 6 8 3 7 5 1
Merge-Sort(A, 0, 7)
Merge-Sort(A, 4, 7)
A: 2 4 6 8

3 7 5 1
Merge-Sort(A, 0, 7)
Merge (A, 4, 5, 7)
A: 2 4 6 8

1 3 5 7
Merge-Sort(A, 0, 7)
Merge-Sort(A, 4, 7), return
A: 2 4 6 8 1 3 5 7
Merge-Sort(A, 0, 7)
Merge-Sort(A,
Merge(A, 0, 3, 0,
7) 7), done!
A: 1 2 3 4 5 6 7 8
Ex:- [179, 254, 285, 310, 351, 423, 450, 520, 652, 861]

Tree of calls of merge sort

1,10

1,5 6,10

1,3 4,5 6,8 9,10

1,2 3,3 4,4 5,5 6,7 8,8 9,9 10,10

1,1 2,2 6,6 7,7


Merge Sort: Algorithm
Algorithm MergeSort (low, high)
// sorts the elements a[low],…,a[high] which are in the global array
//a[1:n] into ascending order ( increasing order ).
// Small(p) is true if there is only one element to sort. In this case the list is
// already sorted.

{ if ( low<high ) then // if there are more than one element

{
mid ← (low+high)/2; Recursive Calls
MergeSort(low,mid);
MergeSort(mid+1, high);
Merge(low, mid, high);

}
}
Merge-Sort: Merge Example
low mid high
A: 2
5 3
5 7 28
15 8 30
1 4
6 5 14
10 6

B: 5 5 15 28 30 6 10 14

L: R:
3 5 15 28 6 10 14 22
Merge-Sort: Merge Example

A: 5 5 15 28 30 6 10 14
B:
3
1 5 15 28 30 6 10 14

i=low

L: low mid R: high

3
2 15
3 28
7 30
8 6
1 10
4 14
5 22
6

h=low j=mid+1
Merge-Sort: Merge Example

A: 5 5 15 28 30 6 10 14
B:
1 2
5 15 28 30 6 10 14

L: low mid R: high

3
2 5
3 15
7 28
8 6
1 10
4 14
5 22
6

h j
Merge-Sort: Merge Example

A: 5 5 15 28 30 6 10 14
B:
1 2 3 28 30
15 6 10 14

L: low mid R: high

2 3 7 8 6
1 10
4 14
5 22
6

h j
Merge-Sort: Merge Example

A: 5 5 15 28 30 6 10 14
B:
1 2 3 4 6 10 14

L: low mid R: high

2 3 7 8 6
1 10
4 14
5 22
6

h j
Merge-Sort: Merge Example

A: 5 5 15 28 30 6 10 14
B:
1 2 3 4 5 6 10 14

L: low mid R: high

2 3 7 8 6
1 10
4 14
5 22
6

h j
Merge-Sort: Merge Example

A: 5 5 15 28 30 6 10 14
B:
1 2 3 4 5 6 10 14

L: low mid R: high

2 3 7 8 6
1 10
4 14
5 22
6

h j
Merge-Sort: Merge Example

A: 5 5 15 28 30 6 10 14
B:
1 2 3 4 5 6 7 14

L: low mid R: high

2 3 7 8 6
1 10
4 14
5 22
6

h j
Merge-Sort: Merge Example

A: 5 5 15 28 30 6 10 14
B:
1 2 3 4 5 6 7 8
14

L: low mid R: high

3
2 5
3 15
7 28
8 6
1 10
4 14
5 22
6

h j
Merge-Sort: Merge Example

A: 5 5 15 28 30 6 10 14
B:
1 2 3 4 5 6 7 8

L: low mid R: high

3
2 5
3 15
7 28
8 6
1 10
4 14
5 22
6

h j
A:
5 5 15 28 30 6 10 14

B: 1 2 3 4 5 6 7 8
Algorithm Merge(low,mid,high)
// a[low:high] is a global array containing two sorted subsets in a[low:mid]
// and in a[mid+1:high]. The goal is to merge these two sets into a single
// set residing in a[low:high]. b[ ] is a temporary global array.
{
h:=low; j:=mid+1; i:=low;
while( h ≤ mid ) and ( j ≤ high ) do
{
if( a[h] ≤ a[j] ) then
{
b[i]:=a[h]; h:=h+1;
}
else
{
b[i]:=a[j]; j:=j+1;
}
i:=i+1;
}
if( h > mid ) then
for k:=j to high do
{
b[i] := a[k]; i:= i+1;
}
else
for k:=h to mid do
{
b[i] := a[k]; i:= i+1;
}
for k:= low to high do a[k]:=b[k];
}
Merge-Sort Analysis
n

n/2 n/2

n/4 n/4 n/4 n/4

2 2 2
Merge-Sort Time Complexity
If the time for the merging operation is proportional to n, then the
computing time for merge sort is described by the recurrence relation

c1 n=1, c1 is a constant
T(n) =
2T(n/2) + c2n n>1, c2 is a constant

Assume n=2k, then

T(n) =2T(n/2) + c2n


=2(2T(n/4)+c2n/2)+c2n
=4T(n/4)+2c2n

…..
…..
=2k T(1)+ kc2n
= c1n+c2nlogn = = O(nlogn)
Summary
• Merge-Sort
– Most of the work done in combining the
solutions.
– Best case takes o(n log(n)) time
– Average case takes o(n log(n)) time
– Worst case takes o(n log(n)) time
3. Quick Sort
• Divide:
• Pick any element as the pivot, e.g, the first
element
• Partition the remaining elements into
FirstPart, which contains all elements < pivot
SecondPart, which contains all elements > pivot

• Recursively sort FirstPart and SecondPart.


• Combine: no work is necessary since sorting is done in
place.
pivot divides a into two sublists x and y.

4 2 7 8 1 9 3 6 5
pivot

x y
The whole process

4 2 7 8 1 9 3 6 5

2 1 3 4 7 8 9 6 5

1 2 3 6 5 7 8 9

1 3 5 6 8 9

5 9
Process:
Keep going from left side as long as a[ i ]<pivot and from the right
side as long as a[ j ]>pivot

pivot 85 24 63 95 17 31 45 98

i j

85 24 63 95 17 31 45 98

i j

85 24 63 95 17 31 45 98

i j

85 24 63 95 17 31 45 98

i j
If i<j interchange ith and j th elements and
then Continue the process.

85 24 63 45 17 31 95 98

i j

85 24 63 45 17 31 95 98

i j

85 24 63 45 17 31 95 98

i
85 24 63 45 17 31 95 98

85 24 63 45 17 31 95 98

j i

If i ≥j interchange jth and pivot elements


and then divide the list into two sublists.
35 24 63 45 17 85 95 98
j

Two sublists:

35 24 63 45 17 95 98
85

Recursively sort
FirstPart and SecondPart
QickSort( low, j-1 ) QickSort( j+1,high )
Quick Sort Algorithm :
Algorithm QuickSort(low,high)
//Sorts the elements a[low],…..,a[high] which resides
//in the global array a[1:n] into ascending order;
// a[n+1] is considered to be defined and must ≥ all the
// elements in a[1:n].
{
if( low< high ) // if there are more than one element
{ // divide p into two subproblems.
j :=Partition(low,high);
// j is the position of the partitioning element.
QuickSort(low,j-1);
QuickSort(j+1,high);
// There is no need for combining solutions.
}
}
Algorithm Partition(low, high)
{
pivot:= a[ low ]; i:=low; j:= high+1;
while( i < j ) do
{
i++;
while( a[ i ] < pivot ) do
i++;
j--;
while( a[ j ] > pivot ) do
j--;

if ( i < j ) then Interchange(i, j ); // interchange ith and


} // jth elements.

Interchange(low, j ); return j; // interchange pivot and jth element.


}
Algorithm interchange (x,y )
{
temp:=a[x];
a[x]:=a[y];
a[y]:=temp;
}
Time complexity analysis
• The time required to sort n elements using quicksort involves 3
components.
– Time required for partitioning the array, which is roughly
proportional to n.
– Time required for sorting lower subarray.
– Time required for sorting upper subarray.
• Assume that there are k elements in the lower subarray.
• Therefore,

c1 n=1, c1 is a constant
T(n) =
T(k) + T(n-k-1) +c2n n>1, c2 is a constant
A worst/bad case
It occurs if the list is already in sorted order
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9
3 4 5 6 7 8 9
4 5 6 7 8 9
5 6 7 8 9 O(n2)
6 7 8 9
7 8 9
8 9
9
Worst/bad Case
n cn

n-1 c(n-1)

n-2 c(n-2)

3c
3

2 2c
1c
1
contd...
• In the worst case, the list is always partitioned into
two sublists in which one of them is always empty.
Thus , for the worst case analysis,

T(n) = T(n-1) +c2n n > 1, c2 is a constant

= T(n-1) +c2n
= T(n-2) + c2 ( n -1)+ c2n
= T(n-3) + c2 ( n -2) + c2( n -1)+c2n
…..
…..
= n(n+1)/2 = ( n2+n)/2= O(n2)
A Best/Good case
• It occurs only if each partition divides the list into two
equal size sublists.

O(n logn)
Best/Good Case
n

n/2 n/2

n/4 n/4 n/4 n/4

2 2 2
c1 n=1, c1 is a constant
T(n) =
2T(n/2) + c2n n>1, c2 is a constant

Assume n=2k, then

T(n) =2T(n/2) + c2n


=2(2T(n/4)+c2n/2)+c2n
=4T(n/4)+2c2n

…..
…..
=2k T(1)+ kc2n
= c1n+c2nlogn = = O(nlogn)
Summary
• Quick-Sort
– Most of the work done in partitioning
– Best case takes O(n log(n)) time
– Average case takes O(n log(n)) time
– Worst case takes O(n2) time
4.Strassen’s Matrix Multiplication
Basic Matrix Multiplication
Let A an B two n×n matrices. The product C=AB is also an n×n matrix.

void matrix_mult (){


for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
for(k=1; k<=n; k++){
C[i,j]=C[i,j]+A[i,k]+B[k,j];
}
}}

Time complexity of above algorithm is


T(n)=O(n3)
Divide and Conquer Technique
• We want to compute the product C=AB, where each of A,B,
and C are n×n matrices.
• Assume n is a power of 2.
• If n is not a power of 2, add enough rows and columns of
zeros.
• We divide each of A,B, and C into four n/2×n/2 matrices,
rewriting the equation C=AB as follows:
Then, A11 A12 B11 B12

c11 c12
1 1 2 2  5 5 6 6
C11=A11B11+A12B21
 C11 C12   1 1 2 2  5 5 6 6
C12=A11B12+A12B22 C   
C 21 C 22 3 3 4 4  7 7 8 8
C21=A21B11+A22B21 c21 c22 3 3 4 4 7 7 8 8 
C22=A21B12+A22B22 A
21 22 21A B22 B

• Each of these equations specifies two multiplications of size n/2×n/2


and the addition of their n/2×n/2 products.
• We can derive the following recurrence relation for the time T(n) to
multiply two n×n matrices:

T(n)= c1 if n<=2
8T(n/2)+ c2n2 if n>2

T(n) = O(n3)

• This method is not faster than the ordinary method.


T(n)= 8T(n/2)+ c2n2
=8 8T(n/4)+ c2(n/2)2 + c 2 n2

= 82 T(n/4)+ c22n2 + c 2 n2

=82 8T(n/8)+ c2(n/4)2 + c22n2 + c2n2

=83 T(n/8)+ c24n2 + c22n2 + c2n2


:
=8kT(1)+ ………………+ c24n2 + c22n2 + c2n2

= 8log n c + c 2 n2
2 1
.
8
log
=n 2 c1 + c n2 = n3 c1+ c2n2 = O(n3 )
Strassen’s method
• Matrix multiplications are more expensive than matrix
additions or subtractions( O(n3) versus O(n2)).

• Strassen has discovered a way to compute the multiplication


using only 7 multiplications and 18 additions or subtractions.

• His method involves computing 7 n/2×n/2 matrices


M1,M2,M3,M4,M5,M6, and M7, then cij’s are calculated using
these matrices.
Formulas for Strassen’s Algorithm
M1 = (A11 + A22)  (B11 + B22)
M2 = (A21 + A22)  B11
M3 = A11  (B12 – B22)
M4 = A22  (B21 – B11)
M5 = (A11 + A12)  B22
M6 = (A21 – A11)  (B11 + B12)
M7 = (A12 – A22)  (B21 + B22)

C11=M1 + M4 - M5 + M7
C12= M3 + M5
C21= M2 + M4
C22=M1 + M3 - M2 + M6
C11 C12 A11 A12 B11 B12
= *
C21 C22 A21 A22 B21 B22

M1 + M4 - M5 + M7 M3 + M5
=
M2 + M4 M1 + M3 - M2 + M6

The resulting recurrence relation for T(n) is

T(n)= c1 n<=2
7T(n/2) +c2n2 n>2
T(n)= 7kT(1) + c2n2 1+ 7/4 + (7/4)2 + (7/4) 3+……………..+ (7/4)k-1

..
.

= 7log n c +c2 n2 (7/4)log2n


2 1

=c1nlog27 + c2nlog24 ( n log27-log24 )

= c1nlog27 + c2( nlog24 +log27 - log24 ) = c1nlog27 + c2nlog27

=c nlog27 = O(nlog27) ~ O( n2.81)

You might also like