brian mitchell ([email protected]) - drexel university mcs680-fcs 1 running time of programs...
TRANSCRIPT
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
1
Running Time
of
Programs
int MSTWeight(int graph[][], int size){
int i,j;int weight = 0;
for(i=0; i<size; i++)for(j=0; j<size; j++)
weight+= graph[i][j];
return weight;}
1
1
nn
O(1)
O(1)
O(n) O(n)
Running Time = 2O(1) + O(n2) = O(n2)
MCS680:Foundations Of
Computer Science
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
2
Introduction
• Choosing an algorithm– Simplicity
• Easy to code– Minimize code defects (bugs)
• Generally tradeoff “easy-to-implement” for slower performance
– Good for small or controlled input sizes– Selection Sort versus Merge Sort
– Clarity• Algorithms should be clear and well-
documented– Simplifies software maintenance issues
– Efficiency• Generally efficient algorithms are harder to
understand and implement
• Efficient algorithms are required when:– We are concerned about running time
» Generally a function of input size
– We are concerned about runtime resources» Memory, bandwidth, processor capacity
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
3
Measuring Running Time
• Approaches– Benchmarking
• Develop representative input samples– Execute algorithm against input samples
– Measure performance (Execution Time)
• Must be careful of algorithm anomalies – Some algorithms performance is a direct
function of the input data and not the size of the input data
– Analysis• Group inputs according to size
– The number of elements to be sorted, the number of nodes or edges in a graph, etc.
• Determine a function, T(n), to model the number of units of time taken by an algorithm on any input size, n.
• Because some algorithms performance is affected by the particular input sequence we should consider
– Worst Case and Average Case running times
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
4
Running Time Example -Inner Loop of Selection Sort
• Assignment of small to i takes 1 time unit
• Assignment of j=(i+1) takes 1 time unit
• Consider the if statement:– Comparison takes 1 time unit
– Assignment of j to small takes 1 time unit
– Worst case is that the comparison and assignment operation happens on every loop iteration
– Thus, the if statement takes 2 time units
• Consider the for loop– Loop is executed (n-i) times
– Each time j is compared to n and incremented• Total of 2 time units per loop iteration
small = i;for (j=(i+1); j<n; j++)if(A[j] < A[small])small = j;
Consider the following code fragment:
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
5
Running Time Example -Inner Loop of Selection Sort
• Total Running Time– Loop Execution Time:
• Body (if statement) is 2 units• Loop is executed (n-i) times• Loop management takes 2 units per iteration• Total loop time is 4(n-i)
– Initialization/Termination Time:• 1 unit for assigning small from i• 1 unit for initializing j (to i+1)• 1 additional unit for the last (j<n) comparison
– Happens when j=n (last time around the loop)
• Total Running Time– T(n) = 4(n-i) + 3, letting m=(n-i+1) we get:– T(m) = 4m -1 (Linear Growth!)
small = i;for (j=(i+1); j<n; j++)if(A[j] < A[small])small = j;
Consider the following code fragment:
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
6
Approximate Running Time-“Big-Oh”
• Running Time Factors– The computer running the algorithm
• CPU, Architecture, Bus, ...
– The compiler used to generate the machine code
• Some compilers generate better code that others
– Prevents us from determining the actual running time of the program
• Approximate Running Time– Use “Big-Oh” notation
– Use of “Big-Oh” abstracts• Average machine instructions generated by the
compiler
• The number of machine instructions executed per second on a given computer
– Promotes a “level playing field” for comparing algorithm running times
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
7
Simplifying Analysis With“Big-Oh”
• In a previous example we estimated the running time of the inner loop of the Selection Sort.– T(m) = 4m - 1
• However we made some assumptions that are probably not true– All assignments take the same amount of time– A comparison takes the same amount of time as
an assignment
• A more accurate assessment would be:– The running time of the inner loop of the
Selection Sort is some constant times m plus or minus another constant
• T(m) = am + b where {a,b} are unknown constants
• Estimate with Big-Oh:– Running time of inner loop of selection sort is
O(m).
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
8
Definition-Big-Oh
• Consider O(f(m))– Definition of O(f(m)) is:
• The worst case running time is some constant times f(m)
– Examples• O(1) = some constant times 1• O(m) = some constant times m• O(m2) = some constant times m2
• O(lg m) = some constant times lg m
– Because a constant is built into the Big-Oh notation we can eliminate any constants from our runtime analysis, thus
• T(m) = 4m - 1 = O(4m - 1)• O(4m - 1) = O(4m) + O(1)• But because Big-Oh notation has a constant built
in:• O(4m) + O(1) = O(m) + O(1) but O(1) is a
constant and constants are built in to Big-Oh– O(4m - 1) = O(m)
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
9
Big-OhNotation
• In the previous slide we claimed thatO(4m - 1) is O(m)– Recall that Big-Oh notation is a worst case
upper bound on execution complexity
– We can prove that O(4m-1) is O(m) if we can find a constant, c, that holds for
• (4m - 1) <= cm for all m>= 0
• Hence if c=4 then (4m-1) <= 4m for all m>=0
• Thus O(4m-1) is O(4m)
• Because Big-Oh notation has a constant built into the definition we can show that O(4m) is O(m)
– Suppose that O(4m) = O(m)
– For O(4m) choose the implicit constant to be 1
– For O(m) choose the implicit constant to be 4
• Thus because of the implicit constant we know that O(4m) is O(m)
– Thus we showed by manipulating the internal constant that O(4m-1) is O(4m) which is O(m)
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
10
Simplifying Big-OhExpressions
• Remember:– Big-Oh expressions infer a built-in constant– Big-Oh expressions are a worst-case upper bound
for execution complexity
• Simplification Rules– Constant Factors Do Not Matter!
• Because Big-Oh expressions implicitly contain a constant, you may drop the explicit constant
– O(10000m) is O(m) implicit constant is 10000
– Low Order Terms Do Not Matter!• Remember that Big-Oh is an upper bound!
• If T(n) = aknk+ak-1nk-1+...+a2n2+a1n+a0 thenT(n) [ak + ak-1 + ... + a2 + a1 + a0]nk
• Thus T(n) is O([ak + ak-1 + ... + a2 + a1 + a0]nk)
• If we let c = [ak + ak-1 + ... + a2 + a1 + a0] then c is a constant
• Thus T(n) is O(c•nk)
• Thus T(n) is O(nk) because constant factors do not matter
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
11
Simplifying Big-Oh Expressions: An Example
• Suppose that we have a programs whose running time is T(0)=1, T(1)=4, T(2)=9, and in general T(n) = (n+1)2:– Thus T(n) = n2 + 2n + 1
– Because we are interested in an upper bound we can state that:
• T(n) n2 + 2n2 + 1n2
• Thus T(n) 4n2 for all n > 0 because a polynomial expression is always less then the sum of the polynomial coefficients taken to the power of the highest power of n
– This demonstrates the rule that low order terms do not matter
• Thus T(n) is O(4n2)
• But recall the rule that constant factors do not matter
• Thus T(n) is O(n2)
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
12
Simplifying Big-Oh Expressions: An Example
T(n) = (n+1)2 versus O(n2)
0
200000
400000
600000
800000
1000000
1200000
0 100 200 300 400 500 600n
Exe
cuti
on
Co
mp
lexi
ty
(n+1)^2O(n^2)
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
13
Simplifying Big-Oh Expressions
• We just saw two mechanisms for simplifying Big-Oh expressions– Dropping constant factors
– Dropping low order terms
– These rules will greatly simplify our analysis of “real” programs and algorithms
• Other Rules– Big-Oh expressions are transitive
• Recall that transitivity means that if A B and B C then A C
• The relationship “is of Big-Oh” is another form of transitivity
– If f(n) is O(g(n)) and O(g(n)) is O(h(n)) then it follows by transitivity that f(n) is O(h(n))
– Proof: Let c1 and c2 be constants. Therefore, f(n) c1•g(n) and g(n) c2•h(n). Thus,f(n) c1c2 •h(n) by transitivity. But c1c2 is a constant resulting in f(n) being of O(h(n))
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
14
Tightness of Big-OhExpressions
• Goal: we want the “tightest” big-oh upper bound that we can prove– Because big-oh is an upper bound we can
imply that:• O(n) is O(n2) or O(n3)
• Conversely, O(n3) is not O(n2) or O(n)
• In general O(nk) – IS O(nx) for x k
– But it IS NOT O(nz) for z < k
– The following table lists some of the more common running times for programs and their informal names:
Big-Oh Informal Name
O(1) constantO(n) linearO(log n) logarithmicO(lg n) logarithmicO(n log n) n log nO(n lg n) n log nO(n2) quadraticO(nk) polynomialO(2n) exponential
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
15
Logarithms in Big-Oh Analysis
• Consider the following function that returns TRUE if the input number is a power of 2
• Analysis
– The while loop is executed until x reaches 1 or until x becomes an odd value
– Thus we execute the loop by dividing n by 2 a maximum of k times for n = 2k
– Taking the log of both sides we get• log2 n = k which is lg n
– Thus PowerOfTwo() is O(lg n)
#define ODD(x) ((x%2) == 1)
BOOL PowerOfTwo(unsigned int x){if (x == 0) return FALSE;while (x > 1) if(ODD(x))return FALSE;
elsex /= 2;
return TRUE;}
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
16
PowerOfTwo()Execution Complexity
T(n) versus O(lg n)
0
1
2
3
4
5
6
0 5 10 15 20 25 30 35 40
n
Ex
ec
uti
on
Tim
e
T(n)O(lg n)
• Notice how T(n) is bounded by O(lg n)
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
17
Summation Rule For Big-Oh Expressions
• Technique for summing Big-Oh expressions– As shown before we can drop constants
and lower-order terms when analyzing running times
– Same rule applies to summing Big-Oh expressions
– Also recall that Big-Oh expressions are an upper bound
• O(n) is O(n2)
• O(lg n) is O(n)
– RULE: Given O(f(n)) + O(g(n)) take the part with the larger complexity and drop the other part
• O(n) + O(n2) = O(n2)
• O(lg n) + O(n) = O(lg n)
• O(1) + O(n) = O(n)
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
18
Example: Summation of Big-Oh Expressions
• Consider the following algorithm that places 1’s in the diagonal of a matrix
• Analysis
– The zeroing phase of the algorithm takes two loops to initialize all matrix elements to zero• Both loops are bounded [0...n], this is O(n2)
– The diagionalization phase of the algorithm requires one loop to place 1’s on the matrix diagional• Loop is bounded [0...n], this is O(n)
– Total execution time is O(n2) + O(n) = O(n2)
void DiagonalOnes(int A[][], int n){int i,j;
for(i = 0; i < n; i++)for(j = 0; j < n; j++)A[i][j] = 0;
for(i = 0; i < n; i++)A[i][i] = 1;
}
O(n2)
O(n)
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
19
Analyzing the Running Time of a Program
• Goal: Develop techniques for analyzing algorithms and programs– Simple and tight bounds on execution
complexity
• Break the program or algorithm up into individual parts– Simple statements
– Loops
– Conditional statements
– Procedure/Function calls
• Analyze the individual parts in context to develop a Big-Oh expression
• Simplify the Big-Oh expression
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
20
Simple Statements
• All simple statements take O(1) time unless the statement is a function call– O(1) time indicates that a constant amount
of time is required to execute the statement
– Simple statements are:• Arithmetic expressions
– z = a + b;
• Input/Output (file, terminal, network)– gets(name);
– printf(“%s\n”,”Hello World!”);
• Array or structure accessing statements– a[1][2] = 9;
– customer.age = 30;
– linkedListPtr = linkedListPtr->next;
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
21
Analyzing For Loops
• For loops are syntactically developed to specify the lower bound, the upper bound and the increment of the looping construct– for(i = 0; i < n; i++)
• Given a for loop it is easy to develop an upper bound for the number of times that the loop will be executed– Can always leave the loop early with a
goto, return or break statement
• Goal: Determine an upper bound on the number of times that loop body will be executed
• Analysis: Upper bound on the execution of a for loop is – (number of times loop is executed) *
(execution time for body of the loop) +O(1) for initializing the loop index +O(1) for the last comparison
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
22
Analyzing Conditional Statements
• Conditional statements typically takes the form:– if <condition> then
<if-part>else
<else-part>– Execution a conditional statement involves
• A condition to test
• An if-part that is executed if the condition is TRUE
• An optional else-part that is executed if the condition is FALSE
– Condition part takes O(1) unless it involves a function call
– Let the if-part take O(f(n))
– Let the else-part (if present) take O(g(n))
– Thus• If the else-part is missing, running time is O(f(n))
• If the else-part is present, running time is O(max(f(n),g(n)))
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
23
Running Time Example:Simple, Loop and Conditionals• Consider the following code fragment
• Analysis
– Running time of the if-part [f(n)] is O(n2)
– Running time of the else-part [g(n)] is O(n)
– Total execution time is O(max(f(n),g(n))) which is O(max(n2,n))
– Thus total execution time is O(n2)
if(A[0][0] = 0)for(i = 0; i < n; i++)for(j = 0; j < n; j++)A[i][j] = 0;
elsefor(i = 0; i < n; i++)A[i][j] = 1;
O(n)O(1)O(n2)
O(n)O(1)
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
24
Analyzing Blocks
• A block of code consists of a sequence of one or more statements– begin...end in Pascal
– {...} in C, C++ and Java
• Statements in a block may be– Simple statements
– Complex statements (for, while, if,...)
• Total execution time is the sum of all of the statements in the block– Use techniques (rule of sums) to simplify
the expression
• Thus if a block contains n statements, the execution time is:
n
iiStatementOblockO
1
)()(
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
25
Analyzing While and RepeatLoops
• There is no (implicit) upper limit on the number of times that a while or repeat loop is executed
• Analysis must determine an upper bound on the number of times that the loop is executed– Execution complexity is the number of
times around the loop multiplied by the execution complexity of the loop body
• The following code fragment can be shown to be O(n)
BOOL FindIt(int A[], int n){int i = 0;
while((A[i] != val)&&(i < n))i++;
return (i != n)}
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
26
Using Trees to Model Analysis of Source Code Fragments
• Technique: Build tree and develop execution complexity by traversing the tree from the bottom up to the tree root
(1) for(i=0; i<(n-2); i++){
(2) small = i;(3) for(j=i+1; j<n; j++)(4) if(A[j] < A[small])(5) small = j;(6) temp = A[small];(7) A[small] = A[i];(8) A[i] = temp;
}
for [1-8]
block [2-8]
[2] for [3-5] [6] [7] [8]
if [4-5]
[2]
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
27
Analyzing Procedure Calls
• Task for analyzing code with procedure calls involves – Treating the procedure call as a simple
statement
– Use O(f(n)) is place of O(1) for the procedure call where f(n) is the execution complexity of the actual procedure call
• Must fully analyze the procedure call prior to evaluating it in context
• If the procedure is a recursive call then it must be analyzed by using other techniques– Generally the execution complexity can be
modeled by performing an inductive proof on the number of times that the recursive call is performed
• See the previous analysis of the Factorial() function
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
28
Analyzing Recursive Procedure Calls
• Analyzing recursive procedure calls is more difficult then analyzing standard procedure calls– Technique: To analyze a recursive procedure
call we must associate with each procedure P an unknown running time Tp(n) that defines P’s running time as a function of n
• Must develop a recurrence relation– Tp(n) is normally developed by an induction on
the size of argument n
– Must set up the recurrence relation in a way that ensures that the size of the argument n decreases as the recurrence proceeds
– The recurrence relation must specify 2 cases• The argument size is sufficiently small that no
recursive calls will be made by P
• The argument size is sufficiently large that recursive calls will be made
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
29
Recursive Call Analysis -Technique
• To develop Tp(n) we examine the procedure P and do the following:– Use the techniques that we already
developed to analyze P’s non-recursive call statements
– Let Tp(n) be the running time of the recursive calls in P
– Now reevaluate P twice:• Develop the base case. Evaluate P on the
assumption that n is sufficiently small that no recursive procedure calls are made
• Develop the inductive definition. Evaluate P on the assumption that n is large enough to result in recursive calls being made to P
– Replace big-oh terms such as O(f(n)) by a constant times the function involved
• O(f(n)) cf(n)
– Solve the resultant recurrence relation
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
30
Recursive Call Analysis Example - Factorial
• Consider the following code fragment
• Analysis
– Determination of a good recursive procedure• There is a basis case (n <= 1)
• There is an inductive case for n > 1
– For the basis case (n <= 1)• Lines (1) and (2) are executed, each are O(1), thus the
total execution time for the base case is O(1)
– For the inductive case (n > 1)• Lines (1) and (3) are executed, line (1) is O(1) and line
(3) is O(1) for the multiplication and T(n-1) for the recursive call
• Thus total time for the inductive case is:O(1) + T(n-1)
int Factorial(int n){
(1) if (n <= 1)(2) return 1;
else(3) return n * Factorial(n-1);
}
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
31
Recursive Call Analysis Example - Factorial
• Analysis (con’t)– Thus the running time of Factorial() can be
modeled by the following recurrence relation• Basis: T(1) = O(1)
• Inductive: T(n) = O(1) + T(n-1)
– Now replace big-oh expressions by constants• Basis: T(1) = a
• Inductive: T(n) = b + T(n-1), for n > 1
– Now solving the recurrence relation• T(1) = a
• T(2) = b + T(1) = a + b
• T(3) = b + T(2) = a + 2b
• In general, T(n) = a + (n-1)b for all n>1
• T(n) = a + (n-1)b = a + bn - b = (a-b) + bn
• Thus T(n) = bn + (a-b), but (a-b) is a constant
• The result is T(n) = bn + c (where c = (a-b))
• In big-oh terms T(n) is O(n) + O(1) = O(n)
• Thus, Factorial() is O(n)
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
32
Analysis of MergeSort
• Analysis of MergeSort()– Must determine the running time of
• Split() and Merge()
– Use the recursive technique to analyze MergeSort()
void MergeSort(mList list){mList SecondList;
if (list != NULL){if(list->next != NULL){SecondList = Split(list);MergeSort(list);MergeSort(SecondList);list = Merge(list,SecondList);
}}
}
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
33
Analysis of Split()
• Analysis of Split()– Basis Case: O(1) + O(1) = O(1)
• Basis case is for n=0 and n=1 (two if statements)
– Inductive Case: O(1)+O(1)+T(n-2)+O(1)• This is O(1) + T(n-2)
mList Split(mList orig){mList secondCell;
if (orig == NULL) return NULL; else if (orig->next == NULL) return NULL; else { secondCell = orig->next;
orig->next = secondCell->next;secondCell->next = Split(secondCell->next);return secondCell;
}}
BA
SIS
IND
UC
TIV
E
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
34
Analysis of Split()
• Analysis of Split (Con’t)– Replace big-oh expressions by constants
• BASIS CASE (n = {0,1}): – List is empty, first if statement is executed
– List length is zero T(0) = a
– List contains 1 element, first and second if statement is executed
– List length is one T(1) = b
• INDUCTIVE CASE (n > 1):– T(n) = O(1) + T(n-2)
– T(n) = c + T(n-2)
– T(2) = c + T(0) = a + c
– T(3) = c + T(1) = b + c
– T(4) = c + T(2) = a + 2c
– T(5) = c + T(3) = b + 2c
• In general for EVEN n, T(n) = a + cn/2
• In general for ODD n, T(n) = b + c(n-1)/2
• For any input list, the size of the list must be EVEN or ODD
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
35
Analysis Of Split()
• Because any input list to Split() must be even or odd, the worst case running time is the maximum time that it takes to process an even or an odd sized input list
• Even Sized List:– T(n) = a + cn/2, let constant m = c/2
– Thus T(n) = a + m(n/2)
– Thus T(n) = O(1) + O(n) = O(n)
• Odd Sized List:– T(n) = b + c(n-1)/2 = b + cn/2 - c/2
– Let constant m = c/2
– Thus T(n) = (b-m) + m(n/2)
– Let constant p = (b-m)
– T(n) = p + m(n/2)
– Thus T(n) = O(1) + O(n) = O(n)
• Thus split is O(n) because both odd and even sized lists are O(n)
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
36
Analysis of Merge()
• Analysis of Merge()– Basis Case:
• List 1 is NULL: O(1) + O(1) = O(1)• List 2 is NULL: O(1) + O(1) + O(1) = O(1)• Thus the basis case is O(1)
mList Merge(mList lst1, mList lst2){mList *ml;if (lst1 == NULL) ml = lst2;
else if (lst2 == NULL) ml = lst1; else if (lst1->element <= lst2->element) {
lst1->next = Merge(lst1->next, lst2); ml = lst1;
} else { lst2->next = Merge(lst1, lst2->next);
ml = lst2; }return ml; //Return the merged list
}
BA
SIS
IND
UC
TIV
E
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
37
Analysis of Merge()
• Analysis of Merge() con’t– Inductive Case (neither list1 or list2 is NULL):
• Recall that the execution time of a conditional is the maximum of running time of all of the possible execution outcomes
• The compound if statement in Merge() has four possible outcomes
• Thus the running time of the statement is equal to: max(O(1), O(1), O(1)+T(n-1), O(1)+T(n-1))
– Both of the recursive options take O(1) for the assignment and T(n-1) for the recursive call
» The size of the input list is reduced by one on each recursive call
• Thus the running time of the compound if statement is T(n) = O(1) + T(n-1)
• We showed in our analysis of the Factorial() function that in general any recurrence relation in the form of T(n) = O(1) + T(n-1) is O(n)
• Hence, the Merge() procedure is O(n)
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
38
Analysis of MergeSort()
• Analysis of MergeSort()– Basis Case:
• The list is empty: O(1)
• The list contains one element: O(1)+O(1) = O(1)
• Thus the basis case is O(1)
void MergeSort(mList list){mList SecondList;
if (list != NULL){if(list->next != NULL){SecondList = Split(list);MergeSort(list);MergeSort(SecondList);list = Merge(list,SecondList);
}}
}
BA
SIS
IND
UC
TIV
E
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
39
Analysis of MergeSort()
• Analysis of MergeSort() con’t– Inductive Case (list contains 2 or more
elements)• O(1) for the two test cases
• O(1) + O(n) for the assignment and the call to Split()
• T(n/2) + T(n/2) = 2T(n/2) for the two calls to MergeSort()
• O(1) + O(n) for the assignment and call to Merge()
• Recall that the running time for a block of code is the sum of all of the running times for each statement in the block of code
• T(n) = O(1)+O(1)+O(n)+2T(n/2)+O(1)+O(n)
• T(n) = 3O(1) + 2O(n) + 2T(n/2)
• Dropping the lower order terms and the leading coefficients we get
• T(n) = O(n) + 2T(n/2)
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
40
Analysis of MergeSort()
• Analysis of MergeSort() con’t– T(n) = O(n) + 2T(n/2)
– Replacing big-oh expressions by constants
– Basis Case: T(1) = O(1) = a
– Inductive Case: T(n) = bn + 2T(n/2)
– For simplicity (easier to show a pattern) assume n is a power of 2 and greater than 1
– T(2) = 2T(1) + 2b = 2a + 2b = 2a+(2*1)b
– T(4) = 2T(2) + 4b = 4a + 8b = 4a+(4*2)b
– T(8) = 2T(4) + 8b = 8a + 24b = 8a+(8*3)b
– T(16) = 2T(8) + 16b = 16a + 64b = 16a+(16*4)b
– In general T(n) = na + [n lg(n)]b
– Thus T(n) is O(n) + O(n lg n)
– Recalling that we are allowed to drop lower order terms we get:
• T(n) = O(n lg n)
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
41
General Approach
• The approach we used to analyze recursive procedure calls, coupled with the general techniques that we developed, can be generalized to handle just about any algorithm– Simple statements are O(1)
– Loops must be analyzed to determine an upper bound
• Complexity is n * (complexity of loop body)– Where n is the upper bound on the number of
times that the loop is executed
– Code blocks are of order:O(Sum(complexity of the block statements))
– Procedure/Function calls are of order:O(f(n)) where f(n) is the complexity of the procedure or function call
– Conditional statements are of the order:O(max(complexity of the conditional parts))
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
42
General Approach
• First, we analyze the simple statements and procedure/function calls– We the replace the big-oh notation by a
constant times the complexity of the statement
• Second, we look at loops and conditionals– For loops we multiply the loop block by
the upper bound of the number of times that the loop executes
– For conditionals we only consider the maximum complexity of the options of the conditional expression
• Third, we look at blocks– We sum the complexity of the block
statements
• Finally we transform the function and constant notation to Big-Oh notation and simplify using the rules that we discussed
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
43
General Approach Example-SelectionSort()
void SelectionSort(int A[], int n){int i,j,small,temp;
for(i=0; i<(n-2); i++){//Get initial smallest elementsmall = i;
//Find actual smallest elementfor(j=i+1; j<n; j++)if(A[j] < A[small])small = j;
//Put smallest element in the first //location of the unsorted portion//of the arraytemp = A[small];A[small] = A[i];A[i] = temp;
}}
O(1
)3O
(1)
O(1
)
O(n
-i)
O(n
)
Brian Mitchell ([email protected]) - Drexel University MCS680-FCS
44
General Approach Example-SelectionSort()
• Analysis– Inner loop block: O(1)
– Inner loop: O(n-i)
– Outer Loop Block:O(1) + O(n-i) + 3O(1) = 4O(1) + O(n-i)= O(1) + O(n-i)= O(n-i) for outer loop block
– Replace big-oh notation by a constant times the growth function
• T(n) = c(n-i) for inner loop block• Loop is executed (n-1) times• T(n) = (n-1)*c(n-i) = (n-1)*(cn-ci)• T(n) = cn2 - cin- cn+ ci
– Let r be another constant = ci
• T(n) = cn2 - rn - cn + r• Thus the running time is:
O(n2)-O(n)-O(n)+O(1) = O(n2)-2O(n)+O(1)• Dropping the lower order terms we show that
the running time of SelectionSort() is O(n2)