2 - Complejidad algoritmica
Transcripción
2 - Complejidad algoritmica
Algorítmica y Complejidad Tema 2 – Complejidad algorítmica. Complejidad algorítmica. 1. Tiempo de ejecución. 2. Comportamiento asintótico. 3. Complejidad. 4. Complejidad de algoritmos no recursivos. 5. Complejidad de algoritmos recursivos. 2 Complejidad algorítmica. 1. Tiempo de ejecución. 2. Comportamiento asintótico. 3. Complejidad. 4. Complejidad de algoritmos no recursivos. 5. Complejidad de algoritmos recursivos. 3 Tiempo de ejecución. Memoria utilizada. Eficiencia de un algoritmo Tiempo de ejecución. ¿De qué depende el tiempo de ejecución? • Datos de la entrada. • Calidad del código objeto. • Plataforma de ejecución. • Complejidad del algoritmo. Fundamentos. Factores externos al algoritmo. Factor interno. 4 Tiempo de ejecución. Vamos a estudiar el tiempo de ejecución de los algoritmos en función del tamaño de alguno de sus parámetros característicos. Por ejemplo: •Número de datos en la entrada. •Tamaño de los números con los que se va a operar. • Número de nodos en un grafo. Nos referiremos con T(n) al tiempo de ejecución de un algoritmo cuyo parámetro de estudio tiene un tamaño n. Fundamentos. 5 Tiempo de ejecución. Ejemplo: Búsqueda de un carácter en un array. Algoritmo a utilizar: Valor inicial del puntero 1 2 3 4 5 6 7 a e z b u c g n-1 n p v Orden de la búsqueda Valor final del puntero Fundamentos. Posición del carácter buscado (1..n) Carácter no encontrado (0) 6 Tiempo de ejecución. 1 2 3 4 5 6 7 a e z b u c g n-1 n p v Orden de la búsqueda A : array (1..n) of character; i := n; while (i > 0) and then (A(i) /= c) loop i := i - 1; end loop; return i; Fundamentos. 7 Tiempo de ejecución. 1 2 3 4 5 6 7 a e z b u c g Caso mejor: n-1 n p v Elemento buscado A : array (1..n) of character; Tiempo Veces i := n; t1 1 while (i > 0) and then (A(i) /= c) loop t2 t3 1 0 t4 1 i := i - 1; end loop; return i; Tmínimo = t1 + t2 + t4 Fundamentos. 8 Tiempo de ejecución. Caso malo: 1 2 3 4 5 6 7 a e z b u c g n-1 n p v Elemento buscado A : array (1..n) of character; Tiempo Veces i := n; t1 1 while (i > 0) and then (A(i) /= c) loop t2 t3 n n-1 t4 1 i := i - 1; end loop; return i; Tmalo = t1 + nt2 + (n-1)t3 + t4 Fundamentos. ¿Es el caso peor? 9 Tiempo de ejecución. 1 2 3 4 5 6 7 a e z b u c g Caso peor: n-1 n p v ¡El elemento buscado no está! A : array (1..n) of character; Tiempo Veces i := n; t1 1 while (i > 0) and then (A(i) /= c) loop t2 t3 n+1 n t4 1 i := i - 1; end loop; return i; Tmáximo = t1 + (n+1)t2 + nt3 + t4 Fundamentos. 10 Tiempo de ejecución. Caso medio: 1 a 1 a 2 e 2 e 3 z 3 z n-1 p n-1 p n v n v 1 a 1 a 1 a 2 e 2 e 2 e 3 z 3 z 3 z n-1 p n-1 p n-1 p n v n v n v Tiempo = t1 + t2 + t4 Tiempo = t1 + 2t2 + t3 + t4 + Tiempo = t1 + (n-1)t2 + (n-2)t3 + t4 Tiempo = t1 + nt2 + (n-1)t3 + t4 Tiempo = t1 + (n+1)t2 + nt3 + t4 n+1 ∑ t1 + k t2 + (k-1) t3 + t4 k=1 Fundamentos. 11 Tiempo de ejecución. n+1 n+1 k=1 k=1 ∑ t1 + k t2 + (k-1) t3 + t4 = ∑ t1 + k t2 + k t3 – t3 + t4 = n+1 n+1 n+1 k=1 k=1 k=1 = ∑ k (t2 + t3) + t1 – t3 + t4 = (t2 + t3) ∑ k + ∑ t1 – t3 + t4 = c1 n ∑k = c1 (n+1) (n+2) / 2 + c0 (n+1) Tmedio = c0 = n (n+1) / 2 k=1 c1 (n+1) (n+2) / 2 + c0 (n+1) (n+1) = Equiprobables = c1 (n+2) / 2 + c0 = n c1 / 2 + c1 + c0 = a b Tmedio = a n + b Fundamentos. 12 Complejidad algorítmica. 1. Tiempo de ejecución. 2. Comportamiento asintótico. 3. Complejidad. 4. Complejidad de algoritmos no recursivos. 5. Complejidad de algoritmos recursivos. 13 Comportamiento asintótico. Vamos a estudiar el comportamiento de los algoritmos cuando el tamaño de la entrada se lleva al límite: Cuando n ∞ T (n) El tiempo de ejecución del algoritmo anterior depende del número de elementos del array. an+b b n Fundamentos. 14 Comportamiento asintótico. Tiempos de ejecución de diferentes tipos de algoritmos sobre un computador capaz de procesar 1.000.000.000 instrucciones por segundo. T(n) N Log n n n log n n2 n3 2n n! 10 3,3 nS 10 nS 33 nS 100 nS 1 µS 1 µS 3,6 mS 50 5,6 nS 50 nS 282 nS 2,5 µS 125 µS 13 días > Edad universo 100 6,6 nS 100 nS 664 nS 10 µS 1 mS > Edad universo > Edad universo 1000 10 nS 1 µS 10 µS 1 mS 1S > Edad universo > Edad universo 10.000 13,3 nS 10 µS 133 µS 100 mS 16,7 min. > Edad universo > Edad universo 100.000 16,6 nS 100 µS 1,7 mS 10 S 11,6 días > Edad universo > Edad universo 1.000.000 19,9 nS 1 mS 20 mS 16,7 min. 32 años > Edad universo > Edad universo Fundamentos. 15 Comportamiento asintótico. Representación gráfica del comportamiento de varios tipos de algoritmos. T n! 2n n3 n2 n log n n log n n Fundamentos. 16 Complejidad algorítmica. 1. Tiempo de ejecución. 2. Comportamiento asintótico. 3. Complejidad. 4. Complejidad de algoritmos no recursivos. 5. Complejidad de algoritmos recursivos. 17 Complejidad. Cota superior (O) c Є R+, E f(n) ≤ c g(n) E O (g(n)) = { f(n) / n0 Є N: n ≥ n0 } A c g(n) f(n) Є O (g(n)) f(n) f(n) = O (g(n)) n0 Fundamentos. n 18 Complejidad. En el ejemplo visto anteriormente: T (n) = O (n) T (n) 2a n Por ejemplo: an+b c = 2a y n0 > b/a b b/a Fundamentos. n 19 Complejidad. Propiedades de la cota superior (O) f1(n) = O (g(n)) y f2(n) = O (h(n)) => f1(n) + f2(n) = O (max (g(n), h(n))) f1(n) = O (g(n)) y f2(n) = O (h(n)) => f1(n) x f2(n) = O (g(n) x h(n)) f(n) lim = =k g(n) n→∞ Fundamentos. ≠ 0 => O (f(n)) = O (g(n)) = 0 => f(n) = O (g(n)) y g(n) ≠ O (f(n)) 20 Complejidad. ... y más propiedades de la cota superior (O) O (k x f(n)) = k x O (f(n)) = O (f(n)) P(n) polinomio de grado k => P(n) = O (nk) O (loga n) = O (logb n) = O (log n) Fundamentos. 21 Complejidad. Cota inferior (Ω) c Є R+, E f(n) ≥ c g(n) A f(n) Є Ω (g(n)) E Ω (g(n)) = { f(n) / n0 Є N: n ≥ n0 } f(n) f(n) = Ω (g(n)) c g(n) n0 Fundamentos. n 22 Complejidad. En nuestro ejemplo nos sirve la misma función: T (n) = Ω (n) T (n) Por ejemplo: an+b c = a/2 y n0 ≥ 0 b a/2 n n Fundamentos. 23 Complejidad. Propiedades de la cota inferior (Ω) f1(n) = Ω (g(n)) y f2(n) = Ω (h(n)) => f1(n) + f2(n) = Ω (g(n) + h(n)) f1(n) = Ω (g(n)) y f2(n) = Ω (h(n)) => f1(n) x f2(n) = Ω (g(n) x h(n)) f(n) lim = =k g(n) n→∞ Fundamentos. ≠ 0 => Ω (f(n)) = Ω (g(n)) = 0 => f(n) ≠ Ω (g(n)) y g(n) = Ω (f(n)) 24 Complejidad. Orden exacto (Θ) E c1 g(n) ≤ f(n) ≤ c2 g(n) n0 Є N: A c1, c2 Є R+, E Θ (g(n)) = { f(n) / n ≥ n0 } Θ (g(n)) = O (g(n)) ∩ Ω (g(n)) c2 g(n) f(n) Є Θ (g(n)) f(n) f(n) = Θ (g(n)) c1 g(n) n0 Fundamentos. n 25 Complejidad. Para nuestro ejemplo: T (n) = Θ (n) T (n) 2a n Por ejemplo: c1 = a/2 an+b c2 = 2a n0 > b/a b a/2 n b/a Fundamentos. n 26 Complejidad. Propiedades del orden exacto (Θ) f1(n) = Θ (g(n)) y f2(n) = Θ (h(n)) => f1(n) + f2(n) = Θ (max (g(n), h(n))) f1(n) = Θ (g(n)) y f2(n) = Θ (h(n)) => f1(n) x f2(n) = Θ (g(n) x h(n)) f(n) lim = =k g(n) n→∞ Fundamentos. ≠ 0 => Θ (f(n)) = Θ (g(n)) = 0 => Θ (f(n)) ≠ Θ (g(n)) 27 Complejidad. O (f(n)) define un orden de complejidad. f(n) es la función más sencilla del conjunto. O (1) Orden constante O (log n) Orden logarítmico O (n log n) Fundamentos. O (n) Orden lineal O (n2) Orden cuadrático O (n3) Orden cúbico O (nk) Orden polinómico O (an) Orden exponencial O (n!) Orden factorial Orden polinómico 28 Complejidad. Jerarquía de órdenes de complejidad. O (n!) O (an) O (n3) O (n2) O (n log n) O (n) O (log n) O (1) Fundamentos. 29 Complejidad. • Cada orden de complejidad pertenece también a todos los órdenes superiores. • Los cambios en el Hw o Sw afectan al tiempo de ejecución pero no a la complejidad. • A veces la complejidad juega un papel secundario frente a otros factores: mantenibilidad, costes de desarrollo, frecuencia de utilización, ... • En general, un algoritmo de complejidad inferior será mejor que uno de complejidad superior. Fundamentos. 30 Complejidad. • Un algoritmo asintóticamente más eficiente que otro, puede no serlo para entradas pequeñas: 10 n2 n3 O (n2) O (n3) La elección lógica sería O (n2) pero sólo para valores n > 10 T (n) 10 Fundamentos. n 31 Complejidad algorítmica. 1. Tiempo de ejecución. 2. Comportamiento asintótico. 3. Complejidad. 4. Complejidad de algoritmos no recursivos. 5. Complejidad de algoritmos recursivos. 32 Complejidad de algoritmos no recursivos. Instrucción simple: I O(1) Secuencia de instrucciones simples: I1 O(1) I2 O(1) ......... Ik Fundamentos. O(1) O(1) 33 Complejidad de algoritmos no recursivos. Secuencia de instrucciones complejas: I1 O(f1(n)) I2 O(f2(n)) ......... Ik O(max (f1(n), f2(n),...,fk(n))) O(fk(n)) Bifurcaciones: f0(n) f1(n) Fundamentos. O(max (f0(n), f1(n), f2(n))) f2(n) 34 Complejidad de algoritmos no recursivos. Bucles: x f0(n) f1(n) O(f0(n) x f1(n)) Llamadas a procedimientos: Fundamentos. • No recursivas Complejidad del procedimiento. • Recursivas Más complicado 35 Complejidad de algoritmos no recursivos. Ejemplo 1: for i in 1..100 loop { O (1) } 100 x O (1) O (1) end loop; Fundamentos. 36 Complejidad de algoritmos no recursivos. Ejemplo 2: for i in 1..n loop { O (1) } n x O (1) O (n) end loop; Fundamentos. 37 Complejidad de algoritmos no recursivos. Ejemplo 3: for i in 1..n loop for j in 1..n loop { O (1) } n x n x O (1) O (n2) end loop; end loop; Fundamentos. 38 Complejidad de algoritmos no recursivos. Ejemplo 4: for i in 1..n loop for j in 1..i loop O (n2) { O (1) } i=1 j=1 i=2 j = 1, 2 i=3 j = 1, 2, 3 ...................... i=n j = 1, ..., n end loop; end loop; El número total de veces que se ejecuta es: n 1 + 2 + 3 + ... + n = ∑ k = n (n+1) / 2 = (n2 + n) / 2 k=1 Fundamentos. 39 Complejidad de algoritmos no recursivos. Ejemplo 5: i := 1; while i < n loop { O (1) } O (log n) i := 2 * i; end loop; En la iteración k i = 2k Finaliza cuando 2k ≥ n Fundamentos. log2 2k ≥ log2 n k ≥ log2 n 40 Complejidad de algoritmos no recursivos. Ejemplo 6: if a > b then O(1) for i in 1..n loop O(n) O(1) { O (1) } end loop; else O (n) a := b; end if; Fundamentos. 41 Complejidad de algoritmos no recursivos. Ejemplo 7: for i in 1..n loop ¿ O (n3) ? if i = 1 then {O (n2) else { O (n) } end if; } i=1 n2 i=2 n i=3 n ............. i=n n n2 + n + ... + n = n2 + (n – 1) n = 2 n2 – n O (n2) end loop; Fundamentos. 42 Complejidad de algoritmos no recursivos. Ejemplo 8: function factorial (n : natural) return natural is fac : natural := 1; begin if n>0 then for i in 1..n loop fac := fac * i; end loop; end if; return fac; end factorial; ............... ............... factorial (x); O (n) Fundamentos. 43 Complejidad algorítmica. 1. Tiempo de ejecución. 2. Comportamiento asintótico. 3. Complejidad. 4. Complejidad de algoritmos no recursivos. 5. Complejidad de algoritmos recursivos. 44 Complejidad de algoritmos recursivos. Sólo vamos a utilizar los siguientes métodos: •Expansión de las recurrencias. •Resolución de las ecuaciones en recurrencia. En la resolución de ecuaciones examinaremos sólo las que sean lineales (homogéneas o no) y con raíces reales tanto sencillas como múltiples. Fundamentos. 45 Complejidad de algoritmos recursivos. Expansión de las recurrencias. function factorial (n : natural) return natural is begin if n=0 then return 1; else return n * factorial (n-1); end if; end factorial; T(0) = 1 Factorial Fundamentos. T(n) = T(n-1) + 1, n≥1 46 Complejidad de algoritmos recursivos. Desarrollo de algunos términos: T(n) = T(n-1) + 1 T(n-1) = T(n-2) + 1 T(n-2) = T(n-3) + 1 Sustitución de términos: T(n) = T(n-1) + 1 = T(n-2) + 1 + 1 = T(n-3) + 1 + 1 +1 Término general: T(n) = T(n-k) + k Término no recursivo: k=n T(n) = T(n-n) + n = T(0) + n = 1 + n T(n) = O (n) Fundamentos. 47 Complejidad de algoritmos recursivos. Recurrencias lineales homogéneas: a0 T(n) + a1 T(n-1) + a2 T(n-2) + ... + ak T(n-k) = 0 T(n) = xk a0 xk + a1 xk-1 + a2 xk-2 + ... + ak = 0 (Ecuación característica) Fundamentos. 48 Complejidad de algoritmos recursivos. Raíces sencillas: (x – r1) (x – r2) ... (x – rk) = 0 k T(n) = ∑ ci rin = c1 r1n + c2 r2n + ... + ck rkn i=1 Raíces múltiples: (x – r1)m1 (x – r2)m2 ... (x – rk)mk = 0 m1 m2 mk i=1 i=1 i=1 T(n) = ∑ c1i ni-1 r1n + ∑ c2i ni-1 r2n + ... + ∑ cki ni-1 rkn ci y cki se determinan a partir de las condiciones iniciales. Fundamentos. 49 Complejidad de algoritmos recursivos. Recurrencias lineales no homogéneas: a0 T(n) + a1 T(n-1) + ... + ak T(n-k) = b0n p0(n) + ... + bsn ps(n) di = grado de pi(n) (a0 xk + a1 xk-1 + a2 xk-2 + ... + ak) (x – b0)d0+1 ... (x – bs)ds+1 = 0 (Ecuación característica) A partir de aquí se procede como en los casos anteriores. Fundamentos. 50 Complejidad de algoritmos recursivos. Ejemplo 1: T(0) = 0 Sucesión de Fibonacci: T(1) = 1 T(n) = T(n-1) + T(n-2), n ≥ 2 a0 T(n) + a1 T(n-1) + a2 T(n-2) + ... + ak T(n-k) = 0 T(n) – T(n-1) – T(n-2) = 0 a0 = 1 a1 = -1 a2 = -1 k = 2 Lineal homogénea. Fundamentos. 51 Complejidad de algoritmos recursivos. T(n) – T(n-1) – T(n-2) = 0 T(n) = xk = x2 x2 – x – 1 = 0 x= 1+√5 2 1-√5 2 k T(n) = ∑ ci rin = c1 r1n + c2 r2n + ... + ck rkn i=1 T(n) = c1 n n 1+√5 1-√5 + c2 2 2 Raíces sencillas. Fundamentos. 52 Complejidad de algoritmos recursivos. T(0) = c1 T(1) = c1 0 0 1+√5 1-√5 + c2 = c1 + c2 = 0 2 2 c1 = – c2 = 1 1 1-√5 1+√5 + c2 =1 2 2 T(n) = 1 √5 n 1 1+√5 – 2 √5 T(n) = O Fundamentos. 1+√5 2 1-√5 2 1 √5 n n 53 Complejidad de algoritmos recursivos. Ejemplo 2: T(0) = 0 Ecuación en recurrencia: T(1) = 1 T(2) = 2 T(n) = 5 T(n-1) – 8 T(n-2) + 4 T(n-3), n ≥ 3 a0 T(n) + a1 T(n-1) + a2 T(n-2) + ... + ak T(n-k) = 0 T(n) – 5 T(n-1) + 8 T(n-2) – 4 T(n-3) = 0 Lineal homogénea. Fundamentos. a0 = 1 a1 = -5 a2 = 8 a3 = -4 k = 3 54 Complejidad de algoritmos recursivos. T(n) – 5 T(n-1) + 8 T(n-2) – 4 T(n-3) = 0 T(n) = xk = x3 x3 – 5 x2 + 8 x – 4 = 0 2 2 1 x= m1 m2 mk i=1 i=1 i=1 T(n) = ∑ c1i ni-1 r1n + ∑ c2i ni-1 r2n + ... + ∑ cki ni-1 rkn 2 1 i=1 i=1 T(n) = ∑ c1i ni-1 2n + ∑ c2i ni-1 1n T(n) = c11 n0 2n + c12 n1 2n + c21 n0 1n T(n) = c11 2n + c12 n 2n + c21 Raíces múltiples. Fundamentos. 55 Complejidad de algoritmos recursivos. T(0) = c11 20 + c12 0 20 + c21 = c11 + c21 = 0 c11 = 2 T(1) = c11 21 + c12 1 21 + c21 = 2 c11 + 2 c12 + c21 = 1 c12 = – ½ T(2) = c11 22 + c12 2 22 + c21 = 4 c11 + 8 c12 + c21 = 2 c21 = – 2 T(n) = 2 2n – ½ n 2n – 2 Fundamentos. T(n) = O (n 2n) 56 Complejidad de algoritmos recursivos. Ejemplo 3: Ecuación en recurrencia: T(0) = 1 T(n) = 2 T(n-1) + n + 2n, n ≥ 1 a0 T(n) + a1 T(n-1) + ... + ak T(n-k) = b0n p0(n) + ... + bsn ps(n) T(n) – 2 T(n-1) = 2n + n a0 = 1 a1 = -2 k = 1 b0 = 1 b1 = 2 d0 = 1 d1 = 0 Lineal no homogénea. Fundamentos. 57 Complejidad de algoritmos recursivos. (a0 xk + a1 xk-1 + a2 xk-2 + ... + ak) (x – b0)d0+1 ... (x – bs)ds+1 = 0 (Ecuación característica) a0 = 1 a1 = -2 k = 1 b0 = 1 d0 = 1 b1 = 2 d1 = 0 (a0 xk + a1 xk-1) (x – b0)d0+1 (x – b1)d1+1 = 0 (1 x1 – 2 x1-1) (x – 1)1+1 (x – 2)0+1 = 0 (x – 1)2 (x – 2)2 = 0 Fundamentos. x= 1 1 2 2 58 Complejidad de algoritmos recursivos. m1 m2 mk i=1 i=1 i=1 T(n) = ∑ c1i ni-1 r1n + ∑ c2i ni-1 r2n + ... + ∑ cki ni-1 rkn 2 2 i=1 i=1 n1 T(n) = ∑ c1i ni-1 1n + ∑ c2i ni-1 2n T(n) = c11 n0 1n + c12 1n + c21 n0 2n + c22 n1 2n T(n) = c11 + c12 n + c21 2n + c22 n 2n Raíces múltiples. Fundamentos. 59 Complejidad de algoritmos recursivos. Necesitamos más condiciones iniciales T(0) = 1 T(1) = 2 T(0) + 1 + 21 = 5 T(2) = 2 T(1) + 2 + 22 = 16 T(3) = 2 T(2) + 3 + 23 = 43 T(0) = c11 + c21 20 = c11 + c21 = 1 T(1) = c11 + c12 1 + c21 21 + c22 1 21 = c11 + c12 + 2 c21 + 2 c22= 5 c11 = – 2 T(2) = c11 + c12 2 + c21 22 + c22 2 22 = c11 + 2 c12 + 4 c21 + 8 c22= 16 c21 = 3 c12 = – 1 c22 = 1 T(3) = c11 + c12 3 + c21 23 + c22 3 23 = c11 + 3 c12 + 8 c21 + 24 c22= 43 T(n) = – 2 – n + 3 2n + n 2n Fundamentos. T(n) = O (n 2n) 60 Complejidad de algoritmos recursivos. Observaciones: • Realmente no es necesario calcular los coeficientes ci y cij para determinar la complejidad. • Sí es necesario su cálculo para obtener el tiempo de ejecución. Fundamentos. 61