Metodología y Tecnología de la Programación Curso 2008/09 Tema 5 Introducción a la Complejidad Algorítmica Temario Tema 5. Introducción a la Complejidad Algorítmica 5.1 Algoritmos sencillos y complejos 5.1.1 Factores del Tiempo de Ejecución 5.2 Casos Peor y Promedio 5.3 Notaciones Asintóticas 5.3.1 Notaciones O y Ω 5.3.2 La Velocidad de Crecimiento 5.3.3 Funciones de Complejidad más Usuales 5.4 Cálculo del Tiempo de Ejecución de un Algoritmo 5.4.1 5.4.2 5.4.3 5.4.4 5.4.5 Operaciones en Notación Asintótica Series Cálculo del Tiempo de Ejecución Reglas Generales para Análisis de Algoritmos Propiedades de la Notación Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 2 1 Temario Tema 5. Complejidad de Algoritmos 5.1 Algoritmos sencillos y complejos 5.1.1 Factores del Tiempo de Ejecución 5.2 Casos Peor y Promedio 5.3 Notaciones Asintóticas 5.3.1 Notaciones O y Ω 5.3.2 La Velocidad de Crecimiento 5.3.3 Funciones de Complejidad más Usuales 5.4 Cálculo del Tiempo de Ejecución de un Algoritmo 5.4.1 5.4.2 5.4.3 5.4.4 5.4.5 Operaciones en Notación Asintótica Series Cálculo del Tiempo de Ejecución Reglas Generales para Análisis de Algoritmos Propiedades de la Notación Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 3 5.1 Algoritmos sencillos y complejos ¾ Cuando hay necesidad de elegir entre varios algoritmos, ¿cómo se debe elegir? Hay tres objetivos que suelen contradecirse: 1. Que el algoritmo sea fácil de entender, codificar y depurar. 2. Que el algoritmo se ejecute con la mayor rapidez posible. 3. Que el algoritmo utilice de forma óptima la memoria disponible. ¾ Lo que suele ocurrir frecuentemente: ¾ Se implanta primero un algoritmo sencillo ¾ Se efectúan simulaciones y mediciones antes de dedicarse al diseño definitivo ¾ Se determina el beneficio real que se obtendría escribiendo un algoritmo más complejo. Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 4 2 5.1.1 Factores del Tiempo de Ejecución ¾ El tiempo de ejecución de un programa depende de factores como: 1. Los datos de entrada al programa. 2. La calidad del código generado por el compilador utilizado para crear el programa objeto. 3. La naturaleza y rapidez de las instrucciones de máquina empleadas en la ejecución del programa, y 4. La complejidad de tiempo del algoritmo base del programa. ¾ Con frecuencia, el tiempo de ejecución no depende de la entrada exacta, sino sólo de su tamaño. Un buen ejemplo de esto es el proceso conocido como clasificación u ordenación. ¾ La medida natural del tamaño de la entrada a un programa de clasificación es el número de elementos a ordenar o, en otras palabras, la longitud de la lista de entrada. ¾ En general, la longitud de entrada es una medida apropiada de tamaño, y se supondrá que tal es la medida utilizada. Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 5 5.2 Casos Peor y Promedio ¾ T(n): tiempo de ejecución de un programa con una entrada de tamaño n. ¾ Ejemplo: un programa pueden tener un tiempo de ejecución T(n) = cn2, donde c es una constante. ¾ Las unidades de T(n) se dejan sin especificar. Se puede considerar a T(n) como el número de instrucciones ejecutadas en un ordenador idealizado. ¾ El tiempo de ejecución es en realidad una función de la entrada específica y no sólo del tamaño de ella. En este caso se define T(n) como el tiempo de ejecución del peor caso, es decir, el máximo valor del tiempo de ejecución para entradas de tamaño n ¾ También se considera Tprom(n), el valor medio del tiempo de ejecución de todas las entradas de tamaño n. Aunque Tprom(n) parece una medida más razonable, es engañoso suponer que las entradas son igualmente probables. Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 6 3 5.2 Casos Peor y Promedio (cont.) ¾ Como hemos dicho, no es posible expresar T(n) en unidades estándares de tiempo, como los segundos… Por lo tanto sólo se pueden hacer observaciones del tipo: “el tiempo de ejecución de tal algoritmo es proporcional a n2” Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 7 5.3 Notaciones Asintóticas 5.3.1 Notación O y Ω ¾ Para hacer referencia a la velocidad de crecimiento de los valores de una función se usará la notación conocida como notación asintótica (“o mayúscula”). ¾ Así, decir que el tiempo de ejecución T(n) de un algoritmo es O(n2), que se lee “o mayúscula de n al cuadrado” o tan sólo “o de n cuadrado”, significa que existen constantes positivas c y n0 tales que para n mayor o igual que n0, se tiene que: T(n)≤cn2. ¾ Dicho de otro modo, cuando el tiempo de ejecución de un programa es O(f(n)), se dice que tiene una velocidad de crecimiento f(n) Del mismo modo que f(n) es una cota superior para la velocidad de crecimiento de T(n), para especificar una cota inferior para la velocidad de crecimiento de T(n), se usa la notación T(n) es Ω(g(n)), que se lee “T(n) es omega mayúscula de g(n)” o simplemente “T(n) es omega de g(n)” Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 8 4 5.3.2 La velocidad de crecimiento ¾ ¿Es mejor un programa con tiempo de ejecución O(n2) que uno con tiempo O(n3)? Recordemos: T(n) ≤ cn2 • • Programa #1: 5n3 Programa #2: 100n2 5n3 / 100n2 = n/20 ¾ La respuesta a esto depende del tamaño de las entradas que se procesen los programas: espera que ¿entradas de tamaño n < 20? Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 9 5.3.3 Funciones de Complejidad más Usuales ¾ Las funciones de complejidad más usuales son (ordenadas de mejor a peor) son: • O(1). Complejidad constante. Por ejemplo, es la complejidad que se presenta en acciones de asignación. • O(log N). Complejidad logarítmica. Suele presentarse en algoritmos con iteración o recursión no estructural, como por ejemplo en el de búsqueda binaria. • O(N). Complejidad lineal. Suele aparecer en la complejidad de un ciclo cuando su cuerpo es de complejidad constante. • O(N log N). En algoritmos de recursión no estructural, por ejemplo QuickSort. • O(N2). Complejidad cuadrática. En ciclos doblemente anidados, por ejemplo ordenación por burbuja. • O(N3). Complejidad cúbica. En ciclos o recursiones triples. • O(Nk). Complejidad polinómica. Para k > 3. • O(2N). Complejidad exponencial. Problemas de explosión combinatoria, por ejemplo, generación de un plan. Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 10 5 5.4 Cálculo del Tiempo de Ejecución 5.4.1 Operaciones en Notación Asintótica ¾ Calcular el tiempo de ejecución de un programa, aunque sólo sea una aproximación a un factor constante, es un problema matemático complejo. ¾ En la práctica esto suele ser más sencillo; basta con aplicar unos cuantos principios básicos: Regla de la suma: supóngase que T1(n) y T2(n) son los tiempos de ejecución de dos algoritmos A1 y A2 y que: T1(n) es O(f(n)) T2(n) es O(g(n)) → Entonces T1(n) + T2(n), el tiempo de ejecución de A1 seguido de A2, es O(máx (f(n),g(n))) Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 11 5.4 Cálculo del Tiempo de Ejecución 5.4.1 Operaciones en Notación Asintótica Regla del producto: si T1(n) y T2(n) son O(f(n)) y O(g(n)) respectivamente: → Entonces T1(n)·T2(n) es O(f(n)·g(n))) → Según esto, O(c·f(n)) significa lo mismo que O(f(n)) donde c es una constante → Por ejemplo, O(n2/2) es lo mismo que O(n2) 5.4.2 Series Serie aritmética: En este tipo de serie, la diferencia (d) entre términos (t) sucesivos es constante: t, t + d, t + 2d, ..., t + (n – 1)d → Nos interesa su término general: Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 12 6 5.4.4 Reglas Generales para Análisis de Algoritmos ¾ No existe un conjunto completo de reglas para analizar algoritmos, sólo se proporcionarán ciertas sugerencias. 1. El tiempo de ejecución de cada proposición de asignación, por lo común, puede tomarse como O(1). Hay unas cuantas excepciones, como aquellos casos en que se permitan llamadas a funciones en proposiciones de asignación. O(T(Asignación)) = O(1) | O(T(Función)) 2. El tiempo de ejecución de una secuencia de proposiciones se determina por la regla de la suma, es decir, por el máximo tiempo de ejecución de una proposición de la secuencia. O(T(Secuencia)) = O(acción1) + ... + O(acciónN ) Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 13 5.4.4 Reglas Generales para Análisis de Algoritmos 3. El tiempo de ejecución de una proposición condicional Si es el costo de las proposiciones que se ejecutan condicionalmente, más el tiempo para evaluar la condición. O(T(Si)) = O(T(condición)) + O(T(cuerpo)) 4. El tiempo para una construcción Si-Entonces-Sino es la suma del tiempo requerido para evaluar la condición más el mayor entre los tiempos necesarios para ejecutar las proposiciones cuando la condición es verdadera y el tiempo de ejecución de las proposiciones cuando la condición es falsa. O(T(Si−Entonces−Sino)) = O(T(condición)) + Máx(O(T(Entonces)),O(T(Sino))) 5. El tiempo para ejecutar un ciclo es la suma, sobre todas las iteraciones del ciclo, del tiempo de ejecución del cuerpo y del empleado para evaluar la condición de terminación (este último suele ser O(1)). A menudo este tiempo es, despreciando factores constantes, el producto del número de iteraciones del ciclo y el mayor tiempo posible para una ejecución del cuerpo. O(T(ciclo)) = O(T(iteraciones)) *O(T(cuerpo)) Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 14 7 5.4.5 Propiedades de la Notación O( ) ¾ Teniendo dos funciones f(n) y g(n) se cumplen las siguientes propiedades en la notación O( ): • • • • • cO(f(n)) ⇒ O(f(n)) O(f(n) + g(n)) ⇒ Máx(O(f(n)),O(g(n))) O(f(n)) + O(g(n)) ⇒ O(f(n) + g(n)) O(f(n)) * O(g(n)) ⇒ O(f(n) * g(n)) O(O(f(n))) ⇒ O(f(n)) Las operaciones de suma y multiplicación son conmutativas. Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 15 Ejercicios Procedimiento Intercambiar (↓↑x, ↓↑y ∈ Entero) Constantes ∅ Variables aux ∈ Entero Acciones aux ← x x←y y ← aux Si (N MOD 2 = 0) Entonces Para I ← 1..N Hacer X←X+1 Fin Para Fin Si Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 16 8 Ejercicios Procedimiento Fibonacci(↓Número ∈ Entero, ↑Resultado ∈ Entero) Constantes ∅ Variables Contador, Aux, Fib-1, Fib-2 ∈ Entero Acciones Si Número ≤ 1 Entonces Resultado ← 1 Si no Fib-1 ← 1 Fib-2 ← 1 Para Contador ← 2..Número Hacer Aux ← Fib-2 Fib-2 ← Fib-1 Fib-1 ← Aux + Fib-1 Fin Para Resultado ← Fib-1 Fin Si Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 17 Ejercicios Procedimiento Burbuja (↓↑V ∈ Vector[1..N] ∈ Entero) Constantes ∅ Variables i, j ∈ Entero Acciones Para i ← 1 .. N-1 Hacer (B.1) Para j ← N .. i + 1 Hacer (B.2) Si A[j - 1] > A[j] Entonces (B.3) Intercambiar(A[j], A[j-1]) (B.4) Fin Si Fin Para Fin Para Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 18 9 Función BúsquedaBinariaNoRecursiva (E ∈ Entero, V ∈ Vector[1.. ÚltimaPosiciónVector] ∈ Entero) Æ 0..ÚltimaPosiciónVector Variables Inferior, Superior, Medio ∈ 1..ÚltimaPosiciónVector Encontrado ∈ Lógico Acciones Encontrado ← Falso Inferior ← 1 Superior ← ÚltimaPosiciónVector Mientras ((¬Encontrado) ∧ (Inferior ≤ Superior)) Hacer Medio ← (Inferior + Superior) DIV 2 Si (E = V[Medio]) Entonces Encontrado ← Verdadero Si no Si (E > V[Medio]) Entonces Inferior ← Medio + 1 Si no Superior ← Medio – 1 Fin Si Fin Si Fin Mientras Si Encontrado Entonces BúsquedaBinariaNoRecursiva ← Medio Si no BúsquedaBinariaNoRecursiva ←de 0 la Programación Metodología y Tecnología Tema 5. Introducción a la Complejidad Algorítmica Fin Si Ejercicios 19 Más Ejercicios… ¾ Exámenes ¾ Algoritmos del Tema 4 “Ordenación y Búsqueda” ¾ Algoritmos del Tema 5 “Introducción a la Complejidad Algorítmica” ¾ Cualquier otro algoritmo (no recursivo) de la asignatura Metodología y Tecnología de la Programación Tema 5. Introducción a la Complejidad Algorítmica 20 10