Análisis de complejidad introducción notación big o

15

Click here to load reader

description

Calculo de la complejidad de un algoritmo para comprender el comportamiento asintótico del mismo, como precursor a la notación "Big-O"

Transcript of Análisis de complejidad introducción notación big o

Page 1: Análisis de complejidad   introducción notación big o

Análisis de complejidad

Introducción a la notación Big-O

http://discrete.gr/complexity/?es

Page 2: Análisis de complejidad   introducción notación big o

Introducción

• La complejidad de un algoritmo es una forma de evaluar qué tan rápido se ejecuta un algoritmo o programa.

• El análisis de complejidad permite comparar dos algoritmos, de manera independiente de su implementación y nos permite explicar cómo se comporta a medida que aumentan los datos de entrada.

Page 3: Análisis de complejidad   introducción notación big o

Introducción

• Para analizar el comportamiento de un algoritmo debemos contar cuántas instrucciones fundamentales ejecuta el pedazo de código que estamos analizando.

• Para contar cuántas instrucciones hay, tenemos que encontrar las instrucciones sencillas que pueden ser ejecutados directamente por la UCP

Page 4: Análisis de complejidad   introducción notación big o

Instrucciones básicas

• Supondremos que nuestro procesador puede ejecutar las siguientes instrucciones por separado.

• Asignar un valor a una variable• Buscar el valor de un elemento particular de un

arreglo• Comparar dos valores• Incrementar un valor• Operaciones aritméticas básicas

Page 5: Análisis de complejidad   introducción notación big o

Analicemos este fragmento de código

int M = A[0]for (int i=0; i<n;i++) { if (A[i] >= M) { M = A[i]; }}

Buscar, asignar = 2 instrucciones

1ª iteración: asignación y comparación =2 instruccionesSig. “n” iteraciones: comparación e incremento=2 instrucciones

Buscar y comparar = 2 instrucciones

Si entra al if: encontrar y asignar = 2 instrucciones *pero no siempre ocurre*

El ciclo for sin ninguna instrucción tiene f(n) = 4 + 2*n instrucciones.La cantidad de instrucciones con el if no pueden definirse tan fácilmente

Page 6: Análisis de complejidad   introducción notación big o

Análisis del peor caso

• f(n) no puede definirse tan fácilmente por que la cantidad de instrucciones no sólo depende de “n” sino también de la entrada.

• Si A=[1,2,3,4]• Si A=[4,3,2,1]• ¿Qué es lo peor que puede ocurrir con

nuestro algoritmo? ¿Cuándo se requerirá la mayor cantidad de instrucciones?

Page 7: Análisis de complejidad   introducción notación big o

Análisis del peor caso

• En el ejemplo, el peor caso es cuando M tiene que reemplazarse cada vez, y genera la mayor cantidad de instrucciones en el for.

• f(n)=4 + 2n + 4n =6n+4• Esta función f, dado un tamaño “n” del

problema, entrega el número de instrucciones que serán necesarias en el peor de los casos.

Page 8: Análisis de complejidad   introducción notación big o

Comportamiento asintótico

• No siempre es necesario contar las instrucciones, además de que la cantidad real de instrucciones depende del compilador y el lenguaje de programación.

• Ahora encontraremos la función “f” a través de un filtro.

Page 9: Análisis de complejidad   introducción notación big o

Comportamiento asintótico

• En la función 6n + 4 tienen 2 términos: 6n y 4• Queremos ver cómo se comporta el algoritmo

cuando se le trata de forma ruda (peor escenario) lo cual es bastante útil cuando comparamos algoritmos.

• De los términos de la función vamos a ignorar los que crecen lentamente y mantendremos los que crecen rápidamente conforme “n” se incrementa.

Page 10: Análisis de complejidad   introducción notación big o

Comportamiento asintótico

• En nuestra función dejaremos el término 6n.• También ignoraremos a la constante que

multiplica a “n”. f(n)=n• Esto de eliminar los factores y mantener el

término de mayor crecimiento, es lo que denominamos “comportamiento asintótico”

• El comportamiento asintótico de f(n)=4+6n es f(n)=n.

Page 11: Análisis de complejidad   introducción notación big o

Comportamiento asintótico

Función• f(n)=5n + 12• f(n)=109• f(n)=n2+3n + 112• f(n)= n3+1999n + 1337• f(n)=n + sqr(n)

Comportamiento asintótico• f(n)=n• f(n)=1• f(n)=n2

• f(n)=n3

• f(n)=n

Page 12: Análisis de complejidad   introducción notación big o

ANALICEMOS LA COMPLEJIDAD Y COMPORTAMIENTO ASINTÓTICO DEL SIGUIENTE FRAGMENTO DE CÓDIGO

Ordenamiento burbuja

Page 13: Análisis de complejidad   introducción notación big o

for (int i = 0; i<100; i++){ num = rand() % 100; if (i>0){ for (int j = 0; j<i; j++) if (num == c[j]){ num = rand() % 100; j = -1; } } c[i] = num; } //ordenar arreglo for (int x = 0; x<100; x++){ for (int y = 0; y<99; y++){ if (c[y]>c[y + 1]){ b = c[y]; c[y] = c[y + 1]; c[y + 1] = b; } } //mostrar arreglo for (int h = 0; h<100; h++) cout << c[h] << "\t";

Page 14: Análisis de complejidad   introducción notación big o

ANALICEMOS LA COMPLEJIDAD Y COMPORTAMIENTO ASINTÓTICO DEL ORDENAMIENTO INSERCIÓN

Page 15: Análisis de complejidad   introducción notación big o

//ordenar arreglo for (int l = 0; l<99; l++){ pos_m = inicial(k, l); if (k[l]>k[pos_m]){ m = k[pos_m]; for (int g = pos_m - 1; g >= 1; g--){ k[g + 1] = k[g]; } k[l] = m; } for (int h = 0; h<100; h++) cout << k[h] << "\t"; cout << endl; }. . .

//parte del ordenamiento de insercionint inicial(int o[], int c){ int p = c; int d = o[c]; for (int h = c; h<100; h++){ if (o[h]<d){ d = o[h]; p = h; } } return p; }