Escolar Documentos
Profissional Documentos
Cultura Documentos
This lecture will introduce some tools and notations necessary to study algorithm efficiency. The lecture will cover
Asymptotic behaviour Big-O notation Simplifying big-O expressions Big-O of sums and products Big-Omega and Big-Theta notation
Asymptotic Behaviour
Definition
An algorithm is a finite set of precise instructions for performing a computation or for solving a problem.
An important question when comparing two algorithms for the same problem: which one is faster?
this will have many possible answers, and may depend on
the language in which it is written. the machine used to run the algorithm. the size of the problem instance, e.g. is this a 4x4 matrix or a 1024x1024 matrix?
11/2/2006
Lecture7
gac1
11/2/2006
Lecture7
gac1
Asymptotic Behaviour
Asymptotic analysis is a method of abstracting away from these details. This is achieved by
examining the run-time as the problem instance increases in size. ignoring constants of proportionality
if run-time doubles when going from a 2x2 matrix to a 3x3 matrix, thats more interesting than it going from 0.01 sec to 0.02 sec on a particular machine.
Big-O Notation
Definition
Let f and g be functions from the set of integers or the set of reals to the set of reals. The function f(x) is big-O of g(x) iff
cR+ kR+ x ( (x > k) ( |f(x)| c|g(x)| ) )
Notation
We will write f(x) is O(g(x)), when f(x) is big-O of g(x).
Example
You have implemented two division algorithms for n-bit numbers. One takes 100n2 + 17n + 4 microseconds. The other takes n3 microseconds. For some values of n, n3 < 100n2 + 17n + 4 (e.g. n = 5). But for large enough n, n3 will be bigger. We will concentrate on this big picture.
11/2/2006 Lecture7 gac1 3
Intuition
The constant k formalizes our concept of big enough problem instances. The constant c formalizes our concern to avoid worrying about constants of proportionality.
11/2/2006 Lecture7 gac1 4
Examples
cx f (x)
Proof
For this proof, we will assume the triangle inequality xy ( |x+y| |x| + |y| ). Using this property, |f(x)| |anxn| + |an-1xn-1| + + |a1x| + |a0| = xn(|an| + |an-1|/x + + |a1|/xn-1 + |a0|/xn) xn(|an| + |an-1| + + |a1| + |a0|) for x > 1 So using c = |an| + |an-1| + + |a1| + |a0| and k = 1 gives x ( (x > k) ( |f(x)| c|g(x)| ) ), completing the proof.
11/2/2006 Lecture7 gac1 6
ff Example 2 We will show that f(x) = x2 + 5x is O(x2). x2 > 5x whenever x > 5. So for x > 5, f(x) 2x2. So using k = 5, c = 2, we have f(x) is O(x2).
11/2/2006 Lecture7 gac1 5
Big-O of Sums
It is often necessary to characterise the growth of a sum of functions.
Let f(x) denote the run-time of a Delphi function fun1, and let g(x) denote the run-time of another Delphi function fun2. What is known about the run-time of the main program that first calls fun1 and then calls fun2?
Big-O of Sums
By the triangle inequality,
|f1(x)+f2(x)| |f1(x)| + |f2(x)| c1|g1(x)| + c2|g2(x)| for all x > max(k1, k2) c1 max( |g1(x)|, |g2(x)| ) + c1 max( |g1(x)|, |g2(x)| ) (c1 + c2) | max( |g1(x)|, |g2(x)| ) |
Theorem
Let f1(x) be O(g1(x)) and f2(x) be O(g2(x)). Then f1(x)+f2(x) is O( max(|g1(x)|,|g2(x)|) ).
Using c = c1 + c2, and k = max(k1, k2), we have that f1(x)+f2(x) is O( max( |g1(x)|, |g2(x)| ) ).
Example
Given that n! is O(nn), provide a big-O expression for n! + 34 n10. You may assume n is non-negative. n! is O(nn) and 34 n10 is O(n10). So n! + 34 n10 is O( max( |nn|, |n10| ) ) = O( max(nn, n10) ).
Proof
There exist k1,k2,c1,c2, such that
|f1(x)| c1|g1(x)| for all x > k1, and |f2(x)| c2|g2(x)| for all x > k2
11/2/2006 Lecture7 gac1 7
11/2/2006
Lecture7
gac1
Big-O of Products
A similar theorem exists for the big-O of a product of functions. Theorem
Let f1(x) be O(g1(x)) and f2(x) be O(g2(x)). Then f1(x)f2(x) is O( g1(x)g2(x) ).
Big-Omega Notation
Big-O notation provides a useful abstraction for upperbounds on function growth, but has some problems.
x2 is O(x2), but also x2 is O(x3) or even O(2x). Providing a lower-bound on function growth would be helpful, but is often much harder. Let f and g be functions from the set of integers or the set of reals to the set of reals. The function f(x) is big-Omega of g(x) iff
cR+ kR+ x ( (x > k) ( |f(x)| c|g(x)| ) ).
Proof
There exist k1,k2,c1,c2, such that
|f1(x)| c1|g1(x)| for all x > k1, and |f2(x)| c2|g2(x)| for all x > k2
Definition
Notation
We will write f(x) is (g(x)), when f(x) is big-Omega of g(x).
Big-Omega Notation
Example
Show that x2 x2 6x is (x2).
Big-Omega Notation
Theorem
f(x) is (g(x)) iff g(x) is O(f(x)).
|x2
6x = 6/x). For x 7, (1 6/x) is positive. 2|(1 6/x) for x 7. 6x| = |x |x2|(1 6/7) for x 7. So choosing k = 7 and c = 1/7, we have that x2 6x is (x2). x2(1
Proof
If f(x) is (g(x)), then we have
|f(x)| c1|g(x)| for x > k1. Since c1 is positive, we have |g(x)| (1/c1)|f(x)|. Using c = 1/c1 and k = k1 gives g(x) is O(f(x)).
11/2/2006
Lecture7
gac1
11
11/2/2006
Lecture7
gac1
12
Big-Theta Notation
Definition
Let f and g be functions from the set of integers or the set of reals to the set of reals. The function f(x) is big-Theta of g(x) iff f(x) is O(g(x)) and f(x) is (g(x)).
Big-Theta in Action
x2 x2 6x
Notation
We will write f(x) is (g(x)), or f(x) is order g(x), when f(x) is bigTheta g(x).
x2/7
Example
We recently proved that x2 6x is (x2). Also, from our theorem on big-O of polynomials, x2 6x is O(x2). Thus x2 6x is (x2). Note that while x2 6x is O(x3), it is not (x3) Note that while x2 6x is (x), it is not (x).
11/2/2006
Lecture7
gac1
13
Summary
This lecture has covered
Asymptotic behaviour Big-O notation Simplifying big-O expressions Big-O of sums and products Big-Omega and Big-Theta notation
The next lecture will use these concepts to examine the complexity of algorithms.
11/2/2006
Lecture7
gac1
15
11/2/2006
Lecture7
gac1
16
We will concentrate on time complexity in this lecture Often, an algorithm will take much longer on one input than on another, even when both inputs are the same size. Example
Consider the following algorithm, Linear Search, which looks for a particular element value in an array.
11/2/2006
Lecture8
gac1
11/2/2006
Lecture8
gac1
Linear Search
1. 2. 3. procedure linear_search( integer x, integer a[n] ) begin i := 1 while( i n and x a[ i ] ) i := i + 1 end
Worst/Average-Case Complexity
Given the array a[1] = 1, a[2] = 5, a[3] = 2, a call linear_search( 1, a ) will clearly take less time than a call linear_search( 2, a ).
This algorithm terminates with i equal to the number of the element, so a[i] = x.
(assuming that there is at least one such element)
The algorithm works by comparing x to each element in a[ ] in turn. The first one to match is taken as the result.
11/2/2006 Lecture8 gac1
Linear Search
We will now find an upper bound for the worst-case time complexity of linear_search.
Line 1 executes once. Line 2 (the comparisons) executes at most n times. Line 3 executes at most n 1 times.
Binary Search
Binary search is another searching algorithm, which can be used on an array which is known to be sorted
we will assume it is sorted in ascending order
procedure binary_search( integer x, integer a[n] ) begin i := 1 { we know that x is somewhere between } j := n { the ith and the jth element of a, inclusive } while( i < j ) begin m := floor( (i+j)/2 ) if x > a[ m ] then i := m + 1 else j := m end end
Lecture8 gac1 6
1. 2. 3. 4. 5.
All we needed to assume was that each of these times is a constant (independent of n).
11/2/2006 Lecture8 gac1 5 11/2/2006
Binary Search
How this algorithm works:
Variables i and j record the lower and upper array indices which could contain x, respectively. In each iteration, the index half-way between i and j is found (m). If half-way is not an integer, it is rounded down (floor function). If x is bigger than element a[m], then x can only be above m in the array, since the array is sorted
in this case, we dont need to search from 1 to m, and so i := m+1
Binary Search
We will now find an upper bound for the worst-case time complexity of binary_search.
For simplicity, we will analyse the algorithm for the case where n is a power of 2. Originally i = 1 and j = 2k, so m = 2k-1. After the first iteration, we have either i = 2k-1 + 1 and j = 2k, or i = 1 and j = 2k-1. In either case, we have a total of 2k-1 elements to search. After the second iteration, we will have 2k-2 elements, and so on until we have one element left. So line 3 executes exactly k+1 times. Line 4 and 5 therefore execute k times, and lines 1 and 2 execute once. The total complexity is O(1) + O(k+1) + O(k) = O(k) = O(log2 n).
11/2/2006 Lecture8 gac1 8
The algorithm terminates when i = j, i.e. there is only one possible element left to search.
11/2/2006 Lecture8 gac1 7
Bubble Sort
Bubble sort is an algorithm to sort an array in ascending order. procedure bubble_sort( real a[n] )
begin for i := 1 to n 1 for j := 1 to n i if a[ j ] > a[ j + 1 ] then swap a[ j ] and a[ j + 1 ] end
Bubble Sort
An example execution
a[1] a[2] a[3] a[4]
= = = = 1 5 3 0
pair-wise swap
a[1] a[2] a[3] a[4]
= = = = 1 0 3 5
The procedure
makes repeated passes over the array a[ ]. during each iteration, it repeatedly swaps neighbouring elements that are not in the right order. the first iteration ensures that the largest element in the array ends up in position a[n]. the second iteration ensures that the second largest element ends up in position a[n-1], and so on. after n-1 iterations, the array will be sorted.
11/2/2006 Lecture8 gac1 9
= = = =
1 3 0 5
= = = =
0 1 3 5
1st iteration
2nd iteration
3rd iteration
11/2/2006
Lecture8
gac1
10
A Quick Lemma
To analyse the complexity of bubble sort, we need the following lemma. Lemma
S ( n) = i =
i =1 n 1
Bubble Sort
To analyse the worst-case complexity of bubble sort
notice that there will be n-1 iterations of the outer loop for each iteration of the outer loop, there will be n-i iterations of the inner loop each iteration of the inner loop is O(1) the total number of iterations of the inner loop is thus
n(n 1) 2
for n > 1.
Proof
We will prove by induction. It is clearly true for n = 2. Assume true for n, and we will demonstrate it is true for n+1.
S (n + 1) = i = S (n) + n =
i =1
11/2/2006 Lecture8
(n i) = n(n 1) i = n(n 1)
i =1 i =1
11/2/2006 Lecture8 gac1
n 1
n 1
n(n 1) n(n 1) = 2 2
11/2/2006
Lecture8
gac1
13
11/2/2006
Summary
This lecture has covered
Time complexity and space-complexity Worst-case and average-case complexity Common complexity classes The time-complexity of some common algorithms
Linear search Binary search Bubble sort
However, we are not yet able to analyse recursive algorithms. The next lecture will introduce recurrence relations, which will enable us to do so.
11/2/2006 Lecture8 gac1 15
Recurrence Relations
This lecture will cover
What is a recurrence relation? The substitution method. Solution of some linear homogeneous recurrence relations: degree 1 and degree 2. Solution of some linear non-homogeneous recurrence relations: degree 1 and degree 2.
Definition
A recurrence relation for the sequence {an} is an equation that expresses an in terms of one or more of the previous terms of the sequence (i.e. a0, a1,, and an-1), for all n n0, where n0 N.
Example
an = an-1 + an-2 for n 2 is a recurrence relation.
11/2/2006 Lecture9 gac1 1 11/2/2006 Lecture9 gac1 2
Example
an = 2an/2 + n, for n > 1. (note the notation x for floor(x) ) We may have seen similar recurrences before, and be able to guess a solution an = O(n log2 n). Assume this is true for n/2. Then an 2c n/2 log n/2 + n for large enough n.
11/2/2006 Lecture9 gac1 4
Example
Our bank interest example an = 1.1an-1 is a linear homogeneous recurrence relation of degree 1 with constant coefficients.
11/2/2006 Lecture9 gac1 6
Proof
We can prove this with the substitution method. Assume true for n 1. We will show it holds for n. can-1 = ccn-1 = cn = an. It only remains to determine . Substituting n = 0, gives = a0.
11/2/2006 Lecture9 gac1 7
Proof
Assume true for n-1 and n-2. We will show it to hold for n. c1an-1 + c2an-2 = c1(1r1n-1 + 2r2n-1) + c2 (1r1n-2 + 2r2n-2) = 1r1n-2 (c1r1 + c2) + 2r2n-2(c1r2 + c2). But c1r1 + c2 = r12 and c1r2 + c2 = r22. So c1an-1 + c2an-2 = 1r1n-2r12 + 2r2n-2r22 = 1r1n + 2r2n = an.
11/2/2006 Lecture9 gac1 8
1 =
5+ 5 5 5 , 2 = 10 10
n n
Example
Obtain a solution to the recurrence an = an-1 + an-2, with a0 = 1, a1 = 1?
note that this is the famous Fibonacci sequence.
11/2/2006 Lecture9 gac1 9
5 + 5 1+ 5 5 5 1 5 + an = 10 2 10 2
11/2/2006 Lecture9 gac1
10
Non-Homogeneous Recurrences
Proof
Assume true for n-1. We will show it holds for n. can-1 + k = c(cn-1 + k/(1 c)) + k = cn + k( 1 + c/(1 c) ) = cn + k/(1 c) = an. It remains to determine the value of from initial condition a0. Substituting n = 0, we obtain a0 = + k/(1 c), so = a0 - k/(1 c).
There are many results on these equations, but we will only look at the particularly important case when F(n) is a constant. Firstly, lets consider the degree 1 case. Theorem
Let c be a real number with c 1. Then an = cn + k/(1 c) is a solution to the recurrence relation an = can-1 + k. The value of can can be found from the initial condition a0.
11/2/2006 Lecture9 gac1 11
Theorem
Then an = + nk is a solution to the recurrence relation an = an-1 + k. The value of can can be found from the initial condition a0.
11/2/2006 Lecture9 gac1 12
Non-Homogeneous Recurrences
Proof
Assume true for n-1. We will show it holds for n. an-1 + k = + (n 1)k + k = + nk = an. It remains to determine the value of from initial condition a0. Substituting n = 0, we obtain = a0.
Non-Homogeneous Example
We will try to find a solution for the recurrence
an = an-1 + 2an-2 + 1, with a0 = 1, a1 = 1.
So we have
a1 = 1r1 + (a0 1 p)r2 + p 1(r1 r2) = a1 a0 r2 + p(r2 1).
The solutions are distinct, and c1 + c2 1, so the theorem will help us find a solution. We obtain
an = 12n + 2(-1)n .
Thus
1 = (a1 a0 r2 + p(r2 1))/(r1 r2), since r1 r2, and 2 = a0 1 p.
1 1 an = 2 n + (1) n 2 2
gac1 16
Summary
This lecture has covered
What is a recurrence relation? The substitution method. Solution of some linear homogeneous recurrence relations: degree 1 and degree 2. Solution of some linear non-homogeneous recurrence relations: degree 1 and degree 2.
Which of these linear recurrence relations with constant coefficients can be solved using the techniques in this lecture?
(a) (b) (c) (d) an = 2an-1 2an-2. an = 4an-1 + 4an-2. an = 3an-1 + 2an-2 + 1. an = 2an-1 2an-2 + 1.
Lecture9 gac1 17
We have ploughed through some [fairly unpleasant?] algebra, but it will be worth it for the next lecture
we can use these relations to analyse recursive algorithms.
11/2/2006 Lecture9 gac1 18
11/2/2006
Recursive Algorithms
Definition
An algorithm is called recursive if it solves a problem by reducing it to one or more instances of the same problem with smaller input.
11/2/2006
Lecture10
gac1
11/2/2006
Lecture10
gac1
The recurrence is of the form an = an-1 + k, so the solution has the form an = + nk.
k = 1, a0 = 0 So an = n. n multiplications are performed by a call to factorial(n). The run time will be O(n).
Let us denote by an the total number of multiplication operations performed by factorial(n). We have a0 = 0 and an = 1 + an-1, for n > 0.
A recurrence relation!
11/2/2006 Lecture10 gac1 3
11/2/2006
Lecture10
gac1
Recursive Fibonacci
For a different type of example, consider the following algorithm for calculating the Fibonacci sequence recall that fib(1) = 1, fib(2) = 1, and fib(n) = fib(n-1) + fib(n-2) for n > 2. function fib(n : positive integer) begin if n <= 2 then result := 1 else result := fib( n 1 ) + fib( n 2 ) end
11/2/2006 Lecture10 gac1 5
Recursive Fibonacci
We may wish to determine the number of addition operations required by this algorithm.
Let us denote this an.
Recursive Fibonacci
This is a linear non-homogeneous recurrence relation of degree 2 with constant coefficients.
Compare with an = c1an-1 + c2an-2 + k. We have c1 = 1, c2 = 1, k = 1.
Recursive Fibonacci
Substituting n = 1 and n = 2 gives
1r1 + 2r2 1 = 0 (*) 1r12 + 2r22 1 = 0 (**)
2r22 1 2r2r1 + r1 = 0, i.e. 2 = (1 r1)/(r22 r2r1) = -1/5 and 1 = 1/5 (after some work!)
The two roots of this quadratic are r1 = (1 + 5)/2 and r2 = (1 - 5)/2, and the solution to the recurrence has the form an = 1r1n + 2r2n k/(c1 + c2 1) = 1r1n + 2r2n 1.
11/2/2006 Lecture10 gac1 7
Iterative Factorial
We can compare the recursive versions of these algorithms to their iterative equivalents. An iterative factorial is shown below.
function factorial(n : non-negative integer) begin result := 1 for i = 1 to n result := result * i end
Iterative Factorial
Note that this doesnt mean the two version have the same run time.
The constant of proportionality in the O(n) hides the details. In practice, function calls (stack manipulation, etc.) often have a large overhead. But the result is still valuable: for large enough n, the execution time of the two ways of calculating factorial are out by at most a constant multiplicative factor.
Iterative Fibonacci
An iterative version of the Fibonacci generator is shown below.
function fib(n : positive integer) begin x := 0 result := 1 for i = 1 to (n 1) begin z := x + result x := result result := z end end
Lecture10 gac1
Iterative Fibonacci
Addition is only performed once in the loop, so a total of (n-1) additions are performed. Apart from the initialization of x, result, and i (which are O(1)), the remaining operations take O(n) time.
the execution time is linear in n.
This compares very favourably with the recursive version: linear vs. exponential run-time! We can draw a valuable lesson from this example
recursion often makes the algorithm neater and easier to read, but it must be used with caution, as exponential run-times can result.
11/2/2006
11
11/2/2006
Lecture10
gac1
12
Summary
This lecture has covered
How to analyse recursive execution time Recursive and iterative factorial algorithms Recursive and iterative Fibonacci algorithms
We can now analyse some recursive algorithms. There is an important class of recursive algorithms, known as divide and conquer algorithms, that we cant yet analyse. For this, we need more recurrence relations.
11/2/2006 Lecture10 gac1 14
Divide-and-Conquer Recurrences
This lecture will introduce divide-and-conquer recurrence relations
used to analyse divide-and-conquer recursive algorithms
Divide-and-Conquer Recurrences
A divide-and-conquer algorithm breaks up a large problem into several proportionally smaller versions of the same problem.
this approach is often used for sorting, for example detailed examples in the next lecture.
11/2/2006
Lecture11
gac1
11/2/2006
Lecture11
gac1
We will use this expansion to analyse special cases of the general D&C recurrence relation.
11/2/2006 Lecture11 gac1 3
Quick test:
Why do I need to write the base of the log in the first case, but not in the second?
11/2/2006
Lecture11
gac1
First, let us consider our expansion of the recurrence, when g(n) is constant.
f (n) = a k f (1) + a j g (n / b j )
j =0 k 1
this is the sum of an O(1) function and an O(log n) function, and is therefore an O(log n) function.
= a k f (1) + c a j
j =0
k 1
11/2/2006
Lecture11
gac1
11/2/2006
Lecture11
gac1
Summary so far:
We have shown that for a = 1, f(n) is O(log n). We now need to examine the case a > 1.
We finally have to consider the case where a > 1 and n is not an integer power of b.
11/2/2006 Lecture11 gac1 8
Examples
Example 1
Find a big-O expression for an increasing function satisfying f(n) = 5f(n/2) + 3. Compare with f(n) = a f(n/b) + g(n). This is a divide-andconquer recurrence relation with:
constant g(n) = c = 3. a = 5 1. b = 2 > 1.
We can therefore apply the theorem. log a log 5 2.33 f(n) is O(n ) = O(n ) or O(n ). Note that log2 5 = 2.32 to 2 decimal places. But for a big-O expression, we have used O(n2.33).
b 2
Examples
A plot of the function f(n) is shown below (*).
1800 1600
Examples
Example 2
Find a big-O expression for an increasing function satisfying f(n) = f(n/2) + 16. Compare with f(n) = a f(n/b) + g(n). This is a divide-andconquer recurrence relation with:
constant g(n) = c = 16. a = 1 1. b = 2 > 1.
1400
1200
1000
800
600
400
200
10
12
14
16
18
20
n
(*) Initial conditions: f(1) = 0.24, f(3) = 12.93, f(5) = 42.52, f(7) = 93.13, f(9) = 167.26, f(11) = 266.96, f(13) = 393.99, f(15) = 549.91, f(17) = 736.11, f(19) = 954.88
11/2/2006 Lecture11 gac1 11
11/2/2006
Lecture11
gac1
12
Examples
A plot of the function f(n) is shown below (*).
80
70
60
50
40
30
20
10
n
(*) Initial conditions: f(1) = 0, f(3) = 25.44, f(5) = 37.12, f(7) = 44.96 , f(9) = 50.72, f(11) = 55.36, f(13) = 59.2, f(15) = 62.56, f(17) = 65.44, f(19) = 68.
11/2/2006 Lecture11 gac1 13 11/2/2006 Lecture11 gac1 14
Example
Example
Find a big-O expression for an increasing function f(n) satisfying f(n) = 8 f(n/2) + n2. Compare with f(n) = a f(n/b) + g(n). This is a divide-andconquer recurrence relation with:
g(n) = n2. This has the form g(n) = cnd, with c = 1 > 0 and d = 2 0. a = 8 1. b = 2 > 1.
We can therefore apply the Master Theorem. We have a > bd (8 > 4), so f(n) is O(n log 8 ) = O(n 3 ) .
2
11/2/2006
Lecture11
gac1
15
11/2/2006
Lecture11
gac1
16
Example
A plot of the function f(n) is shown below (*).
800
0.1n3 f(n)
700
600
500
400
300
200
100
10
12
14
16
18
20
n
(*) Initial conditions: f(1) = 1, f(3) = 10, f(5) = 25, f(7) = 60 , f(9) = 100, f(11) = 150, f(13) = 220, f(15) = 280, f(17) = 380, f(19) = 460.
11/2/2006 Lecture11 gac1 17 11/2/2006 Lecture11 gac1 18
Summary
This lecture has covered
divide-and-conquer recurrences a theorem for a common form of divide-and-conquer recurrence the Master Theorem
In the next lecture, we will put these tools to work analysing divide-and-conquer algorithms.
11/2/2006
Lecture11
gac1
19
Obtaining Recurrences
Divide-and-conquer recurrence relations occur when analysing the time-complexity of divide-andconquer algorithms. A divide-and-conquer recurrence relation f(n) = a f(n/b) + g(n) results when the algorithm, operating on a problem of size n (multiple of b),
1. decides how to split up the input; 2. splits the input into smaller segments, each of size n/b, recursively operating on a of those segments; 3. combines the resulting outputs to make to overall output. steps 1+3 combined take time g(n).
11/2/2006
Lecture12
gac1
11/2/2006
Lecture12
gac1
Binary Search
Binary Search is a classic example
we looked at an iterative version in Lecture 8 a slightly different recursive version is shown below: here the aim is to report success iff the value x is found in the (sorted) array a[ ]. procedure binary_search( integer x, integer a[n] )
1. begin if n = 1 then if a[1] = x then report success else report failure else if x < a[ n/2 ] then binary_search( x, a[1 to n/2]) else binary_search( x, a[n/2 + 1 to n]) end
Lecture12 gac1
Binary Search
Algorithm explanation
if the array is of length one, then we only need to look in one place to find x, i.e. a[1]. otherwise, we find the approximate mid-point, n/2. the array is sorted, so if x is less than the value at the mid-point, look in the first-half; otherwise, look in the second-half.
2.
11/2/2006
Binary Search
We can find a big-O estimate for the number of comparison operations. The function g(n)?
g(n) here models the overhead in the execution of line 1 and line 2. each one performs a comparison, so g(n) = 2.
Binary Search
Solution of this recurrence comes from the Master Theorem (or our special case).
Compare with f(n) = a f(n/b) + cnd. We have a = 1, b = 2, c = 2, d = 0. Since a = bd, f(n) is O(nd log n) = O(log n). Binary search is logarithmic-time.
Merge Sort
Merge sort is a famous algorithm for sorting arrays.
it has better asymptotic performance than bubble sort (we will prove this).
Merge Sort
procedure merge_sort( real a[n] ) begin if n = 1 then result := a else L1 = merge_sort( a[ 1 to n/2 ] ) L2 = merge_sort( a[ n/2+1 to n ] ) result := merge( L1, L2 ) end
split
[4,10]
split
[4]
merge
[4, 10]
merge
[1,4,9,10]
[10] [9,1]
11/2/2006
The algorithm is shown in pseudo-code above. For this algorithm to be efficient, we need an efficient implementation of merge().
[9] [1]
Lecture12
[1,9]
gac1 7 11/2/2006 Lecture12 gac1 8
Merge Procedure
The merge procedure can take advantage of the fact that its inputs are sorted arrays.
procedure merge( real L1[p], L2[q] ) begin count1 := 1 count2 := 1 countM := 1 do if count2 > q or L1[count1] < L2[count2] then begin result[countM] = L1[count1] count1 := count1 + 1 end else begin result[countM] = L2[count2] count2 := count2 + 1 end countM := countM + 1 while countM <= p + q end
Lecture12 gac1
Merge Procedure
Algorithm explanation
at each iteration of the while loop, it fills a single element of result[ ]. the source of this element depends on whether the current element of L1 or L2 is smallest the smallest is taken. the counters keep track of the current element being processed on each of the three lists.
1.
count1
[4, 10]
count1
[4, 10]
count1
[4, 10]
count1
[4, 10]
count1
[4, 10]
count2
[1,9]
count2
[1,9]
count2
[1,9]
count2
[1,9]
count2
[1,9]
countM
[?,?,?,?]
9 11/2/2006
countM
[1,?,?,?]
countM
[1,4,?,?]
Lecture12
countM
[1,4,9,?]
gac1
countM
[1,4,9,10]
2.
11/2/2006
iteration
10
Merge Procedure
Algorithm analysis
before we can estimate the execution time of merge_sort, we need to find the execution time of merge we will count the number of comparisons
the loop iterates p+q times there are at most 2(p+q) comparisons on line 1 the comparison on line 2 is performed p+q times
Merge Sort
We can now return to the analysis of merge_sort
when n is even, merge_sort
1. performs a comparison (n = 1). 2. performs two other merge_sorts on problems of size n/2. 3. calls merge, which performs at most 3n comparisons.
the total number of comparisons is therefore at most 3(p+q). merge is called with p = n/2, q = n - n/2. So the total number of comparisons is at most 3n.
11/2/2006 Lecture12 gac1 11
Merge Sort
Writing this as a recurrence relation, f(n) = 2f(n/2) + 3n
compare with f(n) = a f(n/b) + cnd, to get a = 2, b = 2, c = 4, d = 1. we have a = bd, so f(n) is O(nd log n) = O(n log n), from the Master Theorem.
Note that the simplification we made (3n + 1 4n) has not affected the tightness of the bound in this case
f(n) = 2f(n/2) + 3n gives exactly the same bound.
Conclusion: merge_sort performs O(n log n) comparisons, but bubble_sort performs n(n-1)/2.
merge_sort is asymptotically faster.
11/2/2006 Lecture12 gac1 13
Summary
This lecture has covered
obtaining divide-and-conquer recurrences example algorithms
binary search merge sort
This was the last lecture on recurrence relations. In the next lecture we will look at the ideas of computability theory.
11/2/2006 Lecture12 gac1 15