Introduction
What does "algorithm" mean?
Its a sequence of steps to solve a problem. This sequence of steps works depending on the input to the problem.
What does "design & analysis of algorithms" mean?
- correctness of algorithms
- does it terminate?
- efficient (fast):
- estimate the running terminate
- count the number of steps
- is it optimal? Can we do better?
- limits of efficiency (some problems cannot be solved efficiently)
- pseudocode, no programming
Insertion Sort
Input: An array of numbers. Output: An array containing the numbers of in increasing order.
for i in range (2, n):key = A[i]j = i-1while (j > 0 and A[j] > key):A[j+1] = A[j]j = j-1A[j+1] = key
Best case: Already sorted O(n) Worst case: Sorted in reverse order O()
Definition (O-Notation)
Let and be two functions. We say that is of (or is big of) if there exists a constant and a number such that for all .
We write or
Definition (Omega-Notation)
Let and be two functions. We say that is of (or is big of) if there exists a constant and a number such that for all .
We write or
Definition (Theta-Notation)
Let and be two functions. We say that is of (or is big of) if there exists two constants and a number such that for all .
We write or
Overview
An algorithm takes time, for a function , if there exists:
- a strictly positive constant c
- and an experimentation of which takes at most units of time to execute for any input of size .
This is possible thanks to the Principle of Invariance.
Two different implementations of the same algorithm will not differ in efficiency by more than some multiplicative constant.
A barometer instruction is one that is executed at least as often as any other instruction in the algorithm.
Theorem (Limit Criterion)
To establish the relation between two functions, we can use the following theorem.
Let and be two functions.
Let
- If , then (and
- If , then (and
- If , then (and
- If the limit does not exist, then we cannot conclude.
Fibonacci Numbers
def fib(n):if (n <= 1):return nelse:return fib(n-1) + fib(n-2)
This algorithm takes exponential time, which is super slow! A better solution to this problem is shown below:
def fib2(n):if (n <= 1):return nelse:f = [n]f[0] = 0f[1] = 1for i in range (2, len(n)):f[i] = f[i-1]+f[i-2]return f[n]
Here the running time is linear, . In this case, we can even say that it is
In terms of bit-operations (adding numbers), fib2(n) is quadratic.