CS252 Algorithms Friday, 29 March 2024 + Questions (homework or otherwise) + A couple interesting questions from #reading1 - Why is "polynomial time" the standard criterion for "efficient"? - Why don't we do average-time analysis? + Asymptotics worksheet speed run + Going from "here's the problem" to our goal - Formalize the problem - Propose an algorithm - Correctness: prove that the algorithm solves the formalized problem - Runtime: prove O/Ω/ϴ stuff about your algorithm + Example problem - Given an array of at least 2 integers, find the size of the range of the integers (i.e., the distance between the largest and smallest of the integers) A = [3, 19, 2, -5, 3, 0] --> 24 - Solutions? min = A[0] max = A[0] for each element e in A if e < min min = e if e > max max = e return max - min Correct? range is defined as max - min, so all we have to do is prove that this algorithm correctly computes max and min [proof by contradiction? or not...] let m be the minimum element in A suppose min != m m is in A, so at some point during the loop, e = m at that point, e < min, so min would have been assigned the value e (i.e., m) at no time later could min have changed... - Write it up - State or link to the problem - Name the relevant objects - Articulate the algorithm - Prove correctness - Analyze runtime - [Any other observations?] See my attempts at writeups below. ====== Problem: Given a non-empty array A[1...N] of integers, find the size of the range of the integers in A (i.e., the difference between the largest and smallest of the integers). Algorithm 1: 1 top = A[1] 2 for k = 2 to N: 3 if A[k] > top: 4 top = A[k] 5 bottom = A[1] 6 for k = 2 to N: 7 if A[k] < bottom: 8 bottom = A[k] 9 range = top - bottom ===== VERSION 1: more detailed ===== Correctness: Let max be the largest element of A. If max = A[1], then top is set to max at line 1. Otherwise, max = A[i] for one or more values of i between 2 and N. Let j be the smallest such i. Then top will be set to max at line 4 when k = j, because no A[i] < A[j] for all i < j. In either case, after top is set to max, line 4 will never be executed again, because A[k] > max. Therefore, at line 9, top = max. A similar argument shows that at line 9, bottom = min (the smallest element of A). Therefore, by the definition of range specified in the problem statement, line 9 computes the correct value for the range of the array A. Runtime: Let T(N) be defined as the number of lines of code executed during the execution of Algorithm 1. Lines 1, 5, and 9 are executed exactly once apiece regardless of the contents of A, and each of the other six lines is executed at most N - 1 times. Therefore T(N) <= 3 + 6(N - 1) = 6N - 3 = O(N) On the other hand, lines 2, 3, 6, and 7 are executed exactly N - 1 times apiece, so: T(N) >= 3 + 4(N - 1) = 4N - 1 = Ω(N) That is, T(N) = O(N) and T(N) = Ω(N), so T(N) = ϴ(N). More colloquially, Algorithm 1 runs in linear time. ===== VERSION 2: less detailed ===== Correctness: At the end of the kth iteration of the first loop for each value of k, top contains the largest value found in A[1]...A[k]. Therefore, at the end of the loop, top contains the largest value in the entire array--that is, the maximum value. Similarly, bottom contains the minimum value after the completion of the second loop. Therefore, by the definition of range, line 9 correctly computes the range of the array A. Runtime: Each loop in Algorithm 1 goes through N - 1 iterations, and each iteration does a constant amount of work (i.e., an amount of work independent of N). In addition, the non-loop lines are executed just once apiece, and thus do a constant amount of work. Therefore, the runtime T(N) of Algorithm 1 is O(N). Each loop must go through a full N - 1 iterations, since the max or min value might be located at A[N]. Thus, T(N) is also Ω(N). Therefore, T(N) = ϴ(N).