Computational Complexity

Similar documents
Growth of Functions (CLRS 2.3,3)

CS 4407 Algorithms Lecture 2: Iterative and Divide and Conquer Algorithms

3.1 Asymptotic notation

data structures and algorithms lecture 2

CS 4407 Algorithms Lecture 2: Growth Functions

More Asymptotic Analysis Spring 2018 Discussion 8: March 6, 2018

CS473 - Algorithms I

Data Structures and Algorithms Running time and growth functions January 18, 2018

Time complexity analysis

Big O 2/14/13. Administrative. Does it terminate? David Kauchak cs302 Spring 2013

CS 4407 Algorithms Lecture 3: Iterative and Divide and Conquer Algorithms

Analysis of Algorithm Efficiency. Dr. Yingwu Zhu

COMP Analysis of Algorithms & Data Structures

COMP Analysis of Algorithms & Data Structures

Asymptotic Notation. such that t(n) cf(n) for all n n 0. for some positive real constant c and integer threshold n 0

Lecture 2: Asymptotic Notation CSCI Algorithms I

Data Structures and Algorithms CSE 465

MA008/MIIZ01 Design and Analysis of Algorithms Lecture Notes 2

Analysis of Algorithms

Grade 11/12 Math Circles Fall Nov. 5 Recurrences, Part 2

The Time Complexity of an Algorithm

CSED233: Data Structures (2017F) Lecture4: Analysis of Algorithms

The Time Complexity of an Algorithm

Lecture 2. Fundamentals of the Analysis of Algorithm Efficiency

Ch01. Analysis of Algorithms

Algorithms Design & Analysis. Analysis of Algorithm

with the size of the input in the limit, as the size of the misused.

Asymptotic Analysis. Slides by Carl Kingsford. Jan. 27, AD Chapter 2

MA008/MIIZ01 Design and Analysis of Algorithms Lecture Notes 3

Algorithms and Their Complexity

EECS 477: Introduction to algorithms. Lecture 5

ECE250: Algorithms and Data Structures Analyzing and Designing Algorithms

Data Structures and Algorithms. Asymptotic notation

Module 1: Analyzing the Efficiency of Algorithms

Agenda. We ve discussed

Running Time Evaluation

Omega notation. Transitivity etc.

Algorithm efficiency can be measured in terms of: Time Space Other resources such as processors, network packets, etc.

Analysis of Algorithms [Reading: CLRS 2.2, 3] Laura Toma, csci2200, Bowdoin College

Analysis of Algorithms

Asymptotic Analysis 1

P, NP, NP-Complete, and NPhard

Big-Oh notation and P vs NP

Asymptotic Analysis Cont'd

Taking Stock. IE170: Algorithms in Systems Engineering: Lecture 3. Θ Notation. Comparing Algorithms

Lecture 3: Big-O and Big-Θ

Algorithms, Design and Analysis. Order of growth. Table 2.1. Big-oh. Asymptotic growth rate. Types of formulas for basic operation count

When we use asymptotic notation within an expression, the asymptotic notation is shorthand for an unspecified function satisfying the relation:

Lecture 1: Asymptotics, Recurrences, Elementary Sorting

CIS 121 Data Structures and Algorithms with Java Spring Big-Oh Notation Monday, January 22/Tuesday, January 23

Analysis of Algorithms I: Asymptotic Notation, Induction, and MergeSort

When we use asymptotic notation within an expression, the asymptotic notation is shorthand for an unspecified function satisfying the relation:

COMP 382: Reasoning about algorithms

Asymptotic Analysis and Recurrences

Module 1: Analyzing the Efficiency of Algorithms

CS 380 ALGORITHM DESIGN AND ANALYSIS

Reading 10 : Asymptotic Analysis

CSC Design and Analysis of Algorithms. Lecture 1

COMP 9024, Class notes, 11s2, Class 1

CS Non-recursive and Recursive Algorithm Analysis

Analysis of Algorithms

Big-O Notation and Complexity Analysis

Lecture 2. More Algorithm Analysis, Math and MCSS By: Sarah Buchanan

Ch 01. Analysis of Algorithms

CSC236 Week 4. Larry Zhang

Big O (Asymptotic Upper Bound)

i=1 i B[i] B[i] + A[i, j]; c n for j n downto i + 1 do c n i=1 (n i) C[i] C[i] + A[i, j]; c n

Introduction to Algorithms 6.046J/18.401J

Fundamentals of Programming. Efficiency of algorithms November 5, 2017

Divide-and-Conquer Algorithms Part Two

Asymptotic Analysis of Algorithms. Chapter 4

Asymptotic Analysis. Thomas A. Anastasio. January 7, 2004

An analogy from Calculus: limits

Review Of Topics. Review: Induction

CS 61B Asymptotic Analysis Fall 2017

CS 344 Design and Analysis of Algorithms. Tarek El-Gaaly Course website:

Lecture 10: Big-Oh. Doina Precup With many thanks to Prakash Panagaden and Mathieu Blanchette. January 27, 2014

Lecture 1: Asymptotic Complexity. 1 These slides include material originally prepared by Dr.Ron Cytron, Dr. Jeremy Buhler, and Dr. Steve Cole.

Analysis of Algorithms

Md Momin Al Aziz. Analysis of Algorithms. Asymptotic Notations 3 COMP Computer Science University of Manitoba

Algorithms, CSE, OSU. Introduction, complexity of algorithms, asymptotic growth of functions. Instructor: Anastasios Sidiropoulos

Advanced Algorithmics (6EAP)

Asymptotic Algorithm Analysis & Sorting

CIS 121. Analysis of Algorithms & Computational Complexity. Slides based on materials provided by Mary Wootters (Stanford University)

COMPUTER ALGORITHMS. Athasit Surarerks.

Design and Analysis of Algorithms

Cpt S 223. School of EECS, WSU

In-Class Soln 1. CS 361, Lecture 4. Today s Outline. In-Class Soln 2

Recursion. Computational complexity

The Growth of Functions and Big-O Notation

CSC236 Week 3. Larry Zhang

Defining Efficiency. 2: Analysis. Efficiency. Measuring efficiency. CSE 421: Intro Algorithms. Summer 2007 Larry Ruzzo

Foundations II: Data Structures and Algorithms

Lecture 3. Big-O notation, more recurrences!!

Introduction to Algorithms and Asymptotic analysis

CSE 417: Algorithms and Computational Complexity

Divide and Conquer CPE 349. Theresa Migler-VonDollen

5 + 9(10) + 3(100) + 0(1000) + 2(10000) =

2. ALGORITHM ANALYSIS

Introduction to Computer Science Lecture 5: Algorithms

Transcription:

Computational Complexity S. V. N. Vishwanathan, Pinar Yanardag January 8, 016 1 Computational Complexity: What, Why, and How? Intuitively an algorithm is a well defined computational procedure that takes some value, or set of values, as input and produces some values or set of values as output. For instance, we can think of an algorithm as a recipe for solving a particular problem such as matrix multiplication, sorting, etc. It is important to understand the asymptotic performance of an algorithm in order to compare its relative performance with other algorithms which perform the same task. This is also useful in order to determine the amount of resources necessary to solve a given problem efficiently. A mathematically precise way to characterizing the time and memory complexity of an algorithm is to use Θ, O, and Ω notation. 1 Roughly, the English interpretation of the Oh-notation is as follows: O(f); functions that grow no faster than f, Ω(f); functions that grow no slower than f, Θ(f); functions that grow at the same rate as f, o(f); functions that grow slower than f, ω(f); functions that grow faster than f. Before we study the math, let us understand the need for these tools. Usually we want to estimate the compexity of an algorithm in asymptotic form rather than it s exact speed. In other words, we study how the resource requirements of the algorithm grows as the input size grows, and tends to infinity. If, say, we are interested in the execution time of the program, one way to check asymptotic performance is to just code the algorithm and measure the time it takes for different sized inputs. However, this approach is not useful because the runtime depends on a number of external factors such as hardware, the programming language used, the style of the programmer and so on. Therefore, we need a mechanism which is independent of these factors, and yet provides us with a useful tool for analyzing and comparing algorithms. Efficiency of an algorithm can be determined by many criteria, including the amount of work done (time complexity) or the amount of space used (space complexity). Given sufficiently large input, an algorithm with a lower growth rate will always take less time even though it was run on a slower computer and it was written by a bad programmer. For example, consider two sorting 1 All the functions we consider are asymptotically non-negative. What this means is that there exists a n + such that for all n > n + the function f(n) is non-negative. 1

algorithms which we will discuss in the next lecture: Insertion sort (c 1 n ) and Merge sort (c n(log n)). Assume that insertion sort is coded by the best programmer (c 1 = ) with a low level language on a computer which can execute one billion operations per second. On the other hand, Merge sort is coded by a bad programmer (c = 50) with a high level language on slow computer which can only execute ten million operations per second. Even with these differences, sorting ten million numbers with Insertion sort takes.3 days while Merge sort only takes 0 minutes. Worst, Average, and Best Case Complexity.1 Best case complexity We use best-case performance to measure the behaviour of the algorithm under optimal conditions. For example, for a list with n items, the best case for linear search algorithm is when the value is equal to the first element of the list, so that we only need to do one comparison. Given D n = the set of all inputs of size n, t(i) = number of basic operations needed for input I; we can define best-case complexity as the minimum number of basic operations performed by the algorithm on any input of a certain size; B(n) = min{t(i) I D n }.. Average case complexity In average case complexity, we measure the average number of basic operations performed by the algorithm on any input of a certain size. For example, for linear search algorithm, if we assume that each element in the list is equally likely to be the value that we were looking for, algorithm only visits n/ elements on average. Given D n = the set of all inputs of size n, t(i) = number of basic operations needed for input I and P (I) the probability that input I occurs; we can define the average case complexity as A(n) = I D n P (I).t(I). We can estimate the probability of occurance of certain inputs either from past experience or by building a generative model which outputs the probability of observing various inputs (e.g. all numbers are equally likely to match in linear search)..3 Worst case complexity Worst-case complexity is usually the most important criterion for comparing algorithms since we often want a guarantee that the algorithm will always finish on time. For example, for linear search algorithm, the worst case is when the value we are looking for is not in the list or when it s at the end of the list (therefore, we have to make n comparisons). Example is taken from: cs.iupui.edu/ xkzou/teaching/cs580/introduction.ppt

Figure 1: Worst case W (n) vs Average case A(n) vs Best case B(n) Given D n = the set of all inputs of size n, t(i) = number of basic operations needed for input I; we can define worst-case complexity as the maximum number of basic operations performed by the algorithm on any input of a certain size; W (n) = max{t(i) I D n }. 3 Order of Growth We saw average, best and worst-case time complexity, however exactly determining B(n), A(n) and W (n) for various values of n is very hard. Furthermore, as we discussed above, the efficiency of the hardware and the implementation details of a specific algorithm make these numbers extremely hard to calculate. Therefore we will use asymptotic analysis to compare algorithms against one another. Main intuition here is when input size n goes to infinity, we ignore constant factors and drop lower order terms in order to come up with an asymptotic growth rate. Figure shows a comparison between order of growths 3. 3.1 O Notation The O notation provides an asymptotically upper bound (cannot do worse, can do better). Denote by O(g(n)) the set of functions O(g(n)) := {f(n) : c, n 0 > 0 s.t. 0 f(n) cg(n) n n 0 }. Note: The O notation bounds the worst case performance of the algorithm. But saying that an algorithm is O(n ) does not imply that the algorithm takes 3 Images are taken from jriera.webs.ull.es/docencia/lec1.pdf 3

time for every input. Some examples on O notation: n = O(n 3 ): 0 f(n) cg(n) (from the definition) 0 n 3 (substitute) 0/n 3 n /n 3 3 /n 3 (Divide by n 3 ) Now determine c: 0 /n c lim n n = 0 (/n is maximum when n = 1) 0 c (substitute n) c = (satisfies above inequality) Now determine n 0 : 0 /n 0 (substitute c=) 0 / n 0 0 1 n 0 (n 0 = 1 will satisfy) Now substitute n 0 = 1 and c = to the inequality: 0 n n 3 n n 0 = 1 Above inequality holds, therefore n = O(n 3 ). 5n 3 + 10n O(n ) 0 f(n) cg(n) (from the definition) 0 5n 3 + 10n 0 5n 3 /n + 10n/n /n 0 5n + 10/n c 0 (5n + 10)/n c 5n lim +10 n n = Notice that there is no c exists where n n 0 is true. Therefore 5n 3 + 10n O(n ) holds. 3. Ω Notation The Ω notation provides an asymptotically lower bound (we cannot do better, can do worse). Denote by Ω(g(n)) the set of functions Ω(g(n)) := {f(n) : c, n 0 > 0 s.t. 0 cg(n) f(n) n n 0 }. Examples are taken from: http://homepages.ius.edu/rwisman/c55/html/notes/chapter3/asymptotic.htm

Figure : Big O vs Omega vs Big Theta Orders Ω(g(n)) is the set of functions that grow at least as fast as g(n). Note: The Ω notation bounds the best case performance of the algorithm. Saying that an algorithm is Ω(n ) implies that the algorithm takes at least time for every input. Theorem 1 For any two function f and g we have f(n) = Θ(g(n)) iff f(n) = O(g(n)) and f(n) = Ω(g(n)). Some examples on Ω notation: 3n + n = Ω(n ) First, let s find c: 0 cg(n) f(n) (from the notation) 0 3n + n 0/n /n 3n /n + n/n 3n+1 0 c 3 + 1/n (lim n n = 3) c = 3 satisfies above inequality. Let s find n 0 : 0 3 3 + 1/n 0 (substitute c) 3 0 1/n 0 (lim n 1 n = 0) 5

n 0 = 1 satisfies the inequality above. Therefore, 3n + n = Ω(n ) holds for c = 3 and n 0 = 1. 3.3 Θ Notation Denote by Θ(g(n)) the set of functions Θ(g(n)) := {f(n) : c 1, c, n 0 > 0 s.t. 0 c 1 g(n) f(n) c g(n) n n 0 }. In other words, f(n) is sandwiched between c 1 g(n) and c g(n). Although technically Θ(g(n)) is a set, and we should write f(n) Θ(g(n)), we will abuse notation and write f(n) = Θ(g(n)). Another way to test if f(n) = Θ(g(n)) is to check if f(n) lim n g(n) = const. > 0 In summary, Θ class gives a lower bound and upper bound on complexity of a function. Θ(f) is the set of functions that grow at the same rate as f. c g(n) is an upper bound on f(n) and c 1 g(n) is a lower bound on f(n). Some examples on Θ notation: 1/n 3n = Θ(n ) We must find positive constants c 1, c, and n 0 such that: c 1 n 1/n 3n c n for all n n 0 (from the definition) Dividing by n gives: c 1 1/ 3/n c The right inequality holds if c = 1/, n 1, the left inequality holds if c 1 = 1/1, n 7, So we let c 1 = 1/1, c = 1/, and n 0 = 7 3. o Notation The bounds provided by the O notation might not be asymptotically tight (For instance, n = O(n )). In such cases we use the o notation. Denote by o(g(n)) the set of functions o(g(n)) := {f(n) : n 0 > 0 s.t. 0 f(n) < cg(n) c > 0 and n n 0 }. Carefully note the order of the qualifiers. The main difference from the O notation is that the upper bound now holds for all constants c. Intuitively, 6

in the o notation the function f(n) becomes insignificant compared to g(n) as n. Another way to see this is via limits: Some examples for o notation: f(n) lim n g(n) = 0. x is o(x 3 ): lim x x x 3 = lim x 1 x = 0 x log x is o(x x log x ): lim x x 0 x + x + 1 is not o(x ): = lim x log x x = lim x (log x) x = lim x 1 x ln = x lim +x+1 x x = lim x (1 + 1 x + 1 1 x ) = 1 + lim x x + lim x 1 x = = 1 + 0 + 0 = 1 0 3.5 ω Notation Denote by ω(g(n)) the set of functions ω(g(n)) := {f(n) : n 0 > 0 s.t. 0 cg(n) < f(n) c > 0 and n n 0 }. In terms of limits: Some examples for ω notation: f(n) lim n g(n) =. n = ω(n) n lim n n = n log n = ω(n ) lim n n log n n = lim n log n = n ω(n ) lim n n n = 1 7

3.6 L Hospital s Rule If f and g are two functions which satisfy either or lim f(n) = lim g(n) = 0 n c n c f (n) lim g(n) = ± and lim n c n c g (n) exists. Then f(n) lim n c g(n) = lim f (n) n c g (n), where denotes the derivative. This is often used to simply computation of the limits. 3.7 Recurrences Sometimes we can solve a problem by first solving smaller sub-problems and using their solutions to solve the larger problem. As a concrete example, consider the following pseudo-code for sorting an array of n numbers: Algorithm 1 Merge Sort 1: Input: Array of size n : if n = 1 then 3: Return: input array : else 5: Split array into two sub-arrays of size n/ 6: Apply Merge Sort on the two sub-arrays 7: Merge the two sorted sub-arrays into a single sorted array 8: end if 9: Return: Sorted array The time taken by the merge sort algorithm to sort n numbers can be written as the following recurrence: T (n) = T (n/) +. Here c is a constant and the denotes the time taken to merge two sorted subarrays of size n/ into a single sorted array. Note our slightly sloppy notation; we implicitly assume that n is always divisible by. In order to deduce the time complexity of merge sort we write out a recurrence tree. First observe that to solve a problem of size n we need to solve two sub problems of size n/ and expend effort to merge the two solutions together. This is represented by the following tree: 8

T ( n ) T ( n ) Next we observe that solving each problem of size n/ entails solving a problem of size n/ and then expending / work to merge the solutions. This is represented by the following expanded tree: T ( n ) T ( n ) T ( n ) T ( n ) Continuing the same line of argument one gets to the next level: T ( n 8 ) T ( n 8 ) T ( n 8 ) T ( n 8 ) T ( n 8 ) T ( n 8 ) T ( n 8 ) T ( n 8 ) and so on and so forth. It is easy to see that this process will stop when the size of the input is 1 (a single element need not be sorted). This happens after k levels, where n/ k = 1 or in other words when k = log (n). The total work done by the algorithm can now be found by summing over all the nodes of the tree. Observe that at every level of the tree we need to expend work. Since there are log (n) levels, one can easily conclude that T (n) = O(n log (n)). Exercise: Write the recursion tree for the following recurrences and use it to find the complexity of T (n) in O (or if applicable Θ) notation. T (n) = T (n/) + 1 T (n) = T (n/) + 1 9