Análisis de Algoritmos: 2. El Concepto de Complejidad (Aritmética en Notación O)

Descargar como pptx, pdf o txt
Descargar como pptx, pdf o txt
Está en la página 1de 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
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.
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.

Orden de magnitud Representación


Constante O(1)
Logarítmico O(log2(n))
Lineal O(n)
Semilogarítmico O(nlog2(n)) Eficiencia
Cuadrático O(n2)
Cúbico O(n3)
Exponencial O(2n)

Veamos otros algoritmos con orden de magnitud cúbico, logarítmico,


semilogarítmico y exponencial.
Algoritmo de complejidad cúbica
No es difícil concebirlos: algoritmo con tres ciclos anidados.
Ejemplo: llenar una arreglo de tres dimensiones.

//Declaraciones previas: variables globales o de clase


int 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)
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 = 100
En 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).
Un algoritmo clásico de complejidad logarítmica en base 2, es el algoritmo de la búsqueda binaria
sobre un vector ordenado.
vec

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

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;
}
Otros algoritmos sencillos de complejidad logarítmica

i) O(log2(n))

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:
ii) O(log2(n))

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);
}
iii) O(log3(n))

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);
}

En general, si la variable controladora del ciclo (en este caso i)


se dividiera por x, el algoritmo sería O(logx(n)).
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)


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)
•entre
Ahora, existe una fórmula matemática para calcular la suma de los enteros
  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)

También podría gustarte