Y23!02!2119divide and Conquer
Y23!02!2119divide and Conquer
2
1 n=1
e.g. f(n)= f(n-1)+n n>1
return temp;
} where c1 and c2 are constants
4
Solving recurrences (obtain the asymptotic bounds on the
solution)
5
Divide-and-conquer approach usually gives a recursive
algorithm and the time complexity of the algorithm is
usually formulated as a recursive function. Solving the
recursive function will give the time complexity of the
algorithm.
ØDivide problem into subproblems
ØConquer subproblems recursively
ØCombine subproblem solutions
How?
1 2 3
7
Solve it recursively:
Base case: if there is only one disk.
move disk from peg 1 to peg 3
1 2 3
8
Move top (n-1) disks from peg 1 to peg 2
1 2 3
Move the largest disks from peg 1 to peg 3
1 2 3
Move (n-1) disks from peg 2 to peg 3
1 2 3 9
TofH(A,B,C,n) // source peg: A, destination peg: C
{ To call the program:
if (n=1) TofH(1, 2,3, 3) // 3 disks
move disk from A to C
else {
What is the number of moves?
TofH(A,C,B,n-1);
move disk from A to C; Let f(n) be the number of moves
TofH(B,A,C,n-1);
f(n) = 1 n=1
} 2f(n-1)+1 n>1
}
f(n) = 2f(n-1) + 1
= 2(2f(n-2)+1) + 1 = 22f(n-2) + 2 + 1
= 22(2f(n-3)+1) + 2 + 1 = 23f(n-3) + 22 + 2 + 1
= ….
= 2n-1f(1) + 2n-2 + … + 2 + 1
= 2n-1 + 2n-2 + … + 2 + 1 How about time
= 2n - 1 complexity of
the algorithm?
10
Review: Divide-and-conquer approach
(1) In order to obtain a solution for input size n, we assume
the solution(s) for smaller n (subproblem) is available,
then construct the final solution from these solutions.
13
We can do something similar here:
problem: finding largest in n numbers
subproblem: finding largest in first (n-1) numbers
14
largest1(A[1..n]) {
if (n = 1) return A[1]; Execution:
else e.g. Ans: 60
x = largest1(A[1..n-1]); largest1([4, 60, 21, 3, 5])
if (x > A[n]) return x;
else return A[n];
largest1([4, 60, 21, 3]) return
}
60
Time complexity: largest1([4, 60, 21])
return
T(n) = c1 if n =1;
60
T(n) = T(n-1) + c2 for n > 1. largest1([4, 60])
return 60
=> T(n) = O(n). largest1([4])
Base case: return 4
15
Example: Find the largest number from a given set of n numbers
16
largest2(A[1..n]) // for simplicity, assume n is a power of 2
{
If (n = 1)
return A[1];
else {
x1 = largest2(A[1..n/2]);
x2 = largest2(A[n/2+1..n]);
if (x1 > x2)
return x1;
else
return x2;
}
}
Let T(n) be the time complexity of largest2.
T(1) = c1
T(n) = 2T(n/2) + c2 where c1, c2: positive constants
Þ T(n) = O(n)
17
largest2(A[1..n])
{ e.g. 14 65 34 33 7 56 100 20
If (n = 1)
return A[1]; 14 65 34 33 7 56 100 20
else {
x1 = largest2(A[1..n/2]); 14 65 34 33
x2 = largest2(A[n/2+1..n]);
if (x1 > x2)
return x1; 14 65 34 33
else Base case
return x2;
}
}
Remark: This problem, of course,
can be solved using a more
straightforward approach, so it is
only for illustration purpose
18
Note: the following straightforward approach will give
an algorithm with the same time complexity.
largest(A[1..n])
{
maximum = A[1];
for i = 2 to n do
if (A[i] > maximum)
maximum = A[i];
return maximum;
}
19
Remarks:
Theorem :
If T(n) = a T(n/b) + f(n) and f(n) = Q(np), then
Q( n p ) if a < b p
T(n) = Q( n p log n ) if a = b p where a ³1, b ³ 2, p ³ 0
Q( n logb a ) if a > b p
20
Note: recursion may not always be a good solution
The Fibonacci numbers
F1 = 1
Definition: F2 = 1
Fi = Fi-1 + Fi-2 for i > 2
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, …..
Problem: Generate the nth Fibonacci number
Algorithm 1: Direct implementation of recursive definition
21
Claim: T(n) > 2(n-2)/2
Proof: T(n) > T(n-1) + T(n-2)
> T(n-2) + T(n-3) + T(n-2)
= 2T(n-2) + T(n-3)
> 2T(n-2)
> 2(2T(n-4)) = 4T(n-4)
> 4(2T(n-6)) = 8T(n-6)
> ....
> 2k T(n-2k)
1
Note: Fn can be shown to be @ 1.618n T(n) = Q(1.618n)
5
22
In the recursive version, we need to
Can we do better?
recompute FIB1(n) values for many n’s.
FIB2(n) {
if (n <=2) then
return 1
else
p=1 Time Complexity?
q=1
Q(n)
for i = 3 to n do
r=p+q
p=q
q=r Q: Do you think we can
return r still do better?
}
23
Revisit: Computing Fibonacci Numbers
Power1(A, n) { // n ³ 1; A: 2 ´ 2 matrix
if (n = 1)
return A;
else
return 2-Multiply(A, Power1(A, n-1)); // details of 2-
} // Multiply omitted
Complexity:
2-Multiple takes constant time.
Power1(A, n) takes O(n) time.
24
2nd Attempt:
[Hint: if n is always a power of 2, can you design a better
(faster) algorithm?]
Power3(A, n) { // n ³ 1; A: 2 ´ 2 matrix
if (n = 1)
return A;
else Complexity: O(log n)
if (n is odd)
B = Power3(A, (n-1)/2);
return(2-Multiply(A, 2-Multiply(B, B));
else
B = Power3(A, n/2);
return(2-Multiply(B, B));
}
26
How this relates to our problem (computing the Fibonacci #)?
[MIT, Ex31-3, p.981]
0 1
1 1
27
One more example: The maximum subarray problem
Given an array A[1..n] of integers, find a nonempty,
contiguous subarray of A whose values have the largest sum.
e.g. -4 6 -3 -1 6 1 -2
28
1st attempt (brute-force approach)
Idea: check all possible subarrays
Max_subarray1(A, n){
max = -¥
for i = 1 to n
for j = i to n
sum = 0;
for k = i to j
sum = sum + A[k];
if sum > max
max = sum;
ans = (i, j, max);
return ans;
Time complexity: O(n3)
Can we do better?
29
This brute-force algorithm can be further improved due to
many redundant addition
i/j 1 2 3 4 …
1 1
2 2 1
3 3 2 1
4 4 3 2 1 ….
….. ….. ….. ….. ….. ….
redundant
When i = 1; j = 1, we compute sum = A[1]
When i = 1; j = 2, we compute sum = A[1] + A[2]
When i = 1; j = 3, we compute sum = A[1] + A[2] + A[3]
When i = 1; j = 4, we compute sum = A[1] + A[2] + A[3] + A[4]
30
2nd attempt (brute-force approach with improvement)
Idea: check all possible subarrays, faster computation of sum
Time complexity:
O(n2)
Can we do better?
31
3rd attempt: How about divide-and-conquer approach?
middle
You know how to find the maximum subarray in the 1st half
You know how to find the maximum subarray in the 2nd half
What else you need to find?
e.g. 3 -1 3 -5 4 5 -8 2 0 4
We need to find also the maximum subarray across the mid point!
32
Finding the max subarray across the middle:
Idea:
Search for A[i, n/2] for 1 £ i £ n/2 middle Search for A[,
with maximum sum. n/2+1, j] for
n/2+1 £ j £ n
max = -¥; sum = 0;
with maximum
for i from n/2 downto 1
sum.
sum = sum + A[i];
if sum > max
max = -¥; sum = 0;
max = sum; ans = i
for j from n/2+1 to n
return (ans, max)
sum = sum + A[i];
if sum > max
max = sum; ans = j
Combine these two results return (ans, max)
It takes O(n) time.
33
Max_subarray3(A, p, q) {
(i1, j1, max1) = Max_subarray3(A, p, p+q/2);
(i2, j2, max2) = Max_subarray3(A, p+q/2+1, q);
(i3, j3, max3) = Max_subarray_middle(A, p, q);
if max 1 > max 2
if max 1 > max 3
return (i1, j1, max1) O(n) time
else
return(i3, j3, max3)
else
if max2 > max3
return(i2, j2, max2)
else
return(i3, j3, max3)
}
Time complexity: T(n) = 2T(n/2) + cn for n > 1 (n = 2k)
=> T(n) = O(n log n)
Can we do better?
34
Exercises
35
Generating Combinatorial Objects