Introduction

Analysis of Algorithms

Some reasons to perform mathematical analysis: Some important factors in precise analysis that are usually outside a given programmer's domain influence The analysis amounts to determine the frequency of execution of a few fundamental operations: In this course we will be to look for rough estimates of these quantities.

We also have to study the data, and to model the input that might be presented to the algorithm. Most often, we consider one of two approaches to the analysis:

How fast functions grow and big-O notation

Most algorithms have a primary parameter N that affects the running time most significantly. This parameter may be the size of the array to sort or search in, the size of the file, the degree of a polynomial, number of vertices in a graph, number of characters in a string, etc. While estimating efficiency of an algorithm, our goal is to express the resources requirements of it in terms of N. In the table we can see some functions that are convenient to use for estimation of algorithms discussed in this course.

Function Description Graph
1 Most instructions of most programs are executed once or at most only a few times. If all the instructions of a program have this property, we say that the program's running time is constant. N/A
log(N) When the running time of a program is logarithmic, the program gets slightly slower as N grows. This running time commonly occurs in programs that solve a big problem by transformation into a series of smaller problems, cutting the problem size by some constant fraction at each step.
N When the running time of a program is linear, it is generally the case that a small amount of processing is done on each input element. That is, whenever N, doubles so does the running time.
N*log(N)   This timing arises usually when algorithm solves a problem by breaking it up into smaller subproblems, solving them independently, and then combining the solutions. (When N doubles, then the running time more [but not much more] than doubles.)
N2 When the running time is quadratic, that algorithm is practical only for use on only relatively small problems because when N doubles, the running time increases fourfold.
2N Very few algorithms with exponential time are likely to be appropriate for practical use, even though such algorithms arise natuarally as brute-force solution to problems. Whenever N doubles, the running time squares!

The following table shows how much time it takes to solve huge problems on machines of different speed.

Operations
per
seconds
Problem size 1 million Problem size 1 billion
N N*log(N) N2 N N*log(N) N2
106 seconds seconds weeks hours hours never
109 instant instant hours seconds seconds decades
1012 instant instant seconds instant instant weeks

Big-O notation

Definition: A function g(N) is said to be O(f(N)) if there exists constant c0 such that
g(N) < c0 O(f(N))
for all N greater than some N0.

In this course this notation basically will be used to say that one function is approximately equal another (usually simpler) function when parameter N is large. For example, we can say that

3*N2 + 2*N - N*log2(N)
is approximately the same as 3*N2 if N is big enough. That is, we can say that 3*N2 + 2*N = O(N2).

For more details see this page.


More details on these topics can be found in the second chapter of Algorithms in C++ from Robert Sedgewick.