ingeniería en software facultad de ingeniería tecnológico de antioquia institución...

12
Análisis de Algoritmos 2. El concepto de complejidad (aritmética en notación O) Prof.: Ricardo Botero Tabares Ingeniería en Software Facultad de Ingeniería Tecnológico de Antioquia Institución Universitaria 2014

Upload: adlai

Post on 05-Jan-2016

35 views

Category:

Documents


0 download

DESCRIPTION

Análisis de Algoritmos 2. El concepto de complejidad ( aritmética en notación O) Prof.: Ricardo Botero Tabares. Ingeniería en Software Facultad de Ingeniería Tecnológico de Antioquia Institución Universitaria 2014. ANÁLISIS DE ALGORITMOS. 2. El concepto de complejidad - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Ingeniería en Software Facultad de Ingeniería Tecnológico de Antioquia  Institución Universitaria

Análisis de Algoritmos

2. El concepto de complejidad (aritmética en notación O)

Prof.: Ricardo Botero Tabares

Ingeniería en SoftwareFacultad de Ingeniería

Tecnológico de Antioquia Institución Universitaria

2014

Page 2: Ingeniería en Software Facultad de Ingeniería Tecnológico de Antioquia  Institución Universitaria

ANÁLISIS DE ALGORITMOS

2. El concepto de complejidad (aritmética en notación O)

Para calcular el tiempo de ejecución de un algoritmo se debe definir su orden de magnitud, basado en el contador de frecuencias.El orden de magnitud hace referencia a la aritmética en notación O.

Page 3: Ingeniería en Software Facultad de Ingeniería Tecnológico de Antioquia  Institución Universitaria

Orden de magnitud Representación

Constante O(1)

Logarítmico O(log2(n))

Lineal O(n)

Semilogarítmico O(nlog2(n))

Cuadrático O(n2)

Cúbico O(n3)

Exponencial O(2n)

Como se onotó antes, los órdenes de magnitud más comunes son los que se observan en la tabla inferior, donde los algoritmos más eficientes en cuanto a tiempo de ejecución son los de orden de magnitud constante, y los menos eficientes son los de orden de magnitud exponencial.

Eficiencia

Veamos otros algoritmos con orden de magnitud cúbico, logarítmico, semilogarítmico y exponencial.

Page 4: Ingeniería en Software Facultad de Ingeniería Tecnológico de Antioquia  Institución Universitaria

Algoritmo de complejidad cúbicaNo es difícil concebirlos: algoritmo con tres ciclos anidados.Ejemplo: llenar una arreglo de tres dimensiones.

//Declaraciones previas: variables globales o de claseint n; double cubo[] [] [];

void llenarCubo( ){//Se asume que la variable entera n tiene un valor consistente.cubo = new double[n] [n] [n];for (int i = 0; i < n; i++)

for (int j = 0; j < n; j++)for (int k = 0; k < n; k++){

Consola.imprimir(“Digite un número real:”);cubo [i] [j] [k] = Consola.leerReal();

}} Orden de magnitud: O(n3)

Page 5: Ingeniería en Software Facultad de Ingeniería Tecnológico de Antioquia  Institución Universitaria

Algoritmo de complejidad logarítmica

Recordemos el concepto de logaritmo:logb(x) = r

El número r es el exponente al cual hay que elevar el número b (base) para obtener x, es decir:

br = x

Ejemplos:log2(32) = 5 porque 25 = 32

log10(100) = 2 porque 102 = 100En otras palabras: el logaritmo de un número x es el número de veces que hay que dividir dicho número, por otro llamado base (b), hasta obtener un cociente de uno (1).

Page 6: Ingeniería en Software Facultad de Ingeniería Tecnológico de Antioquia  Institución Universitaria

Un algoritmo clásico de complejidad logarítmica en base 2, es el algoritmo de la búsqueda binaria sobre un vector ordenado.

vec

El algoritmo es el siguiente:

int busquedaBinaria(int dato) { // El vector vec y su tamaño n // son atributos de clase int centro, inf = 0, sup = n-1;while (inf <= sup){centro = (sup + inf) / 2; if (vec[centro] == dato) return centro; else if (dato < vec[centro]) sup = centro - 1; else inf = centro + 1; } return -1; }

3 5 8 13 19 23 31 36 45 50 57 61 72 81 93

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

Page 7: Ingeniería en Software Facultad de Ingeniería Tecnológico de Antioquia  Institución Universitaria

void metodoLogaritmico1( ){int n, cont, i;n = 32, cont = 0, i = 32;while (i > 1){

cont = cont + 1; i = i / 2;

}Consola.imprimir(n + “\n” + cont);

}

O también:

Otros algoritmos sencillos de complejidad logarítmica

i) O(log2(n))

Page 8: Ingeniería en Software Facultad de Ingeniería Tecnológico de Antioquia  Institución Universitaria

void metodoLogaritmico2( ){int n, cont, i;n = 32, cont = 0, i = 1;while (i < n){

cont = cont + 1; i = i * 2;

}Consola.imprimir(n + “\n” + cont);

}

ii) O(log2(n))

Page 9: Ingeniería en Software Facultad de Ingeniería Tecnológico de Antioquia  Institución Universitaria

void metodoLogaritmico3( ){int n, cont, i;n = 81, cont = 0, i = 81;while (i > 1){

cont = cont + 1; i = i / 3;

}Consola.imprimir(n + “\n” + cont);

}

iii) O(log3(n))

En general, si la variable controladora del ciclo (en este caso i) se dividiera por x, el algoritmo sería O(logx(n)).

Page 10: Ingeniería en Software Facultad de Ingeniería Tecnológico de Antioquia  Institución Universitaria

Algoritmo de complejidad semilogarítmica

Se debe tener un ciclo logarítmico dentro de otro ciclo de magnitud lineal. Ejemplo:

void semiLogaritmico( int n){int acum, i, j, tot;acum = 0, i = 1;while (i <= n){tot = 0;j = n;while (j > 1){tot = tot +1;j = j / 2;}Consola.imprimir(tot);acum = acum + tot;i = i + 1;}Consola.imprimir(n + “\n” + acum);}

Orden de magnitud: nlog2(n)

Page 11: Ingeniería en Software Facultad de Ingeniería Tecnológico de Antioquia  Institución Universitaria

Búsqueda del algoritmo más eficiente

Considérese el siguiente problema:Leer un entero positivo y mostrar la suma de los enteros desde uno (1) hasta el número ingresado.

Una solución inmediata es la siguiente:

void sumatoria( ){int n, suma = 0, i;Consola.imprimir(“Ingrese un número entero positivo:”);n = Consola.leerEntero( );for (i = 1; i <= n; i++)

suma += i;Consola.imprimir(“Suma enteros desde 1 hasta ” + n + “: ”+ suma);

}Este método es: O(n)

Page 12: Ingeniería en Software Facultad de Ingeniería Tecnológico de Antioquia  Institución Universitaria

Ahora, existe una fórmula matemática para calcular la suma de los enteros entre 1 y una variable entera n:

suma = = n*(n + 1) / 2

Aplicando esta fórmula, podemos solucionar el problema sin el uso de un ciclo en el cálculo de la sumatoria:

void sumatoriaConFormula( ){int n, suma;Consola.imprimir(“Ingrese un número entero positivo:”);n = Consola.leerEntero( );suma = n*(n + 1) / 2;Consola.imprimir(“Suma enteros desde 1 hasta ” + n + “: ”+

suma);}

Este método es: O(1)