AGOSTO 2018
ESTRUCTURA DE DATOS
Unidad 1. Introducción a las estructuras de datos
1.5 Análisis de algoritmos
1.5.1 Complejidad en el tiempo
1.5.2 Complejidad en el espacio
1.5.3 Eficiencia de los algoritmos
MSE. J. JESÚS MINERO GUARDADO
Docente, Instituto Tecnológico Superior de Nochistlán
Introducción
¿Qué algoritmo es mejor para resolver un problema?
Introducción
Opción: Comparación de programas
• No es una comparación fiable porque la eficiencia de los programas
depende de factores “externos”
• Lenguaje de programación empleado
• Compilador empleado
• Máquina sobre la que se ejecute
Complejidad de un algoritmo
• Definición 1
El coste (o complejidad) temporal de un algoritmo es el tiempo
empleado por éste para ejecutarse y dar un resultado a partir de los
datos de entrada.
• Definición 2
El coste (o complejidad) espacial de un algoritmo es el espacio
ocupado en memoria antes, durante y después de ejecutarse.
Medida de la complejidad
• Se trata de medir (prever) la complejidad de un algoritmo
antes de escribir el programa.
• En realidad se trata de estimar el coste de los algoritmos
(tiempo o espacio).
Medida de la complejidad temporal
• Cada operación que pueda aparecer en un programa
consumirá un tiempo diferente. En general, desconocido por
el programador.
• No cuesta lo mismo
if (x<0)
i + j
i * j
sqrt(x)
i = j
Calculo de tiempo de un programa
Conteo de operaciones
La regla básica para calcular el tiempo de ejecución de un programa es ir
desde los lazos o construcciones más internas hacia las más externas.
Se comienza asignando un costo computacional a las sentencias básicas. A
partir de esto se puede calcular el costo de un bloque, sumando los
tiempos de cada sentencia.
Complejidad temporal
Parámetro de medición
Se toma el tamaño de entrada n (descripción de la instancia o segmento
de programa) para medir los requerimientos de tiempo de un algoritmo.
El tiempo de ejecución se describe como función de la entrada T(n)
Ejemplo:
T(n)=n2+2n
Complejidad temporal
T(n)=3n+2
Ejemplo
cont = 1; à 1
do {
x = x + a[cont]; à n
x = x + b[cont]; à n
cont = cont + 1; à n
} while (cont <= n) ; à n
TOTAL: 4n + 1
Ejemplo
z = 0; à 1
for (int x=1; x<=n; x++) à 1 + (n comp) + (n incr) = 2n+1
for (int y=1; y<=n; y++) à (1+n+n)*n = (2n +1)*n=2n2 +n
z = z + a[x,y]; à n*n = n2
TOTAL: 3n2 + 3n + 2
Notación O
• Se requiere contar con una notación que permita comparar la
eficiencia entre los algoritmos…
• La NOTACIÓN ASINTÓTICA (Aritmética de notación O) es la
propuesta de notación aceptada por la comunidad científica para
describir el comportamiento en eficiencia (o complejidad) de un
algoritmo.
• Describe en forma sintética el comportamiento de la función que
con la variable de entrada, determina el número de operaciones
que realiza el algoritmo.
Ordenes más comunes de los algoritmos
• O(1) Constante
• O(n) Lineal
• O(n2 ) Cuadrático
• O(n3 ) Cúbico
• O (nm ) Polinomial
• O(log(n)) Logarítmico
• O(nlog(n)) nlog (n)
• O(mn ) exponencial
• O(n!) factorial
Comportamiento de las funciones
n2
n sqrt(n)
n log n
n
log n
Reglas prácticas para calcular la complejidad
Ejemplo: Sort por intercambio
for (int i=1; i<n; i++)
for (int j=i+1; j<=n;j++)
if (a[ j ] < a[ i ]) → O( 1 ) → O( 1 )
intercambia(a[ i ], a[ j ]);
Ejemplo: Sort por intercambio
for (int i=1; i<n; i++) Peor caso: se repite n veces
for (int j=i+1; j<=n;j++)
if (a[ j ] < a[ i ]) → O( 1 ) → O( n )
intercambia(a[ i ], a[ j ]);
Ciclos = # veces * orden de la instrucción interna
Ejemplo: Sort por intercambio
Se repite n veces
for (int i=1; i<n; i++)
for (int j=i+1; j<=n;j++) → O( n2)
→ O( n )
if (a[ j ] < a[ i ])
intercambia(a[ i ], a[ j ]);
Ciclos = # veces * orden de la instrucción interna
Ejemplo de complejidad 3
O(n )
Otros ejemplos O à (log2 n)
A veces aparecen ciclos multiplicativos, donde la evolución de la variable de control no es lineal (como en los
casos anteriores)
c= 1;
While (c <n)
{
c= 2 * c;
}
El valor inicial de la variable c es 1, llegando a 2n al cabo de n - iteraciones.
El número de iteraciones es tal que 2k >= n >= k (log2 (n)) y, por tanto, la complejidad del ciclo es O(log2 n).
El siguiente es un ejemplo en el cual la variable se divide cada vez a la mitad:
c= n;
While (c > 1)
{
c=c/2
}
Otros ejemplos à O(n 2
log n)
Un razonamiento análogo nos lleva a log2n iteraciones y, por tanto, a un orden O(log2 n) de complejidad.
y la combinación de los anteriores:
for (i=0; i<n; i++)
{
c=i;
while (c>0)
{
c=c/2;
se tiene un bucle interno de orden O(log2 n) que se ejecuta n veces en el ciclo externo; luego el ejemplo es de orden O(n log2n)
Notación O
Jerarquía de órdenes de complejidad
O(1) Constante Eficiente
O(log n) Logarítmica
O(n) Lineal
O(n•log n) Casi lineal
O(n2) Cuadrática Tratable
O(n3) Cúbica
O(nk) k>3 Polinómica
O(kn) k>1 Exponencial Intratable
O(n!) Factorial
Notación O
Complejidad espacial
• Se mide calculando el tamaño de las variables involucradas en el
programa.
• Antes: declaración de variables.(Tipo)
• Durante: Operaciones con las variables
• Después: Valores modificados de las variables.
Ejemplo(2)
Usando la función de entrada T(n),determina la complejidad del
siguiente código.
sum=0 ;
for(i=0 ; i < n ; i++)
for(j=0; j < n; j++)
sum++;
Si n=10?
Ejercicio
Encuentra la complejidad
incrmnt = size/2;
while (incrmnt > 0)
{
for (i=incrmnt; i < size; i++)
{
j = i;
temp = A[i];
while ((j >= incrmnt) && (A[j-incrmnt] > temp))
{
A[j] = A[j - incrmnt];
j = j - incrmnt;
}
A[j] = temp;
}
incrmnt /= 2;
}
Solución
Ejercicio personal
• Realizar un análisis de complejidad de de algún código que desees
donde apliques las estrategias analizadas en clase.
Bibliografía
• DIRECCIÓN NACIONAL DE SERVICIOS ACADÉMICOS VIRTUALES, 2012.
Análisis y diseño de Algoritmos.
• CAIRO, GUAJARDO (2008). Estructura de datos