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

2 Program Complexities

The document discusses algorithms and their analysis, explaining that an algorithm is a sequence of computational steps to solve a problem, and that analyzing algorithms involves proving their correctness and analyzing their performance as problem size increases. It provides the example of insertion sort, explaining the sorting problem, how insertion sort works, proving its correctness, and analyzing its running time, showing it has quadratic worst-case time complexity.

Uploaded by

Dickson Wong
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
69 views

2 Program Complexities

The document discusses algorithms and their analysis, explaining that an algorithm is a sequence of computational steps to solve a problem, and that analyzing algorithms involves proving their correctness and analyzing their performance as problem size increases. It provides the example of insertion sort, explaining the sorting problem, how insertion sort works, proving its correctness, and analyzing its running time, showing it has quadratic worst-case time complexity.

Uploaded by

Dickson Wong
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 37

Data Structures

Program Complexities

1
Algorithms
 What is an algorithm?
A sequence of elementary computational steps that transform
the input into the output
 What for?
A tool for solving well-specified computational problems, e.g.,
Sorting, Matrix Multiplication
 What do we need to do with an algorithm?
Correctness Proof:
for every input instance, it halts with the correct output
Performance Analysis (1 second or 10 years?):
How does the algorithm behave as the problem size gets large
both in running time and storage requirement

2
A Sorting Problem
Input : <a0, a1, … , an-1>

Output: A permutation (re-ordering) <a’0, a’1, … , a’n-1> of


the input sequence such that a’0  a’1  …  a’n-1

Example:

<22, 51, 34, 44, 67, 11> => <11, 22, 34, 44, 51, 67>

3
Insertion Sort
Note that when we are
dealing with kth number, the
5, 3, 1, 2, 6, 4 first k-1 numbers are
already sorted.
3, 5, 1, 2, 6, 4
The kth number is inserted
1, 3, 5, 2, 6, 4 in the correct position.
1, 2, 3, 5, 6, 4
1, 2, 3, 5, 6, 4
1, 2, 3, 4, 5, 6

4
Insertion Sort
5, 3, 1, 2, 6, 4  To sort A[0,1,…,n-1] in place
3, 5, 1, 2, 6, 4  Steps:
1, 3, 5, 2, 6, 4  Pick element A[j]
 Move A[j-1,…,0] to the right until
1, 2, 3, 5, 6, 4
proper position for A[j] is found
1, 2, 3, 5, 6, 4
1, 2, 3, 4, 5, 6 Example 1 3 5 2 6 4

0 … j j+1 . . 1 3 5 2 6 4
1 3 5 5 6 4
Currently Currently 1 3 3 5 6 4
sorted unsorted 1 2 3 5 6 4
part part
5
Insertion Sort
A[0] A[1] A[2] A[3] A[4] A[5]
Insertion-Sort (A)
1. for j=1 to n-1 j=1 5 3 1 2 6 4
2. key=A[j]
3. i=j-1
j=2 3 5 1 2 6 4
4. while i>=0 and A[i]>key j=3 1 3 5 2 6 4
5. A[i+1]=A[i]
6. i=i-1 j=4 1 2 3 5 6 4
7. A[i+1]=key j=5 1 2 3 5 6 4
1 2 3 4 5 6
j=3 1 3 5 2 6 4
1 3 5 5 6 4
1 3 3 5 6 4
1 2 3 5 6 4 6
Correctness of Algorithm
 Why can the algorithm correctly sort?
 We only consider algorithms with loops
Find a property as loop invariant
 How to show something is loop invariant?
Initialization:
It is true prior to the first iteration of the loop
Maintenance:
If it is true before an iteration, it remains true before the
next iteration
Termination:
When the loop terminates, the invariant gives a useful
property that helps to show the algorithm is correct

7
Running time of Insertion Sort
Insertion-Sort(A) Cost times
1 for j = 1 to n-1 c1 n
2 key = A[j] n-1
3 i = j-1 c2 n-1
4 while i >= 0 and A[i] > key j=1..n-1 (tj+1)
5 A[i+1] = A[i] c3 j=1..n-1 tj
6 i=i-1 j=1..n-1 tj
c4
7 A[i+1] = key n-1
c1, c2, .. =c5running time for
executing line 1, line 2, etc.
tj = no. ofc6 times that line 5,6
are executed, for each j.
The running time T(n) c7
= c1*n+c2*(n-1)+c3*(n-1)+c4*(j=1..n-1 (tj+1))+c5*(j=1..n-1 tj)+c6*(j=1..n-1 tj)+c7*(n-1)
8
Analyzing Insertion Sort
T(n) = c1*n+c2*(n-1)+c3*(n-1)+c4*(j=1..n-1 (tj+1))+
c5*(j=1..n-1 tj)+c6*(j=1..n-1 tj)+c7*(n-1)

Worse case:
Reverse sorted: for example 6,5,4,3,2,1
 inner loop body executed for all previous elements.
 tj=j.

 T(n) = c1*n+c2*(n-1)+c3*(n-1)+c4*(j=1..n-1 (j+1))+


c5*(j=1..n-1 j)+c6*(j=1..n-1 j)+c7*(n-1)

 T(n) = An2+Bn+C Note: j=1..n-1 j = n(n-1)/2


j=1..n-1 (j+1) = (n+2)(n-1)/2
9
Analyzing Insertion Sort
T(n)=c1*n+c2*(n-1)+c3*(n-1)+c4*(j=1..n-1 (tj+1))+c5*(j=1..n-1 tj)+c6*(j=1..n-1 tj)+c7*(n-1)

Worst case Reverse sorted  inner loop body executed for all
previous elements. So, tj=j.

 T(n) is quadratic: T(n)=An2+Bn+C

Average case Half elements in A[0..j-1] are less than A[j]. So, tj = j/2

 T(n) is also quadratic: T(n)=An2+Bn+C

Best case Already sorted  inner loop body never executed. So,
tj=0.

 T(n) is linear: T(n)=An+B 10


Kinds of Analysis
(Usually) Worst case Analysis:
T(n) = max time on any input of size n
Knowing it gives us a guarantee about the upper bound.
In some cases, worst case occurs fairly often

(Sometimes) Average case Analysis:


T(n) = average time over all inputs of size n
Average case is often as bad as worst case.
(Rarely) Best case Analysis:
Cheat with slow algorithm that works fast on some input.
Good only for showing bad lower bound.

11
Kinds of Analysis
Worst case

Average case

Best case

0 1 2 3 4 n

 Worst Case: maximum value


 Average Case: average value
 Best Case: minimum value 12
Order of Growth
Examples:
Running time of algorithm in microseconds
(in term of data size n)

f(n) n=20 n=40 n=60


Algorithm A Log2n 4.32 * 10-6sec 5.32 * 10-6sec 5.91 * 10-6sec
Algorithm B Sqrt(n) 4.47 * 10-6sec 6.32 * 10-6sec 7.75 * 10-6sec
Algorithm C n 20 * 10-6sec 40 * 10-6sec 60 * 10-6sec
Algorithm D n log2n 86 * 10-6sec 213 * 10-6sec 354 * 10-6sec
Algorithm E n2 400 * 10-6sec 1600 * 10-6sec 3600 * 10-6sec
Algorithm F n4 0.16 sec 2.56 sec ______ sec
Algorithm G 2n 1.05 sec 12.73 days ______ years
Algorithm H n! 77147 years 2.56 * 1034 years 2.64 * 1068 years
13
Order of Growth
Assume: an algorithm can solve a problem of size n in f(n) microseconds
(10-6 seconds).

f(n)
90000
log2n
80000
microseconds

70000 Sqrt n
60000 n
50000 nlog2n
40000 n2
30000
n4
20000
2n
10000
0 n n!

Note: for example,


For all f(n) in (n4), the shapes of their curves are nearly the same 14as
f(n)=n4.
Asymptotic Notation

How can we indicate running times of


algorithms?
Need a notation to express the growth rate
of a function
A way to compare “size” of functions:
-notation (“Big-oh”)   (upper bound)
-notation (“Big-omega”)   (lower bound)
-notation ( “theta”)   (sandwich)

2015-16B Complexity Analysis 15


-notation (1/2)
-notation provides an asymptotic upper
bound of a function.
For a given function g(n), we denote
(g(n)) (pronounced “big-oh” of g of n) by
the set of functions: f(n) = (g(n))

(g(n)) = {f(n): there exist positive


constants c and n0 such that
0  f(n)  cg(n) for all n  n0}

2015-16B Complexity Analysis 16


-notation (2/2)

We write f(n) = (g(n)) to


Indicate that f(n) is a member of the set (g(n))
Give that g(n) is an upper bound for f(n) to
within a constant factor
Example: 2n2 = (n3), with c = 1 and n0 =
2
When n = 1: 2(1)2 = 2  (1)3 = 1 
When n = 2: 2(2)2 = 8  (2)3 = 8 
When n = 3: 2(3)2 = 18  (3)3 = 27 
2015-16B Complexity Analysis 17
-notation (1/2)
-notation provides an asymptotic lower
bound of a function.
For a given function g(n), we denote
(g(n)) (pronounced “big-omega” of g of n)
by the set of functions: f(n) = (g(n))

(g(n)) = {f(n): there exist positive


constants c and n0 such that
0  cg(n)  f(n) for all n  n0}

2015-16B Complexity Analysis 18


-notation (2/2)

We write f(n) = (g(n)) to


Indicate that f(n) is a member of the set (g(n))
Give that g(n) is a lower bound for f(n) to within
a constant factor
Example: n2 + n = (n2), with c = 1 and
n0=1
When n = 1: (1)2 + 1 = 2  (1)2 = 1 
When n = 2: (2)2 + 2 = 6  (2)2 = 4 
When n = 3: (3)2 + 3 = 12  (3)2 = 9 
2015-16B Complexity Analysis 19
-notation (1/2)

-notation provides an asymptotically


tight bound of a function.
For a given function g(n), we denote
(g(n)) (pronounced “theta” of g of n) by
the set of functions: f(n) = (g(n))

(g(n)) = {f(n): there exist


positive constants c1, c2 and n0
such that 0  c1g(n)  f(n) 
c2g(n) for all n  n0}
2015-16B Complexity Analysis 20
-notation (2/2)
 Theorem
f(n) = (g(n)) if and only if f(n) = (g(n)) and f(n) =
(g(n))

 Example: n2/2 - 2n = (n2), with c1 = 1/4,


c2=1/2, and n0 = 8
When n = 7: 1/4[(7)2] = 12.25  (7)2/2 - 2(7) = 10.5
 1/2[(7)2] = 24.5 
When n = 8: 1/4[(8)2] = 16  (8)2/2 - 2(8) = 16 
1/2[(8)2] = 32 
When n = 9: 1/4[(9)2] = 20.25  (9)2/2 - 2(9) = 22.5
 1/2[(9)2] = 40.5 
2015-16B Complexity Analysis 21
O versus o
What about “<”?
o versus O : o means better e.g. n=o(n2)
 Why 100n=O(n)?
When n is very big like 10000000000000000
100n: 1000000000000000000
 n: 10000000000000000
nearly the same

 Why n=o(n2)?
When n is 10000000000000000
n2 is 100000000000000000000000000000000
Differ a lot! 22
Asymptotic Notation
Relationship between typical functions
log n = o (n)
n = o (n log n)
nc = o (2n) where nc may be n2, n4, etc.
If f(n)=n+log n, we call log n lower order terms
(You are not required to analyze, but remember these
relations)
log n < sqrt(n) < n < nlog n < n2 < n4 < 2n < n!

23
Asymptotic Notation
When calculating asymptotic running time
Drop low-order terms
Ignore leading constants
Example 1: T(n) = An2+Bn+C
An2
T(n) = O(n2)
Example 2: T(n) = Anlogn+Bn2+Cn+D
Bn2
T(n) = O(n2)

24
Asymptotic Performance

Insertion-Sort(A)
Very often the 1 for j = 1 to n-1
O(n2)
algorithm 2 key = A[j]
complexity can 3 i = j-1
be observed 4 while i >= 0 and A[i] > key
directly from 5 A[i+1] = A[i]
simple 6 i=i-1
algorithms 7 A[i+1] = key

There are 4 very useful rules for such Big-Oh analysis ...
25
Asymptotic Performance
General rules for Big-Oh Analysis:

Rule 1. FOR LOOPS Rule 2. NESTED FOR LOOPS


The running time of a for loop is at The total running time of a
most the running time of the statement inside a group of nested
statements inside the for loop loops is the running time of the
(including tests) times no. of iterations statement multiplied by the product
of the sizes of all the loops.
for (i=0;i<N;i++)
a++; O(N) for (i=0;i<N;i++)
for (j=0;j<N;j++)
k++; O(N2)
Rule 3. CONSECUTIVE STATEMENTS
Count the maximum one. Rule 4. IF / ELSE
for (i=0;i<N;i++) For the fragment:
O(N2)
a++; If (condition) take the test +
S1 the maximum
for (i=0;i<N;i++)
else for S1 and S2.
for (j=0;j<N;j++) S2,
26
k++;
Asymptotic Performance

Example of Big-Oh Analysis:

void function1(int n) void function2(int n)


{ int i, j; { int i;
int x=0; int x=0;

for (i=0;i<n;i++) for (i=0;i<n/2;i++)


x++; x++;
}
for (i=0;i<n;i++)
for (j=0;j<n;j++) This function is O(__)
x++;
}

This function is O(__)

27
Asymptotic Performance
Example of Big-Oh Analysis:

void function3(int n) void function4(int n)


{ int i; { int i;
int x=0; int x=0;

if (n>10) for (i=0;i<10;i++)


for (i=0;i<n/2;i++) for (j=0;j<n/2;j++)
x++; x--;
else }
{ for (i=0;i<n;i++)
for (j=0;j<n/2;j++) This function is O(__)
x--;
}
}

This function is O(__)


28
Asymptotic Performance
Example of Big-Oh Analysis:

void function5(int n)
{ int i;
for (i=0;i<n;i++)
Suppose
if (IsSignificantData(i)) IsSignificantData is O(n),
SpecialTreatment(i); SpecialTreatment is O(n log n)

This function is O(____)

29
Comparison of Good and Bad

Coin Flipping
There are N rows of coins
Each row consists of 9 coins
They formulate a matrix of size N*9
Some coins are heads up and some are tails up
We can flip a whole row or a whole column
every time
Your program need to find a flipping method
that can make the number of “heads up” coins
maximum
30
Asymptotic Performance
 Recursion
int Power(int base,int pow)
{ if (pow==0) return 1;
else return base*Power(base,pow-1);
}
 Example
32=9
Power(3,2)=3*Power(3,1)
Power(3,1)=3*Power(3,0)
Power(3,0)=1

T(n): the number of multiplications needed to compute Power(3,n)


T(n)=T(n-1)+1; T(0)=0
T(n)=n
Function T(n) is O(n)
31
Asymptotic Performance
Why recursion?
Can’t we just use iteration (loop)?
The reason for recursion
Easy to program in some situations
Disadvantage
More time and space required
Example:
Tower of Hanoi Problem

32
Tower of Hanoi
Given some rods for stacking disks.
The problem:
Rules: Use fewest steps to move all disks
from the source rod to the target
(1) The disks must be stacked in
without violating the rules through
order of size. the whole process (given one
(2) Each time move 1 disk. intermediate rod for buffering)?

a source rod an intermediate rod a target rod 33


Tower of Hanoi
Suppose you can manage the n-1 disks
How do you solve the n disks case?
A recursive solution:
Step 1: Move the top n-1 disks from source rod
to intermediate rod via target rod
Step 2: Move the largest disk from source rod
to target rod
Step 3: Move the n-1 disks from intermediate
rod to target rod via source rod

34
Tower of Hanoi
void Towers (int n, int Source, int Target, int Interm)
{ if (n==1)
cout<<“From”<<Source<<“To”<<Target<<endl;
else
{ Towers(n-1, Source, Interm, Target);
Towers(1, Source, Target, Interm);
Towers(n-1, Interm, Target, Source);
}
}

How many “cout” are executed?


T(n)=2T(n-1)+1
35
Recursive Relation
T(n)=T(n-1)+A; T(1)=1
 T(n)=O(n)
T(n)=T(n-1)+n; T(1)=1
 T(n)=O(n2)
T(n)=2T(n/2) + n; T(1)=1
 T(n)=O(n log n)
More general form: T(n)=aT(n/b)+cn
Master’s Theorem
(You are not required to know)

36
Learning Objectives
1. Understand the meaning of O and o and
able to use
2. Analyze program complexities for simple
programs
3. Able to compare which function grows
faster
4. Able to do worst case analysis

D:1; C:1,2; B:1,2,3; A:1,2,3,4


37

You might also like