0% found this document useful (0 votes)
18 views

EstructuraDatos AnalysisAlgorithms

Uploaded by

Vaktor Martinez
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views

EstructuraDatos AnalysisAlgorithms

Uploaded by

Vaktor Martinez
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

Analysis of Algorithms

Professor: Wilson Soto


Colombia

2019

Algorithms 2019
Algorithm

An algorithm is any well-defined computational procedure that takes some value,


or set of values, as input and produces some value, or set of values, as output. An
algorithm is thus a sequence of computational steps that transform the input into
the output.

Algorithms 2019 1
Why Analyze an Algorithm?

The most straightforward reason for analyzing an algorithm is to discover its


characteristics in order to evaluate its suitability for various applications or compare
it with other algorithms for the same application. Moreover, the analysis of an
algorithm can help us understand it better, and can suggest informed improvements.
Algorithms tend to become shorter, simpler, and more elegant during the analysis
process.

Algorithms 2019 2
Computational Complexity

The branch of theoretical computer science where the goal is to classify


algorithms according to their efficiency and computational problems according to
their inherent difficulty is known as computational complexity.

Algorithms 2019 3
Analysis of Algorithms

A complete analysis of the running time of an algorithm involves the following


steps:

1. Implement the algorithm completely.

2. Determine the time required for each basic operation.

3. Identify unknown quantities that can be used to describe the frequency of


execution of the basic operations.

Algorithms 2019 4
Analysis of Algorithms (cont.)

1. Develop a realistic model for the input to the program.

2. Analyze the unknown quantities, assuming the modelled input.

3. Calculate the total running time by multiplying the time by the frequency for
each operation, then adding all the products.

Algorithms 2019 5
The running time

The running time of an algorithm on a particular input is the number of primitive


operations or “steps” executed.

Usually, the analysis of algorithms is concentrate on finding only the worst-case


running time.

The worst-case running time of an algorithm gives us an upper bound on the


running time for any input. Knowing it provides a guarantee that the algorithm
will never take any longer.

Algorithms 2019 6
Order of growth

We usually consider one algorithm to be more efficient than another if its


worst-case running time has a lower order of growth.

Algorithms 2019 7
Asymptotic notation

The notations 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 usually is defined only on integer input sizes.

Algorithms 2019 8
O-notation

Definition 1. For a given function g(n), we denote by O(g(n)) the set of functions:

O(g(n)) = {f (n) | ∃c > 0, ∃n0 > 0, ∀n ≥ n0 : 0 ≤ f (n) ≤ cg(n)}

Algorithms 2019 9
Ω-notation

Definition 2. For a given function g(n), we denote by Ω(g(n)) the set of functions:

Ω(g(n)) = {f (n) | ∃c > 0, ∃n0 > 0, ∀n ≥ n0 : 0 ≤ cg(n) ≤ f (n)}

Algorithms 2019 10
Θ-notation

Definition 3. For a given function g(n), we denote by Θ(g(n)) the set of functions:

Θ(g(n)) = {f (n) | ∃c1 > 0, ∃c2 > 0, ∃n0 > 0, ∀n ≥ n0 : 0 ≤ c1g(n) ≤ f (n) ≤ c2g(n)}

Algorithms 2019 11
Algorithms 2019 12
Fibonacci Numbers

Draw the behaviour of the algorithms to get the n-th Fibonacci number.

The Fibonacci numbers are the numbers in the following integer sequence.

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, . . .

In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the


recurrence relation

Fn = Fn−1 + Fn−2

with seed values

F0 = 0 and F1 = 1

Algorithms 2019 13
Fibonacci Numbers

Given a number n, print n-th Fibonacci Number. Examples:

Input : n = 2
Output : 1

Input : n = 9
Output : 34

Signature in Java:

interface Funcion {
int fib (int n);
}

Algorithms 2019 14
Fibonacci Numbers (Method 1 - Recursion)

class Recursion implements Funcion {


int fib(int n) {
if (n <= 1) return n;
else return fib(n-1) + fib(n-2);
}
}

Time Complexity: T (n) = T (n − 1) + T (n − 2) which is exponential.

Algorithms 2019 15
Fibonacci Numbers (Method 2 - Dynamic Programming)

class DP implements Funcion {


int fib(int n) {
int f[] = new int[n+2];
int i;
f[0] = 0;
f[1] = 1;
for (i = 2; i <= n; i++)
f[i] = f[i-1] + f[i-2];

return f[n];
}
}

Time Complexity: O(n)

Algorithms 2019 16
Fibonacci Numbers (Method 3 - Space Optimized Method)

class SpaceOpt implements Funcion {


int fib(int n) {
int a = 0, b = 1, c;
if (n == 0) return a;
for (int i = 2; i <= n; i++) {
c = a + b;
a = b;
b = c;
}
return b;
}
}

Time Complexity: O(n)

Algorithms 2019 17
Fibonacci Numbers (Method 4 - Power of the matrix
{{1,1},{1,0}})

class Power implements Funcion {


int fib(int n) {
int F[][] = new int[][]{{1,1},{1,0}};
if (n == 0) return 0;
power(F, n-1);

return F[0][0];
}

static void multiply(int F[][], int M[][]) {


int x = F[0][0]*M[0][0] + F[0][1]*M[1][0];
int y = F[0][0]*M[0][1] + F[0][1]*M[1][1];
int z = F[1][0]*M[0][0] + F[1][1]*M[1][0];

Algorithms 2019 18
int w = F[1][0]*M[0][1] + F[1][1]*M[1][1];

F[0][0] = x;
F[0][1] = y;
F[1][0] = z;
F[1][1] = w;
}

static void power(int F[][], int n) {


int i;
int M[][] = new int[][]{{1,1},{1,0}};

for (i = 2; i <= n; i++)


multiply(F, M);
}
}
Time Complexity: O(n)

Algorithms 2019 19
Fibonacci Numbers (Method 5 - Optimized Power of the
matrix {{1,1},{1,0}})

class PowerOpt implements Funcion {


int fib(int n) {
int F[][] = new int[][]{{1,1},{1,0}};
if (n == 0) return 0;
power(F, n-1);

return F[0][0];
}

static void multiply(int F[][], int M[][]) {


int x = F[0][0]*M[0][0] + F[0][1]*M[1][0];
int y = F[0][0]*M[0][1] + F[0][1]*M[1][1];
int z = F[1][0]*M[0][0] + F[1][1]*M[1][0];

Algorithms 2019 20
int w = F[1][0]*M[0][1] + F[1][1]*M[1][1];

F[0][0] = x;
F[0][1] = y;
F[1][0] = z;
F[1][1] = w;
}

static void power(int F[][], int n) {


if ( n == 0 || n == 1) return;
int M[][] = new int[][]{{1,1},{1,0}};
power(F, n/2);
multiply(F, F);
if (n%2 != 0) multiply(F, M);
}
}
Time Complexity: O(log n)

Algorithms 2019 21
Fibonacci Numbers (Method 6 - Formula)

class Matrix implements Funcion {


static int f[];
int fib (int n) {
if (n == 0) return 0;
if (n == 1 || n == 2) return (f[n] = 1);

if (f[n] != 0)
return f[n];

int k = (n & 1) == 1? (n + 1) / 2 : n / 2;

f[n] = (n & 1) == 1? (fib(k) * fib(k) +


fib(k - 1) * fib(k - 1))
: (2 * fib(k - 1) + fib(k)) * fib(k);

Algorithms 2019 22
return f[n];
}
}

Time Complexity: O(log n)

Algorithms 2019 23
Fibonacci Numbers (Method 7 - Formula)

class Formula implements Funcion {


int fib (int n) {
double phi = (1 + Math.sqrt(5)) / 2;
return (int) Math.round(Math.pow(phi, n)
/ Math.sqrt(5));
}
}

Time Complexity: O(1)

Algorithms 2019 24
Analysis of Loops O(1)

Time complexity of a function (or set of statements) is considered as O(1) if it


does not contain loop, recursion and call to any other non-constant time function.

//set of non-recursive and non-loop statements

For example swap() function has O(1) time complexity.

A loop or recursion that runs a constant number of times is also considered as


O(1). For example the following loop is O(1).

// Here c is a constant
for (int i = 1; i <= c; i++) {
// some O(1) expressions
}

Algorithms 2019 25
Analysis of Loops O(n)

Time Complexity of a loop is considered as O(n) if the loop variables is


incremented / decremented by a constant amount. For example following functions
have O(n) time complexity.

// Here c is a positive integer constant


for (int i = 1; i <= n; i += c) {
// some O(1) expressions
}

for (int i = n; i > 0; i -= c) {


// some O(1) expressions
}

Algorithms 2019 26
Analysis of Loops O(nc)

Time complexity of nested loops is equal to the number of times the innermost
statement is executed. For example the following sample loops have O(n2) time
complexity

for (int i = 1; i <=n; i += c) {


for (int j = 1; j <=n; j += c) {
// some O(1) expressions
}
}

for (int i = n; i > 0; i -= c) {


for (int j = i+1; j <=n; j += c) {
// some O(1) expressions
}

Algorithms 2019 27
Analysis of Loops O(log n)

Time Complexity of a loop is considered as O(log n) if the loop variables is


divided / multiplied by a constant amount.

for (int i = 1; i <=n; i *= c) {


// some O(1) expressions
}
for (int i = n; i > 0; i /= c) {
// some O(1) expressions
}

Algorithms 2019 28
Analysis of Loops O(log log n)

Time Complexity of a loop is considered as O(log log n) if the loop variables is


reduced / increased exponentially by a constant amount.

// Here c is a constant greater than 1


for (int i = 2; i <=n; i = pow(i, c)) {
// some O(1) expressions
}
//Here fun is sqrt or cuberoot or any other constant root
for (int i = n; i > 0; i = fun(i)) {
// some O(1) expressions
}

Algorithms 2019 29
Analysis of Loops - How to combine time complexities of
consecutive loops?

When there are consecutive loops, we calculate time complexity as sum of time
complexities of individual loops.

for (int i = 1; i <=m; i += c) {


// some O(1) expressions
}
for (int i = 1; i <=n; i += c) {
// some O(1) expressions
}

Time complexity of above code is O(m) + O(n) which is O(m + n), if m == n,


the time complexity becomes O(2n) which is O(n).

Algorithms 2019 30
References

• Thomas H. Cormen, Clifford Stein, Ronald L. Rivest, and Charles E. Leiserson.


Introduction to Algorithms (3rd ed.). McGraw-Hill Higher Education.

• Robert Sedgewick and Philippe Flajolet. An Introduction to the Analysis of


Algorithms. Addison-Wesley. 2011.

• https://www.geeksforgeeks.org/analysis-of-algorithms-set-4-analysis-of-loops/

Algorithms 2019 31

You might also like