ALGORITHMICS - West University of Timișoara

Download Report

Transcript ALGORITHMICS - West University of Timișoara

LECTURE 8:
Divide and conquer
Algorithmics - Lecture 8-9
1
In the previous lecture we saw …
… how to analyze recursive algorithms
– write a recurrence relation for the running time
– solve the recurrence relation by forward or backward substitution
… how to solve problems by decrease and conquer
– decrease by a constant/variable
– decrease by a constant/variable factor
… sometimes decrease and conquer lead to more efficient algorithms than
brute force techniques
Algorithmics - Lecture 8-9
2
Outline
• Basic idea of divide and conquer
• Examples
• Master theorem
• Mergesort
• Quicksort
Algorithmics - Lecture 8-9
3
Basic idea of divide and conquer
• The problem is divided in several smaller instances of
the same problem
– The subproblems must be independent (each one will be
solved at most once)
– They should be of about the same size
• These subproblems are solved (by applying the same
strategy or directly – if their size is small enough)
– If the subproblem size is less than a given value (critical size) it
is solved directly, otherwise it is solved recursively
• If necessary, the solutions obtained for the
subproblems are combined
Algorithmics - Lecture 8-9
4
Basic idea of divide and conquer
Divide&conquer (n)
IF n<=nc THEN <solve P(n) directly to obtain r>
ELSE
<Divide P(n) in P(n1), …, P(nk)>
FOR i←1,k DO
ri ← Divide&conquer(ni)
ENDFOR
r ← Combine (r1, … rk)
ENDIF
RETURN r
Algorithmics - Lecture 8-9
5
Example 1
Compute the maximum of an array x[1..n]
n=8, k=2
32751645
3275
32
75
37
1645
Divide
Conquer
Combine
76
16
45
65
7
Algorithmics - Lecture 8-9
6
Example 1
Algorithm:
Efficiency analysis
Maximum(x[left..right])
IF n=1 then RETURN x[left]
ELSE
m ←(left+right) DIV 2
max1 ← maximum(x[left..m])
max2 ← maximum(x[m+1..right])
if max1>max2
THEN RETURN max1
ELSE RETURN max2
ENDIF
ENDIF
Problem size: n
Dominant operation: comparison
Recurrence relation:
0,
n=1
T(n)=
Algorithmics - Lecture 8-9
T([n/2])+T(n-[n/2])+1, n>1
7
Example 1
Backward substitution:
0,
n=1
T(n)=
T([n/2])+T(n-[n/2])+1, n>1
Particular case: n=2m
0,
n=1
T(2m) = 2T(2m-1)+1
T(2m-1)=2T(2m-2)+1 |* 2
…
T(2)=2T(1)+1
|* 2m-1
T(1)=0
---------------------------T(n)=1+…+2m-1=2m-1=n-1
T(n)=
2T(n/2)+1, n>1
Algorithmics - Lecture 8-9
8
Example 1
0,
n=1
T(n)=
T([n/2])+T(n-[n/2])+1, n>1
Particular case:
n=2m => T(n)=n-1
General case.
(a) Proof by complete mathematical
induction
First step. n=1 =>T(n)=0=n-1
Inductive step.
Let us suppose that T(k)=k-1 for all
k<n.
Then
T(n)=[n/2]-1+n-[n/2]-1+1=n-1
Thus T(n) =n-1 =>
T(n) belongs to Θ(n).
Algorithmics - Lecture 8-9
9
Example 1
General case.
(b) Smoothness rule
If T(n) belongs to (f(n)) for n=bm
T(n) is eventually nondecreasing (for n>n0 it is nondecreasing)
f(n) is smooth (f(cn) belongs to (f(n)) for any positive constant c)
then T(n) belongs to (f(n)) for all n
Remarks.
•
All functions that do not grow too fast are smooth (polynomial and
logarithmic)
•
For our example (“maximum” algorithm): T(n) is eventually
nondecreasing, f(n)=n is smooth, thus T(n) is from (n)
Algorithmics - Lecture 8-9
10
Example 2 – binary search
Check if a given value, v, is an element of an increasingly sorted array,
x[1..n] (x[i]<=x[i+1])
x1 … xm-1 xm xm+1 … xn
v<xm
xm=v
x1 … xm’-1 xm’ xm’+1 … xm-1
True
v>xm
xm+1 … xm’-1 xm’ xm’+1 …
xn
xm=v
True
xleft…..xright
left>right (empty array)
False
Algorithmics - Lecture 8-9
11
Example 2 – binary search
Recursive variant:
Remarks:
nc=0
k=2
binsearch(x[left..right],v)
IF left>right THEN RETURN False
ELSE
m ←(left+right) DIV 2
Only one of the two
IF v=x[m] THEN RETURN True
subproblems is
ELSE
solved
IF v<x[m]
THEN RETURN binsearch(x[left..m-1],v)
This is rather a
ELSE RETURN binsearch(x[m+1..right],v)
decrease &
ENDIF
conquer approach
ENDIF
ENDIF
Algorithmics - Lecture 8-9
12
Example 2 – binary search
First iterative variant:
binsearch(x[1..n],v)
left ← 1
right ← n
WHILE left<=right DO
m ←(left+right) DIV 2
IF v=x[m] THEN RETURN True
ELSE
IF v<x[m]
THEN right ← m-1
ELSE left ← m+1
ENDIF / ENDIF/ ENDWHILE
RETURN False
Second iterative variant:
binsearch(x[1..n],v)
left ← 1
right ← n
WHILE left<right DO
m ←(left+right) DIV 2
IF v<=x[m]
THEN right ← m
ELSE left ← m+1
ENDIF / ENDWHILE
IF x[left]=v THEN RETURN True
ELSE RETURN False
ENDIF
Algorithmics - Lecture 8-9
13
Example 2 – binary search
Second iterative variant:
binsearch(x[1..n],v)
left ← 1
right ← n
WHILE left<right DO
m ←(left+right) DIV 2
IF v<=x[m]
THEN right ← m
ELSE left ← m+1
ENDIF / ENDWHILE
IF x[left]=v THEN RETURN True
ELSE RETURN False
ENDIF
Correctness
Precondition: n>=1
Postcondition:
“returns True if v is in x[1..n] and
False otherwise”
Loop invariant: “if v is in x[1..n]
then it is in x[left..right]”
(i)
(ii)
(iii)
left=1, right=n => the loop
invariant is true
It remains true after the
execution of the loop body
when right=left it implies the
postcondition
Algorithmics - Lecture 8-9
14
Example 2 – binary search
Second iterative variant:
Efficiency:
binsearch(x[1..n],v)
left ← 1
right ← n
WHILE left<right DO
m ←(left+right) DIV 2
IF v<=x[m]
THEN right ← m
ELSE left ← m+1
ENDIF / ENDWHILE
IF x[left]=v THEN RETURN True
ELSE RETURN False
ENDIF
Worst case analysis (n=2m)
1
n=1
T(n)=
T(n/2)+1 n>1
T(n)=T(n/2)+1
T(n/2)=T(n/4)+1
…
T(2)=T(1)+1
T(1)=1
T(n)=lg n+1
Algorithmics - Lecture 8-9
O(lg n)
15
Example 2 – binary search
Remarks:
•
By applying the smoothness rule one obtains that this result is
true for arbitrary values of n
•
The first iterative variant and the recursive one also belong to
O(lg n)
Algorithmics - Lecture 8-9
16
Master theorem
Let us consider the following recurrence relation:
T0
n<=nc
T(n)=
kT(n/m)+TDC(n)
n>nc
If TDC(n) belongs to (nd) (d>=0) then
T(n)
belongs to
(nd)
if k<md
(nd lgn) if k=md
(nlgk/lgm) if k>md
A similar result holds for O and Ω notations
Algorithmics - Lecture 8-9
17
Master theorem
Usefulness:
•
•
•
•
It can be applied in the analysis of divide & conquer algorithms
It avoids solving the recurrence relation
In most practical applications the running time of the divide and
combine steps has a polynomial order of growth
It gives the efficiency class but it does not give the constants
involved in the running time
Algorithmics - Lecture 8-9
18
Master theorem
Example 1: maximum computation:
k=2 (division in two subproblems, both should be solved)
m=2 (each subproblem size is almost n/2)
d=0 (the divide and combine steps are of constant cost)
Since k>md by applying the third case of the master theorem we obtain
that T(n) belongs to (nlg k/lg m)= (n)
Example 2: binary search
k=1 ( only one subproblem should be solved)
m=2 (the subproblem size is almost n/2)
d=0 (the divide and combine steps are of constant cost)
Since k=md by applying the second case of the master theorem we
obtain that T(n) belongs to O(nd lg(n))= (lg n)
Algorithmics - Lecture 8-9
19
Efficient sorting
•
•
Elementary sorting methods belong to O(n2)
Idea to increase the efficiency of sorting process:
–
divide the sequence in contiguous subsequences (usually two)
–
sort each subsequence
–
combine the sorted subsequences to obtain the sorted
sequence
Merge sort
Quicksort
Divide
By position
Combine
Merging
By value
Concatenation
Algorithmics - Lecture 8-9
20
Merge sort
Basic idea:
•
Divide x[1..n] in two subarrays x[1..[n/2]] and x[[n/2]+1..n]
•
Sort each subarray
•
Merge the elements of x[1..[n/2]] and x[[n/2]+1..n] and construct
the sorted temporary array t[1..n] . Transfer the content of the
temporary array in x[1..n]
Remarks:
•
Critical value: 1 (an array containing one element is already
sorted)
•
The critical value can be larger than 1 (e.g.10) and for the
particular case one applies a basic sorting algorithm (e.g.
insertion sort)
Algorithmics - Lecture 8-9
21
Merge sort
15834210
1583
Divide
4210
15
Simple case
1
83
5
8
15
42
3
4
38
10
2
1
24
0
01
Merging
1358
0124
01123458
Algorithmics - Lecture 8-9
22
Mergesort
Algorithm:
mergesort(x[left..right])
IF left<right THEN
m ←(left+right) DIV 2
x[left..m] ← mergesort(x[left..m])
x[m+1..right] ← mergesort(x[m+1..right])
x[left..right] ← merge(x[left..m],x[m+1..right])
ENDIF
RETURN x[left..right]
Remark:
the algorithm will be called as mergesort(x[1..n])
Algorithmics - Lecture 8-9
23
Mergesort
Merge step:
merge (x[left..m],x[m+1..right])
i ← left; j ← m+1; k ← 0;
// scan simultaneously the arrays
// and transfer the smallest element
in t
WHILE i<=m AND j<=right DO
IF x[i]<=x[j]
THEN k ← k+1
t[k] ← x[i]
i ← i+1
ELSE k ← k+1
t[k] ← x[j]
j ← j+1
ENDIF
ENDWHILE
// transfer the last elements of the
first array (if it is the case)
WHILE i<=m DO
k ← k+1
t[k] ← x[i]
i ← i+1
ENDWHILE
// transfer the last elements of the
second array (if it is the case)
WHILE j<=right DO
k ← k+1
t[k] ← x[j]
j ← j+1
ENDWHILE
RETURN t[1..k]
Algorithmics - Lecture 8-9
24
Mergesort
• The merge step can be used independently of the sorting process
• Variant of merge based on sentinels:
– Merge two sorted arrays a[1..p] and b[1..q]
– Add large values to the end of each array a[p+1]=, b[q+1]= 
Merge(a[1..p],b[1..q])
a[p+1] ← ; b[q+1] ← 
i ← 1; j ← 1;
FOR k ← 1,p+q DO
IF a[i]<=b[j]
THEN c[k] ← a[i]
i ← i+1
ELSE c[k] ← b[j]
j ← j+1
ENDIF / ENDFOR
RETURN c[1..p+q]
Efficiency analysis of merge step
Dominant operation: comparison
T(p,q)=p+q
In mergesort (p=[n/2], q=n-[n/2]):
T(n)<=[n/2]+n-[n/2]=n
Thus T(n) belongs to O(n)
Algorithmics - Lecture 8-9
25
Mergesort
Efficiency analysis:
0
n=1
T(n)=
T([n/2])+T(n-[n/2])+TM(n)
n>1
Since k=2, m=2, d=1 (TM(n) is from O(n)) it follows (by the second case
of the Master theorem) that T(n) belongs to O(nlgn). In fact T(n)
is from (nlgn)
Remark.
1.
The main disadvantage of merge sort is the fact that it uses an
additional memory space of the array size
2.
If in the merge step the comparison is <= then the mergesort is
stable
Algorithmics - Lecture 8-9
26
Quicksort
Idea:
•
Divide the array x[1..n] in two subarrays x[1..q] and x[q+1..n] such
that all elements of x[1..q] are smaller than the elements of
x[q+1..n]
•
Sort each subarray
•
Concatenate the sorted subarrays
Algorithmics - Lecture 8-9
27
Quicksort
•
Example 1
(a) x[q]>=x[i], for all i<q
(b) x[q]<=x[i], for all i>q
is called pivot
3124758
Divide
312
An element x[q] having the
properties:
758
•
•
A pivot is placed on its final position
A good pivot divides the array in two
subarrays of almost the same size
Sometimes
•
123
578
–
–
Combine
1234578
The pivot divides the array in an
unbalanced manner
Does not exist a pivot => we must
create one by swapping some
elements
Algorithmics - Lecture 8-9
28
Quicksort
•
Example 2
A position q having the property:
(a)
x[i]<=x[i], for all 1<=i<=q and all
q+1<=j<=n
is called partitioning position
3127548
Divide
•
312
A good partitioning position divides
the array in two subarrays of almost
the same size
Sometimes
7548
•
123
4578
–
–
Combine
1234578
The partitioning position divides the
array in an unbalanced manner
Does not exist such a partitioning
position => we must create one by
swapping some elements
Algorithmics - Lecture 8-9
29
Quicksort
The variant which uses a pivot:
quicksort1(x[le..ri])
IF le<ri THEN
q ← pivot(x[le..ri])
x[le..q-1] ← quicksort1(x[le..q-1])
x[q+1..ri] ← quicksort1(x[q+1..ri])
ENDIF
RETURN x[le..ri]
The variant which uses a
partitioning position:
quicksort2(x[le..ri])
IF le<ri THEN
q ← partition(x[le..ri])
x[le..q] ← quicksort2(x[le..q])
x[q+1..ri] ← quicksort2(x[q+1..ri])
ENDIF
RETURN x[le..ri]
Algorithmics - Lecture 8-9
30
Quicksort
Constructing a pivot:
• Choose a value from the array (the first one, the last one or a random
one)
• Rearrange the elements of the array such that all elements which are
smaller than the pivot value are before the elements which are larger
than the pivot value
• Place the pivot value on its final position (such that all elements on its
left are smaller and all elements on its right are larger)
Idea for rearranging the elements:
• use two pointers one starting from the first element and the other
starting from the last element
• Increase/decrease the pointers until an inversion is found
• Repair the inversion
• Continue the process until the pointers cross each other
Algorithmics - Lecture 8-9
31
Quicksort
How to construct a pivot
01 2 34 5 67
1753824
Pivot
value
41753824
41753824
41253874
41235874
41234875
• Choose the pivot value: 4 (the
last one)
• Place a sentinel on the first
position (only for the initial array)
i=0, j=7
i=2, j=6
i=3, j=4
i=4, j=3 (the pointers crossed)
The pivot is placed on its final
position
Algorithmics - Lecture 8-9
32
Quicksort
Remarks:
pivot(x[left..right])
• x[right] plays the role of a
v ← x[right]
sentinel at the right
i ← left-1
• At the left margin we can place
j ← right
explicitly a sentinel on x[0]
WHILE i<j DO
(only for the initial array x[1..n])
REPEAT i ← i+1 UNTIL x[i]>=v • The conditions x[i]>=v, x[j]<=v
allow to stop the search when
REPEAT j ← j-1 UNTIL x[j]<=v
the sentinels are encountered.
IF i<j THEN x[i]↔x[j] ENDIF
Also they allow obtaining a
ENDWHILE
balanced splitting when the
x[i] ↔ x[right]
array contains equal
elements.
RETURN i
• At the end of the while loop
the pointers satisfy either i=j or
i=j+1
Algorithmics - Lecture 8-9
33
Quicksort
Correctness:
pivot(x[left..right])
v ← x[right]
Loop invariant:
i ← left-1
j ← right
If i<j then x[k]<=v for k=left..i
WHILE i<j DO
x[k]>=v for k=j..right
REPEAT i ← i+1 UNTIL x[i]>=v
REPEAT j ← j-1 UNTIL x[j]<=v
If i>=j then x[k]<=v for k=left..i
IF i<j THEN x[i]↔x[j] ENDIF
x[k]>=v for k=j+1..right
ENDWHILE
x[i] ↔ x[right]
RETURN i
Algorithmics - Lecture 8-9
34
Quicksort
Efficiency:
pivot(x[left..right])
v ← x[right]
Input size: n=right-left+1
i ← left-1
j ← right
Dominant operation: comparison
WHILE i<j DO
REPEAT i ← i+1 UNTIL x[i]>=v
T(n)=n+c,
REPEAT j ← j-1 UNTIL x[j]<=v
c=0 if i=j
IF i<j THEN x[i]↔x[j] ENDIF
and
ENDWHILE
c=1 if i=j+1
x[i] ↔ x[right]
RETURN i
Thus T(n) belongs to (n)
Algorithmics - Lecture 8-9
35
Quicksort
Remark: the pivot position does not always divide the array in a
balanced manner
Balanced manner:
• the array is divided in two sequences of size almost n/2
• If each partition is balanced then the algorithm executes few
operations (this is the best case)
Unbalanced manner:
• The array is divided in a subsequence of (n-1) elements the pivot
and an empty subsequence
• If each partition is unbalanced then the algorithm executes much
more operations (this is the worst case)
Algorithmics - Lecture 8-9
36
Quicksort
Worst case analysis:
0
if n=1
T(n)=
T(n-1)+n+1, if n>1
Backward substitution:
T(n)=T(n-1)+(n+1)
T(n-1)=T(n-2)+n
…
T(2)=T(1)+3
T(1)=0
--------------------T(n)=(n+1)(n+2)/2-3
Thus in the worst case quicksort
belongs to (n2)
Algorithmics - Lecture 8-9
37
Quicksort
Best case analysis:
0,
if n=1
T(n)=
By applying the second case of the
master theorem (for k=2,m=2,d=1)
one obtains that in the best case
quicksort is (nlgn)
2T(n/2)+n, if n>1
Thus quicksort belong to Ω(nlgn) and O(n2)
An average case analysis should be useful
Algorithmics - Lecture 8-9
38
Quicksort
Average case analysis.
Hypotheses:
• Each partitioning step needs at most (n+1) comparisons
• There are n possible positions for the pivot. Let us suppose that
each position has the same probability to be selected
(Prob(q)=1/n)
• If the pivot is on the position q then the number of comparisons
satisfies
Tq(n)=T(q-1)+T(n-q)+(n+1)
Algorithmics - Lecture 8-9
39
Quicksort
The average number of comparisons is
Ta(n)=(T1(n)+…+Tn(n))/n
=((Ta(0)+Ta(n-1))+(Ta(1)+Ta(n-2))+…+(Ta(n-1)+Ta(0)))/n + (n+1)
=2(Ta(0)+Ta(1)+…+Ta(n-1))/n+(n+1)
Thus
n Ta(n)
= 2(Ta(0)+Ta(1)+…+Ta(n-1))+n(n+1)
(n-1)Ta(n-1)= 2(Ta(0)+Ta(1)+…+Ta(n-2))+(n-1)n
----------------------------------------------------------------By computing the difference between the last two equalities:
nTa(n)=(n+1)Ta(n-1)+2n
Ta(n)=(n+1)/n Ta(n-1)+2
Algorithmics - Lecture 8-9
40
Quicksort
Average case analysis.
By backward substitution:
Ta(n) = (n+1)/n Ta(n-1)+2
Ta(n-1)= n/(n-1) Ta(n-2)+2
|*(n+1)/n
Ta(n-2)= (n-1)/(n-2) Ta(n-3)+2 |*(n+1)/(n-1)
…
Ta(2) = 3/2 Ta(1)+2
|*(n+1)/3
Ta(1) = 0
|*(n+1)/2
----------------------------------------------------Ta(n) = 2+2(n+1)(1/n+1/(n-1)+…+1/3) ≈ 2(n+1)(ln n-ln 3)+2
In the average case the complexity order is n*log(n)
Algorithmics - Lecture 8-9
41
Quicksort -variants
Another way to construct a pivot
3752148
v=3, i=1,j=2
pivot(x[left..right])
v←x[left]
i ← left
FOR j ← left+1,right
IF x[j]<=v THEN
i ← i+1
x[i] ↔ x[j]
ENDIF
ENDFOR
RETURN i
3752148
i=2, j=4
3257148
i=3, j=5
3217548
i=3, j=8
Plasare pivot:
1237548
Invariant: x[k]<=v for all left<=k<=i
x[k]>v for all i<k<=j
Pivot position: 3
Complexity order of partition: O(n)
Algorithmics - Lecture 8-9
42
Quicksort -variants
Finding a partitioning position
3752148
v=3
3752148
i=2, j=5
partition(x[left..right])
v ← x[left]
3152748
i=3, j=4
i ← left
j ← right+1
3125748
i=4, j=3
WHILE i<j DO
REPEAT i ← i+1 UNTIL x[i]>=v
REPEAT j ← j-1 UNTIL x[j]<=v Partitioning position: 3
IF i<j THEN x[i] ↔x[j]
Complexity order of partition: O(n)
ENDIF
ENDWHILE
RETURN j
Remark: The partition algorithm is to be used in the variant
quicksort2
Algorithmics - Lecture 8-9
43
Next lecture will be on …
… greedy strategy
… and its applications
Algorithmics - Lecture 8-9
44