Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
TIME COMPLEXITY OF ALGORITHM “ As soon as an Analytical Engine exists, it will necessarily guide the future course of science. Whenever any result is sought by its aid, the question will then arise – By what course of calculation can these results be arrived at by the machine in the shortest time? ” - Charles Babbage, 1864 1 Overview Introduction. Importance & Efficiency of Time complexity. Different notations. Different cases of Time complexity. Derivation of time complexity for searching algorithm. Derivation of time complexity for sorting algorithm. 2 Definition:Algorithm An algorithm, named for the ninth century Persian Mathematician al-Khowarizmi, is simply a set of rules for carrying out some calculations, either by hand or, more usually, on a machine. Informally, an algorithm is any well defined computational procedure that takes some value or set of values as output. 3 Criterias of Algorithms All algorithms must satisfy the following criteria : Input: Zero or more quantities are externally supplied. 2. Output: Atleast one quantity is produced. 3. Definiteness: Each instruction is clear and unambiguous. 4. Finiteness: If we trace out the instructions of an algorithm, then for all cases , the algoprithm terminates after a finite number of steps. 5. Effectiveness: Each instruction must be very basic so that it can be carried out. 1. 4 In the fig. S is the starting node and G is the goal node. In the graph the numeric value represents the corresponding costs from one node to another. Our aim is to traverse from S to G expensing less amount. For conviences we neglect the other factors like time, life risk and so on. In this Real life problem we have to pay more cost for selecting path if we don’t follow Algorithm. If we choose SA-G, S-B-A-G, S-C-B-G, we have to pay more than if we choose S-C-D-G. 5 . (ii) A Sorting Problem: Input : A sequence of n numbers <a1,a2,………an> Output : A permutation (reordering) <a1', a2',………..an'> of the input sequence such that a1'≤ a2' ...............≤an' An instance of a problem consists of the input needed to compute a solution to the problem. 6 (iii) In internet technology also algorithms are applied to manage and manipulate large large amount of information. Public-key cryptography (Network Security) and digital signatures are core technologies which on numerical algorithms. 7 Definition:Time Complexity The Time Complexity of an Algorithm is the amount of time it needs to run to completion. It indicates how many time steps does the Computation of a problem cost. Hence, it is called one of the performance measure tool or parameter of the problem size and the search space dimension respectively. 8 IMPORTANCE & EFFICIENCY OF TIME COMPLEXITY Time Complexity has a greater importance in the field of Software development which includes Line of Code Time Estimation Cost Estimation 9 Complexity :A measure of the performance of an algorithm An algorithm’s performance depends on internal and external factors Internal The algorithm’s efficiency, in terms of: • Time required to run • Space (memory storage) required to run External • Size of the input to the algorithm • Speed of the computer on which it is run • Quality of the compiler Complexity measures the internal factors (usually more interested in time than space) 10 Efficiency When we look at input sizes large enough to make only the order of growth of the running time relevant, this is the study of asymptotic efficiency of algorithms. We shall usually compare algorithms on the basis of their execution times and when we speak of the efficiency we shall simply mean how fast it runs. 11 How can we analyze the efficiency of algorithms? We can measure the • time (number of elementary computations) and • space (number of memory cells) that the algorithm requires. These measures are called computational complexity and space complexity, respectively. Complexity theory is ‘the art of counting resources’. 12 Time complexity functions We need a more abstract / theoretical approach to measure how fast an algorithm is. For this purpose , we define a function f(n) called the time-complexity function of the algorithm. It measures the number of computational steps needed to solve the problem. The argument n of the function is a measure of the size of the task. 13 Contd.. Suppose that we want to sort n numbers. We can use n as the argument of the time-complexity function. We say we have a problem “of size n”. Suppose that we want to find if an integer n is the square of another integer. We can use n as the argument of the time complexity function. 14 Contd.. The function f(n) measures the number of comput-ational steps . You can think of the computational step as a simple operation performed by the comp-uter. For example, it can be an addition, a multiplication, or a comparison between two floating point numbers. This can become more formal using an abstract model of the computer called Turing machine. Generally, f(n) increases with n. 15 Examples (i) Two algorithms solve the same problem. Their time complexity functions are 100n and n2, respectively. Which algorithm should we use if there is an application specific constraint of 1000 basic computations? Which algorithm should we use if we upgrade our computer and can afford 1,000,000 basic computations? 16 Solution :The time complexity function of an algorithm is 100n + n2. For n=10, the most computationally expensive part of the algorithm is the 100n. For n=1000, the most computationally expensive part of the algorithm is the n2. 17 (ii) We run in our PC an algorithm with time complexity function 100n. For the same problem, a supercomputer 1,000 times faster than our PC runs an algorithm with time complexity function n2. Who will finish first for n=1,000,000 ? 18 For example, let us assume two algorithms A and B that solve the same class of problems. The time complexity of A is 5,000n, the one for B is 1.1n for an input with n elements. 19 Complexity Comparison:time complexity of algorithms A and B Input Size Algorithm A Algorithm B n 5,000n 1.1n 10 50,000 3 100 500,000 13,781 1,000 5,000,000 2.51041 1,000,000 5109 4.81041392 20 This means that algorithm B cannot be used for large inputs, while running algorithm A is still feasible. So what is important is the growth of the complexity functions. The growth of time and space complexity with increasing input size n is a suitable measure for the comparison of algorithms. 21 The notation we use to describe the asymptotic running time of an algorithm are defined in terms of functions whose domains are the set of natural numbers N={0,1,2,…} Such notations are convenient for describing the worst case running time function T(n), which is usually defined only on integer input sizes. 22 Different asymptotic notations are Big O notation Big Omega (Ω) notation Theta (Θ) notation Little o notation Little omega (ω) notation 23 Big-Oh is the formal method of expressing the upper bound of an algorithm's running time More formally, for non-negative functions, f(n) and g(n), if there exists an integer n0 and a constant c > 0 such that for all integers n > n0, f(n) ≤ cg(n), then f(n) is Big Oh of g(n). This is denoted as "f(n) = O(g(n))“ If graphed, g(n) serves as an upper bound to the curve you are analyzing, f(n). 24 Fig: The asymptotical bounds O 25 Say that f(n) = 2n + 8, and g(n) = n2. Can we find a constant c, so that 2n + 8 <= n2? The number 4 works here, giving us 16 <= 16. For any number c greater than 4, this will still work. Since we're trying to generalize this for large values of n, and small values (1, 2, 3) aren't that important, we can say that f(n) is generally faster than g(n); that is, f(n) is bound by g(n), and will always be less than it. 26 1: The running time of the program is constant. Example: Find the 5th element in an array. log N: Typically achieved by dividing the problem into smaller segments and only looking at one input element in each segment Example: Binary search N: Typically achieved by examining each element in the input once Example: Find the minimum element 27 N log N: Typically achieved by dividing the problem into subproblems, solving the subproblems independently, and then combining the results Example: Merge sort N^2: Typically achieved by examining all pairs of data elements. Example: Selection Sort N^3: Often achieved by combining algorithms with a mixture of the previous running times Example: Matrix Multiplication 28 For non-negative functions, f(n) and g(n), if there exists an integer n0 and a constant c > 0 such that for all integers n > n0, f(n) ≥ cg(n), then f(n) is omega of g(n). This is denoted as "f(n) = Ω(g(n))“ This is almost the same definition as Big Oh, except that "f(n) ≥ cg(n)", this makes g(n) a lower bound function, instead of an upper bound function. It describes the best that can happen for a given data size. 29 Fig: The asymptotical bounds Ω 30 For non-negative functions, f(n) and g(n), f(n) is theta of g(n) if and only if f(n) = O(g(n)) and f(n) = Ω(g(n)). This is denoted as "f(n) = Θ(g(n))". This is basically saying that the function, f(n) is bounded both from the top and bottom by the same function, g(n). 31 DIFFERENT CASES OF TIME COMPLEXITY Three different cases of Time Complexity are 1. Best Case 2. Average Case 3. Worst Case 32 Contd.. Best, worst and average cases of a given algorithm express what the resource usage is at least, at most and on average, respectively. 33 Worst, best & average cases The worst-case complexity of the algorithm is the function defined by the maximum number of steps taken on any instance of size n. The best-case complexity of the algorithm is the function defined by the minimum number of steps taken on any instance of size n. Finally, the average-case complexity of the algorithm is the function defined by the average number of steps taken on any instance of size n. 34 Best case performance The term best-case performance is used in computer science to describe the way an algorithm behaves under optimal conditions. For example, a simple linear search on an array has a worst-case performance O(n), and average running time is O(n/2), but in the best case the desired element is the first element in the array and the run time is O(1). 35 Average case performance Determining what average input means is difficult, and often that average input has properties which make it difficult to characterise mathematically. Similarly, even when a sensible description of a particular "average case" is possible, they tend to result in more difficult to analyse equations. 36 Worst case performance Worst-case analysis has similar problems, typically it is impossible to determine the exact worst-case scenario. Instead, a scenario is considered which is at least as bad as the worst case. For example, when analysing an algorithm, it may be possible to find the longest possible path through the algorithm even if it is not possible to determine the exact input that could generate this. Indeed, such an input may not exist. 37 In computer science, linear search is a search algorithm, also known as sequential search, that is suitable for searching a set of data for a particular value. It operates by checking every element of a list one at a time in sequence until a match is found. Linear search runs in O(N). If the data are distributed randomly, on average N/2 comparisons will be needed. 38 The best case is that the value is equal to the first element tested, in which case only 1 comparison is needed. The worst case is that the value is not in the list (or is the last item in the list), in which case N comparisons are needed. 39 The simplicity of the linear search means that if just a few elements are to be searched it is less trouble than more complex methods that require preparation such as sorting the list to be searched or more complex data structures, especially when entries may be subject to frequent revision. Another possibility is when certain values are much more likely to be searched for than others and it can be arranged that such values will be amongst the first considered in the list. 40 The following pseudocode describes the linear search technique. For each item in the list: Check to see if the item you're looking for matches the item in the list. If it matches. Return the location where you found it (the index). If it does not match. Continue searching until you reach the end of the list. If we get here, we know the item does not exist in the list. Return -1. 41 This picture uses a different approach to visualising the dynamic nature of the linear search algorithm. This shows the moment when a key is found. A grid of coloured circles represents the data being searched. It is searched through a row at a time. The fact that a particular circle has been checked is shown by a cross marked through the circle. The key being found is shown as a bull's eye. 42 1 3 5 2 9 10 For i = 0 to 5 begin If ( a[i] = = x ) Print “item found” 43 c1 X n c2 For i = 0 to N begin If ( a[i] = = x ) Print “item found” End If ( i = = n + 1 ) Print “ item not found ” 44 Contd….. T (n ) = n c1 + c2 <= n c1 + n c2 n>=1 <= n ( c1+c2) n>=1 T (n) = O (g(n) So, for n elements, Time complexity = O (n ) 45 Quicksort is a well-known sorting algorithm developed by C.A.R. Hoare that,on average, makes Θ(n log n) comparisons to sort n items. However, in the worst case, it makes Θ(n2) comparisons. Typically, quicksort is significantly faster in practice than other Θ(n log n) algorithms. This is because its inner loop can be efficiently implemented on most architectures, and in most real-world data it is possible to make design choices which minimize the possibility of requiring quadratic time. 46 Quicksort sorts by employing a divide and conquer strategy to divide a list into two sub-lists. The steps are: Pick an element, called a pivot, from the list. Reorder the list so that all elements which are less than the pivot come before the pivot and so that all elements greater than the pivot come after it (equal values can go either way). After this partitioning, the pivot is in its final position. This is called the partition operation. Recursively sort the sub-list of lesser elements and the sub-list of greater elements. 47 Quicksort in action on a list of random numbers. The horizontal lines are pivot values. 48 SORTING TECHNIQUE Consider the following numbers 10 9 6 12 5 3 16 2 17 49 QUICK SORT - Algorithm QS ( LB, UB, A ) Begin if( LB < UB) Begin flag = 1, i = LB + 1, j = UB, key = A[LB] while( flag ) begin while( key > A[i] ) while( key < A[j] ) if ( i < j ) swap( A[i], A[j] ) else flag = 0 end if ( i >= j ) swap( A[LB], A[j] ) end QS( LB, j –1, A ) QS( j+1, UB, A ) 50 10 9 6 12 5 3 16 2 17 The array is pivoted about its first element p = 10 10 9 6 12 5 3 16 2 17 51 10 9 6 12 5 3 16 2 17 Find the first element larger than pivot (here, 12) and last element not larger than pivot (here, 2). 10 9 6 12 5 3 16 2 17 52 10 9 6 12 5 3 16 2 17 Swap these two elements. 10 9 6 2 5 3 16 12 17 53 10 9 6 2 5 3 16 12 17 Scan again in both directions and again find the required elements. 10 9 6 2 5 3 16 12 17 54 10 9 6 2 5 3 16 12 17 The pointers have crossed here. So, swap the pivot with the last element not larger than it. Now, array becomes – 3 9 6 2 5 10 16 12 17 55 3 9 6 2 5 10 16 12 17 Now we can observe that the left side of the pivot contains elements smaller than it and the right side of the pivot contains elements greater than it. Now, recursively sort the sub arrays on each side of the pivot. 3 9 6 2 5 10 16 12 17 First sublist Second sublist 56 Now, we have to sort these subarrays separately. 3 9 6 2 Left sublist 5 16 12 17 Right sublist 57 THE SORTED ARRAY After the sorting of the left and right sublists, finally array becomes sorted as--- 2 3 5 6 9 10 12 16 17 58 The running time of this algorithm is usually measured by the number f(n) of comparisons required to solve n elements. 2 It has a worst case running time of order n /2. But an average case running time of order n log n. 59 The worst case occurs when the list is already sorted. Thus the first element requires n comparisons to recognize that it remains in the first position. Furthermore the first sublist will be empty, but the second sublist will have n – 1 elements. So, the second element will require n – 1 comparisons to recognize that it remains in the second position and so on.Consequently, there will be a total of f(n) = n + (n-1) + ….. + 2 + 1 = n(n+1)/2 2 = n /2 +O(n) 2 = O( n ) 60 The Worst Case for QuickSort The tree on the right illustrates the worst case of quick-sort, which occurs when the input is already sorted! 61 The complexity f(n) = O (n log n) of the average case comes from the fact that,on the average , each reduction step of the algorithm produces two sublists. Accordingly, Reducing the initial list places one element and produces two sublists. Reducing the two sublists places two elements and produces four sublists. Reducing the four sublists places four elements and produces eight sublists. Reducing the eight sublists places eight elements and produces sixteen sublists. And so on.The reduction step in the k th level finds the location of 2(k-1) elements.Hence there will be log2n levels of reduction steps. And each level uses at most n comparisons. So, f(n) = O(n log n). In fact, mathematical analysis and empirical evidence both show that f(n) = 1.4 [ n log n ] is the expected number of comparisons for the quick sort algorithm. 62 T(n) = 2. T(n/2) + cn T(n/2) =2T{(n/2)/2} + c(n/2) T(n) = 2{2T(n/4) +c(n/2)} + cn = 4T(n/4) +cn + cn = 8T(n/8) + 3cn [ let, n/2k=1 = 23 T(n/23) + 3 cn k n = 2 ……………………….. k = log2 n ] = 2k T(n/2k) + k cn = n T(1) + log2 n . cn [ T (1) = 1 ] = cn log2 n + n. 1 <= cn log2 n + cn log2 n <= 2cn log2 n [ n> 1 ] So, O(n log2 n ) is the best case. 63 Competitive sorting algorithms Quicksort is a space-optimized version of the binary tree sort. Instead of inserting items sequentially into an explicit tree, quicksort organizes them concurrently into a tree that is implied by the recursive calls. The algorithms make exactly the same comparisons, but in a different order. The most direct competitor of quicksort is heap sort. Heapsort is typically somewhat slower than quicksort, but the worst-case running time is always O(nlogn). Quicksort is usually faster, though there remains the chance of worst case performance except in the introsort variant. If it's known in advance that heapsort is going to be necessary, using it directly will be faster than waiting for introsort to switch to it. 64 Formal analysis It's not obvious that quicksort takes O(n log n) time on average. It's not hard to see that the partition operation, which simply loops over the elements of the array once, uses Θ(n) time. In versions that perform concatenation, this operation is also Θ(n). In the best case, each time we perform a partition we divide the list into two nearly equal pieces. This means each recursive call processes a list of half the size. Consequently, we can make only log n nested calls before we reach a list of size 1. 65 This means that the depth of the call tree is O(log n). But no two calls at the same level of the call tree process the same part of the original list; thus, each level of calls needs only O(n) time all together (each call has some constant overhead, but since there are only O(n) calls at each level, this is subsumed in the O(n) factor). The result is that the algorithm uses only O(n log n) time. An alternate approach is to set up a recurrence relation for T(n), the time needed to sort a list of size n. Because a single quicksort call involves O(n) work plus two recursive calls on lists of size n/2 in the best case, the relation would be: T(n) = O(n) + 2T(n/2) 66 Randomized quicksort expected complexity Randomized quicksort has the desirable property that it requires only O(n log n) expected time, regardless of the input. But what makes random pivots a good choice? Suppose we sort the list and then divide it into four parts. The two parts in the middle will contain the best pivots; each of them is larger than at least 25% of the elements and smaller than at least 25% of the elements. If we could consistently choose an element from these two middle parts, we would only have to split the list at most 2log2 n times before reaching lists of size 1, yielding an O(n log n) algorithm. 67 Unfortunately, a random choice will only choose from these middle parts half the time. The surprising fact is that this is good enough. Imagine that you are flipping a coin over and over until you get k heads. Although this could take a long time, on average only 2k flips are required, and the chance that you won't get k heads after 100k flips is infinitesimally small. By the same argument, quicksort's recursion will terminate on average at a call depth of only 2(2log2 n). But if its average call depth is O(log n), and each level of the call tree processes at most n elements, the total amount of work done on average is the product, O(n log n). 68 Average complexity Even if we aren't able to choose pivots randomly, quicksort still requires only O(n log n) time over all possible permutations of its input. Because this average is simply the sum of the times over all permutations of the input divided by n factorial, it's equivalent to choosing a random permutation of the input. When we do this, the pivot choices are essentially random, leading to an algorithm with the same running time as randomized quicksort. 69 More precisely, the average number of comparisons over all permutations of the input sequence can be estimated accurately by solving the recurrence relation: Here, n - 1 is the number of comparisons the partition uses. Since the pivot is equally likely to fall anywhere in the sorted list order, the sum is averaging over all possible splits. This means that, on average, quicksort performs only about 39% worse than the ideal number of comparisons, which is its best case. In this sense it is closer to the best case than the worst case. This fast average runtime is another reason for quicksort's 70 practical dominance over other sorting algorithms. The height of the tree is N-1 not O(log(n)). This is because the pivot is in this case the largest element and hence does not come close to dividing the input into two pieces each about half the input size. Since the pivot does not appear in the children, at least one element from level i does not appear in level i+1 so at level N-1 you can have at most 1 element left. So we have the highest tree possible. 71 Note also that level i has at least i pivots missing so can have at most N-i elements in all the nodes. Our tree achieves this maximum. So the time needed is proportional to the total number of numbers written in the diagram which is N + N-1 + N-2 + ... + 1, which is again the one summation we know N(N+1)/2 or Θ(N2). 72 Perhaps the problem was in choosing the last element as the pivot. Clearly choosing the first element is no better; the same example on the right again illustrates the worst case (the tree has its empty nodes on the left this time). Since are spending linear time (as opposed to constant time) on the division step, why not count how many elements are present (say k) and choose element number k/2? This would not change the complexity (it is also linear). You could do that and now a sorted list is not the worst case. But some other list is. Just put the largest element in the middle and then put the second largest element in the middle of the node on level 1. This does have the advantage that if you mistakenly run quick-sort on a sorted list, you won't hit the worst case. But the worst case is still there and it is still Θ(N2). 73 Why not choose the real middle element as the pivot, i.e., the median. That would work! It would cut the sizes in half as desired. But how do we find the median? We could sort, but that is the original problem. In fact there is a (difficult) algorithm for computing the median in linear time and if this is used for the pivot, quick-sort does take O(Nlog(N)) time in the worst case. However, the difficult median algorithm is not fast in practice. That is, the constants hidden in saying it is Θ(N) are rather large. Instead of studying the fast, difficult median algorithm, we will consider a randomized quick-sort algorithm and show that the expected running time is 74 Θ(Nlog(N)).