Lecture 1 Analyze the efficiency of algorithms CSE354-Algorithms and Data Structure © Dr. Ahmed Ayoub, 2019 Learning Objectives By the end of this lecture you will be able to: Define the Model of computation Select what to Analyze Perform Running-Time calculations Solve a simple Example Recognize the General Rules State the limitations of worst-case analysis Model of computation To analyze algorithms in a formal framework. Model: a computer with instructions executed sequentially. Standard simple instructions: addition, multiplication, comparison, and assignment. Takes exactly one time unit to do anything (simple.) Has fixed-size integers. Has infinite memory. Model of computation This model clearly has some weaknesses: In real life, not all operations take exactly the same time. By assuming infinite memory, we ignore the fact that the cost of a memory access can increase What to Analyze? The most important resource to analyze is generally the running time. Factors affect the running time of a program: compiler and computer used (cannot deal with) algorithm used and the input size to the algorithm. What to Analyze? We define two functions: Tavg(N), the average running time Tworst(N), worst-case running time N, input of size used by an algorithm Clearly, Tavg(N) ≤ Tworst(N). If there is more than one input. These functions may have more than one argument! Example Given integers: A1, A2, …, AN find the maximum value of Small inputs: no need to design a clever algorithm. Large inputs, algorithm 4 is clearly the best choice Running-Time calculations Generally, there are several algorithmic ideas, and we would like to eliminate the bad ones early An analysis is usually required. The ability to do an analysis usually provides insight into designing efficient algorithms. The analysis also generally pinpoints the bottlenecks, which are worth coding carefully. Running-Time calculations To simplify the analysis, we adopt the convention that there are no particular units of time. Thus, we throw away leading constants. Also, throw away loworder terms, So what we are essentially doing is computing a Big-Oh running time. The answer provided guarantees that the program will terminate within a certain time period, but never later. A simple Example Program fragment to calculate: The declarations count for no time. Lines 1 and 4 count for one unit each. Line 3 counts for 4 units per time executed N times, for a total of 4N. Line 2 has the hidden costs of initializing i, testing i ≤ N, and incrementing i. The total cost of all these is 1 to initialize, N+1 for all the tests, and N for all the increments, which is 2N + 2. We ignore the costs of calling the function and returning, for a total of 6N + 4. Thus, we say that this function is O(N). The General Rules Rule 1—FOR loops: O(N) Rule 2—Nested loops: O(N2) Rule 3—Consecutive Statements: O(N) Rule 4—If/Else: O(N) The limitations of worst-case analysis Sometimes the analysis is shown empirically to be an overestimate: the analysis needs to be tightened; or the average running time is significantly less than the worst-case running time For many complicated algorithms the worst-case bound is achievable by some bad input Unfortunately, an average-case analysis is extremely complex, and a worst-case bound is the best analytical result known! Conclusion Define the Model of computation Select what to Analyze Perform Running-Time calculations Solve a simple Example Recognize the General Rules State the limitations of worst-case analysis