0% found this document useful (0 votes)
161 views

L9 - Analysis of Algorithms PDF

This document discusses analyzing algorithm efficiency through big-O notation. It explains that counting the number of operations an algorithm performs allows assessment of efficiency independent of actual runtime. The key aspects are: 1) Algorithms can be analyzed by counting basic operations like arithmetic, comparisons, and ignoring lower-order terms for larger inputs. 2) Asymptotic analysis focuses on the leading term to determine the growth rate as input size increases. 3) Big-O notation expresses the upper bound of an algorithm's growth rate, allowing algorithms to be classified based on rate of growth like O(n), O(n^2), O(2^n).

Uploaded by

Fatima Argamosa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
161 views

L9 - Analysis of Algorithms PDF

This document discusses analyzing algorithm efficiency through big-O notation. It explains that counting the number of operations an algorithm performs allows assessment of efficiency independent of actual runtime. The key aspects are: 1) Algorithms can be analyzed by counting basic operations like arithmetic, comparisons, and ignoring lower-order terms for larger inputs. 2) Asymptotic analysis focuses on the leading term to determine the growth rate as input size increases. 3) Big-O notation expresses the upper bound of an algorithm's growth rate, allowing algorithms to be classified based on rate of growth like O(n), O(n^2), O(2^n).

Uploaded by

Fatima Argamosa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 38

Lecture 9

Analysis of Algorithms

Measuring Algorithm Efficiency


Lecture Outline
 What is an Algorithm?
 What is Analysis of Algorithms?
 How to analyze an algorithm
 Big-O notation
 Example Analyses

[ CS1020E AY1617S1 Lecture 9 ]


2
You are expected to know…
 Proof by induction
 Operations on logarithm function
 Arithmetic and geometric progressions
 Their sums
 See L9 – useful_formulas.pdf for some of these

 Linear, quadratic, cubic, polynomial functions


 ceiling, floor, absolute value

[ CS1020E AY1617S1 Lecture 9 ]


3
Algorithm and Analysis
 Algorithm
 A step-by-step procedure for solving a problem

 Analysis of Algorithm
 To evaluate rigorously the resources (time and
space) needed by an algorithm and represent the
result of the evaluation with a formula
 For this module, we focus more on time
requirement in our analysis
 The time requirement of an algorithm is also called
the time complexity of the algorithm
[ CS1020E AY1617S1 Lecture 9 ]
4
Measure Actual Running Time?
 We can measure the actual running time of a
program
 Use wall clock time or insert timing code into
program

 However, actual running time is not


meaningful when comparing two algorithms
 Coded in different languages
 Using different data sets
 Running on different computers

[ CS1020E AY1617S1 Lecture 9 ]


5
Counting Operations
 Instead of measuring the actual timing, we
count the number of operations
 Operations: arithmetic, assignment, comparison, etc.

 Counting an algorithm’s operations is a way to


assess its efficiency
 An algorithm’s execution time is related to the
number of operations it requires

[ CS1020E AY1617S1 Lecture 9 ]


6
Example: Counting Operations
 How many operations are required?
for (int i = 1; i <= n; i++) {
perform 100 operations; // A
for (int j = 1; j <= n; j++) {
perform 2 operations; // B
}
}
n n n
Total Ops = A + B   100   (  2)
i 1 i 1 j 1
n
 100n   2n  100n  2n 2  2n 2  100n
i 1

[ CS1020E AY1617S1 Lecture 9 ]


7
Example: Counting Operations
 Knowing the number of operations required
by the algorithm, we can state that
 Algorithm X takes 2n2 + 100n operations to solve
problem of size n

 If the time t needed for one operation is


known, then we can state
 Algorithm X takes (2n2 + 100n)t time units

[ CS1020E AY1617S1 Lecture 9 ]


8
Example: Counting Operations
 However, time t is directly dependent on the
factors mentioned earlier
 e.g. different languages, compilers and computers

 Instead of tying the analysis to actual time t,


we can state
 Algorithm X takes time that is proportional to
2n2 + 100n for solving problem of size n

[ CS1020E AY1617S1 Lecture 9 ]


9
Approximation of Analysis Results
 Suppose the time complexity of
 Algorithm A is 3n2 + 2n + log n + 1/(4n)
 Algorithm B is 0.39n3 + n

 Intuitively, we know Algorithm A will outperform B


 When solving larger problem, i.e. larger n

 The dominating term 3n2 and 0.39n3 can tell us


approximately how the algorithms perform
 The terms n2 and n3 are even simpler and preferred
 These terms can be obtained through asymptotic
analysis
[ CS1020E AY1617S1 Lecture 9 ]
10
Asymptotic Analysis
 Asymptotic analysis is an analysis of
algorithms that focuses on
 Analyzing problems of large input size
 Consider only the leading term of the formula
 Ignore the coefficient of the leading term

[ CS1020E AY1617S1 Lecture 9 ]


11
Why Choose Leading Term?
 Lower order terms contribute lesser to the
overall cost as the input grows larger
 Example
 f(n) = 2n2 + 100n
 f(1000) = 2(1000)2 + 100(1000)
= 2,000,000 + 100,000
 f(100000) = 2(100000)2 + 100(100000)
= 20,000,000,000 + 10,000,000

 Hence, lower order terms can be ignored

[ CS1020E AY1617S1 Lecture 9 ]


12
Examples: Leading Terms
 a(n) = ½ n + 4
 Leading term: ½ n

 b(n) = 240n + 0.001n2


 Leading term: 0.001n2

 c(n) = n lg(n) + lg(n) + n lg( lg(n) )


 Leading term: n lg(n)
 Note that lg(n) = log2(n)

[ CS1020E AY1617S1 Lecture 9 ]


13
Why Ignore Coefficient of Leading Term?
 Suppose two algorithms have 2n2 and 30n2 as
the leading terms, respectively
 Although actual time will be different due to the
different constants, the growth rates of the
running time are the same
 Compare with another algorithm with leading
term of n3, the difference in growth rate is a
much more dominating factor
 Hence, we can drop the coefficient of leading
term when studying algorithm complexity
[ CS1020E AY1617S1 Lecture 9 ]
14
Upper Bound: The Big-O Notation
 If algorithm A requires time proportional
to f(n)
 Algorithm A is of the order of f(n)
 Denoted as Algorithm A is O(f(n))
 f(n) is the growth rate function for Algorithm A

[ CS1020E AY1617S1 Lecture 9 ]


15
The Big-O Notation
 Formal definition
 Algorithm A is of O(f(n)) if there exist a constant k,
and a positive integer n0 such that Algorithm A
requires no more than k * f(n) time units to solve a
problem of size n >= n0

k*f(n)
Time
Algorithm A

f(n)

n0 Problem Size
[ CS1020E AY1617S1 Lecture 9 ]
16
The Big-O Notation
 When problem size is larger than n0, Algorithm A is
bounded from above by k * f(n)
 Observations
 n0 and k are not unique
 There are many possible f(n)

k*f(n)
Time
Algorithm A

f(n)

n0 Problem Size
[ CS1020E AY1617S1 Lecture 9 ]
17
Example: Finding n0 and k
 Given complexity of Algorithm A is 2n2 + 100n
 Claim: Algorithm A is of O(n2)
 Solution
 2n2 + 100n < 2n2 + n2 = 3n2 whenever n >100
 Set the constants to be k = 3 and n0 = 100
 By definition, we say Algorithm A is O(n2)

 Questions
 Can we say A is O(2n2) or O(3n2)?
 Can we say A is O(n3)?
[ CS1020E AY1617S1 Lecture 9 ]
18
Growth Terms
 In asymptotic analysis, a formula can be simplified
to a single term with coefficient 1 (how?)
 Such a term is called a growth term (rate of
growth, order of growth, order of magnitude)
 The most common growth terms can be ordered as
follows (note that many others are not shown)
O(1) < O(log n) < O(n) < O(n log n) < O(n2) < O(n3) < O(2n) < …
“fastest” “slowest”

 “log” = log2
 In big-O, log functions of different bases are all the same (why?)

[ CS1020E AY1617S1 Lecture 9 ]


19
Common Growth Rates
 O(1) — constant time
 Independent of n
 O(n) — linear time
 Grows as the same rate of n
 E.g. double input size  double execution time
 O(n2) — quadratic time
 Increases rapidly w.r.t. n
 E.g. double input size  quadruple execution time
 O(n3) — cubic time
 Increases even more rapidly w.r.t. n
 E.g. double input size  8 * execution time
 O(2n) — exponential time
 Increases very very rapidly w.r.t. n
[ CS1020E AY1617S1 Lecture 9 ]
20
Example: Exponential-Time Algorithm
 Suppose we have a problem that, for an input
consisting of n items, can be solved by going
through 2n cases
 We use a supercomputer, that analyses 200
million cases per second
 Input with 15 items — 163 microseconds
 Input with 30 items — 5.36 seconds
 Input with 50 items — more than two months
 Input with 80 items — 191 million years

[ CS1020E AY1617S1 Lecture 9 ]


21
Example: Quadratic-Time Algorithm
 Suppose solving the same problem with another
algorithm will use 300n2 clock cycles on a Handheld
PC, running at 33 MHz
 Input with 15 items — 2 milliseconds
 Input with 30 items — 8 milliseconds
 Input with 50 items — 22 milliseconds
 Input with 80 items — 58 milliseconds

 Therefore, to speed up program, don't simply rely on


the raw power of a computer
 Very important to use an efficient algorithm

[ CS1020E AY1617S1 Lecture 9 ]


22
Comparing Growth Rates

[ CS1020E AY1617S1 Lecture 9 ]


23
Comparing Growth Rates

[ CS1020E AY1617S1 Lecture 9 ]


24
How to Find Complexity?
 Some rules of thumb
 Basically just count the number of statements executed
 If there are only a small number of simple statements in a
program — O(1)
 If there is a ‘for’ loop dictated by a loop index that goes up
to n — O(n)
 If there is a nested ‘for’ loop with outer one controlled by n
and the inner one controlled by m — O(n*m)
 For a loop with a range of values n, and each iteration
reduces the range by a fixed constant fraction (eg: ½)
— O(log n)
 For a recursive method, each call is usually O(1). So
 If n calls are made — O(n)
 If n log n calls are made — O(n log n)
[ CS1020E AY1617S1 Lecture 9 ]
25
Example: Finding Complexity (1/2)
 What is the complexity of the following code fragment?

int sum = 0;
for (int i = 1; i < n; i = i*2) {
sum++;
}

 It is clear that sum is incremented only when


i = 1, 2, 4, 8, …, 2k where k = log2 n

There are k + 1 iterations.


So the complexity is O(k) or O(log n)

[ CS1020E AY1617S1 Lecture 9 ]


26
Example: Finding Complexity (2/2)
 What is the complexity of the following code fragment?
 For simplicity, let’s assume that n is some power of 3
int sum = 0;
for (int i = 1; i <= n; i = i*3)
for (int j = 1; j <= i; j++)
sum++;

 f(n) = 1 + 3 + 9 + 27 + … + 3(log3 n)
= 1 + 3 + … + n/9 + n/3 + n
= n + n/3 + n/9 + … + 3 + 1
= n * (1 + 1/3 + 1/9 + …)
≤ n * (3/2)
= 3n/2
= O(n)
[ CS1020E AY1617S1 Lecture 9 ]
27
Analysis 1: Tower of Hanoi
 Number of moves made by the algorithm is 2n − 1
 Prove it!
 Hints: f(1)=1, f(n)=f(n-1) + 1 + f(n-1), and prove by
induction

 Assume each move takes c time, then


f(n) = c(2n − 1) = O(2n)

 The Tower of Hanoi algorithm is an exponential


time algorithm
[ CS1020E AY1617S1 Lecture 9 ]
28
Analysis 2: Sequential Search
 Check whether an item x is in an unsorted
array a[ ]
 If found, it returns position of x in array
 If not found, it returns -1

public int seqSearch(int a[], int len, int x) {


for (int i = 0; i < len; i++) {
if (a[i] == x)
return i;
}
return -1;
}

[ CS1020E AY1617S1 Lecture 9 ]


29
Analysis 2: Sequential Search
 Time spent in each iteration through the loop is at
most some constant c1
 Time spent outside the loop is at most some
constant c2
 Maximum number of iterations is n
 Hence, the asymptotic upper bound is
c1n + c2 = O(n)
 Observation
 In general, a loop of n iterations will lead to O(n) growth rate
 This is an example of Worst Case Analysis

[ CS1020E AY1617S1 Lecture 9 ]


30
Analysis 3: Binary Search
 Important characteristics
 Requires array to be sorted
 Maintain sub-array where x might be located
 Repeatedly compare x with m, the middle of
current sub-array
 If x = m, found it!
 If x > m, eliminate m and positions before m
 If x < m, eliminate m and positions after m

 Iterative and recursive implementations

[ CS1020E AY1617S1 Lecture 9 ]


31
Binary Search (Recursive)
int binarySearch(int a[], int x, int low, int high) {
if (low > high) // Base Case 1: item not found
return -1;

int mid = (low+high) / 2;

if (x > a[mid])
return binarySearch(a, x, mid+1, high);
else if (x < a[mid])
return binarySearch(a, x, low, mid–1);
else
return mid; // Base Case 2: item found
}

[ CS1020E AY1617S1 Lecture 9 ]


32
Binary Search (Iterative)
int binSearch(int a[], int len, int x) {
int mid, low = 0;
int high = len-1;

while (low <= high) {


mid = (low+high) / 2;
if (x == a[mid])
return mid;
else if (x > a[mid])
low = mid+1;
else
high = mid-1;
}
return -1; // item not found
}

[ CS1020E AY1617S1 Lecture 9 ]


33
Analysis 3: Binary Search (Iterative)
 Time spent outside the loop is at most c1
 Time spent in each iteration of the loop is at
most c2
 For inputs of size n, if the program goes through
at most f(n) iterations, then the complexity is
c1 + c2f(n) or O(f(n))
 i.e. the complexity is decided by the number of
iterations (loops)

[ CS1020E AY1617S1 Lecture 9 ]


34
Analysis 3: Finding f(n)
 At any point during binary search, part of array is “alive”
(might contain x)
 Each iteration of loop eliminates at least half of
previously “alive” elements
 At the beginning, all n elements are “alive”, and after
 One iteration, at most n/2 are left, or alive
 Two iterations, at most (n/2)/2 = n/4 = n/22 are left
 Three iterations, at most (n/4)/2 = n/8 = n/23 are left
 ...
 k iterations, at most n/2k are left
 At the final iteration, at most 1 element is left
[ CS1020E AY1617S1 Lecture 9 ]
35
Analysis 3: Finding f(n)
 In the worst case, we have to search all the way up
to the last iteration k with only one element left
 We have
n/2k = 1  2k = n  k = log2(n) = lg(n)
 Hence, the binary search algorithm takes O(f(n)), or
O(lg(n)) time
 Observation
 In general, when the domain of interest is reduced by a
fraction for each iteration of a loop, then it will lead to
O(log n) growth rate

[ CS1020E AY1617S1 Lecture 9 ]


36
Analysis of Different Cases
 For an algorithm, three different cases of analysis
 Worst-Case Analysis
 Look at the worst possible scenario
 Best-Case Analysis
 Look at the ideal case
 Usually not useful
 Average-Case Analysis
 Probability distribution should be known
 Hardest/impossible to analyze

 Example: Sequential Search


 Worst-Case: target item at the tail of array
 Best-Case: target item at the head of array
 Average-Case: target item can be anywhere
[ CS1020E AY1617S1 Lecture 9 ]
37
Summary
 Algorithm Definition
 Algorithm Analysis
 Counting operations
 Asymptotic Analysis
 Big-O notation (Upper-Bound)

 Three cases of analysis


 Best-case
 Worst-case
 Average-case

[ CS1020E AY1617S1 Lecture 9 ]


38

You might also like