- Published on
Analysis Of Algorithms
- Authors
- Name
- Simon Kurbiel
Introduction
This will be the introduction to data structures and algorithms. Most of the concepts here can be applied to any classical algorithm. We willl focus mainly on the analysis and proof portions. For the programming parts, i have decided to write them in python. However, I might add c/go parts as well. Here is the table of contents.
Worst-case and Average-case Analysis
Linear Search Algorithm
let us take a simple algorithm such as the linear search. We have a key , and we would like to find it's index. Here is the algoriithm
def linear_search(arr, key):
for i in range(len(arr)):
if arr[i] == key:
return i
return -1
worst-case
The worst case will be mostly what we are looking for, not only because it is easier, but also because it is a good reflection of overall performance. In this case, the worst case is abviously , if the key is the last item or if it doesn't exists at all. Because each iteration of the for loop will take some constant time , in this case, the worst-case time of the algorithm is
The constant represents the maximum amount of time for all statements that are execute only once, independent of the variable
average case
Calculating the average case is a bit more involved, so we will skip it as worst-case is what is mostly sought after.
Finding Max & Min of an Array
Here is a python program to find the max and min of an Array
def max_min(array:list)->tuple:
max:int =array[0]
min:int = array[0]
for i in range(1,len(array)):
if array[i] > max:
max = array[i]
elif array[i] < min:
min = array[i]
return min,max
worst case
in this case, the worst case scenario is very simple to spot. The for loop will be executed at least times at skips the first index. However, the worst case scenario is if it is in a decending order, which means both if else blocks will be executed which makes our algorithm run times
Asymptotic Complexity
intro
When we study the running time of algorithms, our focus is on the perfomance when the size gets very large, because for smaller numbers, the running time will be very small anyways.
Suppose there are two algorithms for a problem of size n, with these running tmes:
Which one of these is faster? Lets tabulate the results for some values of
1 | 10 | 2 |
2 | 20 | 8 |
5 | 50 | 50 |
10 | 100 | 200 |
100 | 1,000 | 20,000 |
1,000 | 10,000 | 2,000,000 |
10,000 | 100,000 | 200,000,000 |
100,000 | 1,000,000 | 2 10^10 |
We can observe the following things
- for , is larger
- at , they are both even
- at , grows faster
Since grows larger than for larger input , we say that is asymptotically larger than . Generally, when comparing algorithms, we drop the lowest coeffecients as it isnt a good indicator as seen above.
Upper Bound
suppose there are positive constants and such that
Then we say is The is read as "big oh" of.
Example
Prove the following function is
Solution: Intuitively, when gets large, the total value will be ~ because the remaining terms are negligible. Now we have to prove that is by finding the positive constants and such that
Example
Prove the following polynomial is
Proof : first we need to get rid of the negative terms
Lower Bound
Ω Lower bound is symmetrical to
Suppose there are positive constants and such that
Then we say is Ω
Example
Prove the following polynomial is Ω
Proof : We must show that for some positive constants . Here we need to pick carefully so that the constant becomes positive.
Tight Bound
Tight Bound
Suppose there are positive constants such that
That is, is both and
Then we say that is .
Example
Prove the following summation is Θ without using the arithmetic sum formula
- Prove
- Prove Ω
Analysis
Nested Loop
suppose we have an algorithm that looks like this
c = 0
for i in range(n+1):
for j in range(i,3n-1):
c = c+1
For this problem, it's much easier if we simply just do a loop analysis. We simply use the sum-rule and product-rule.
- we know that the inner loop is execute times. Since the range of values is 1 to , then we know is
- The outer loop is executed times, which is .
- Therefore by product rule, the total running time is O(n^2)
Insertion Sort Algorithm
def insertion_sort(array:list)->None:
for i in range(1,len(array)):
j:int = i
while j > 0 and array[j] < array[j-1]:
temp:int = array[j]
array[j] = array[j-1]
array[j-1] = temp
j = j-1
worst case
The worst case scenario of the insertion algorithm is if everything is in a descending order. In this case, since the first number is skipped, the number of comparisons will be,
The result was obtained using the arithmetic sum formula. We conclude that the worst-case total time of the algorithm is