Elementos de Programación Dinámica Profesor: Juan Francisco Diaz Elementos de . . . jdiaz@eisc.univalle.edu.co La Subsucesión . . . August 11, 2002 JJ II J I Page 1 of 15 Full Screen Quit 1. Elementos de Programación Dinámica • Cuándo buscar una solución con esta técnica? ? Subestructura Optima ? Subproblemas dependientes. Elementos de . . . La Subsucesión . . . JJ II J I Page 2 of 15 Full Screen Quit • Subestructura Optima: ? Un problema exhibe una Subestructura Optima si una solución óptima al problema contiene implı́citamente soluciones óptimas a subproblemas. ? La Subestructura óptima para un problema, normalmente sugiere el conjunto de subproblemas que pueden llegar a aparecer. Es muy importante que sean pocos (O(nk )) • Subproblemas dependientes: ? El conjunto de subproblemas debe ser pequeño (polinomial en el tamaño de la entrada), es decir, un algoritmo recursivo para el problema resuelve muchas veces los mismos subproblemas. En este caso se dice que los subproblemas se sobreponen,es decir, no son independientes. Elementos de . . . La Subsucesión . . . JJ II J I Page 3 of 15 Full Screen Quit ? Un problema resuelto con la técnica de Dividir y Conquistar normalmente no tiene esta caracterı́stica. ? Idea importante: almacenar las respuestas que se han calculado para no volverlas a calcular. Esto no cuesta mucho en espacio pues el número de subproblemas no es muy grande. ? Miremos lo costoso que puede resultar no almacenar los resultados de los subproblemas ya resueltos: ◦ Sucesión Matrices Recursivo (p, i, j) Elementos de . . . La Subsucesión . . . JJ II J I Page 4 of 15 Full Screen Quit 1 if i = j 2 then return 0 3 m[i, j] ← ∞ 4 for k ← i to j − 1 5 do q ← sucesión Matrices Recursivo (p, i, k) + sucesión Matrices Recursivo (p, k + 1, j) + p[i − 1] × p[k] × p[j] 6 if q < m[i, j] 7 then m[i, j] ← q 8 return m[i, j] ? El árbol de llamados recursivos que realiza el anterior algoritmo, para el caso Sucesión Matrices Recursivo (p, 1, 4) 1..4 Elementos de . . . La Subsucesión . . . 1..1 JJ II J 2..4 2..2 3..4 1..2 2..3 4..4 3..4 1..1 2..2 3..3 4..4 1..3 4..4 1..1 2..3 1..2 3..3 I Page 5 of 15 Full Screen Quit 3..3 4..4 2..2 3..3 2..2 3..3 1..1 2..2 De hecho se puede demostrar que ∀n ≥ 1: T (n) ≥ 2n−1 Elementos de . . . La Subsucesión . . . JJ II J I Page 6 of 15 Full Screen Quit • T (1) ≥ 1 = 20 P • T (n) ≥ 1 + ( n−1 k=1 (T (k) + T (n − k) + 1)), n > 1 Pn−1 = 1 + k=1 2T (k) + (n − 1) P k−1 + n Hip. de inducción ≥ 2 n−1 k=1 2 Pn−2 k = 2 k=0 2 + n = 2(2n−1 − 1) + n = 2(2n−1 ) − 2 + n = 2(2n−1 ) + (n − 2) ≥ 2n−1 ? Moraleja: Arbol de recursión con muchas repeticiones ⇒ usar programación dinámica. • Técnica de memorización: ◦ Cómo mejorar el algoritmo recursivo, para que no repita tantos cálculos? ◦ Cómo lograr una solución de arriba hacia abajo (top-down)? Memorización!! ◦ Idea: Mantener el control recursivo, pero memorizando lo calculado en una tabla. Sucesión Matrices Memorizada (p) Elementos de . . . La Subsucesión . . . 1 n ← length[p] − 1 2 for i ← 1 to n 3 do for j ← i to n 4 do m[i, j] ← ∞ 5 return Mire Sucesión (p, 1, n) Mire Sucesión (p, i, j) JJ II J I Page 7 of 15 Full Screen Quit 1 if m [i, j] < ∞ 2 then return m[i, j] 3 if i = j 4 then m[i, j] ← 0 5 else for k ← i to j − 1 6 do q ← Mirar Sucesión (p, i, k) + Mirar Sucesión (p, k + 1, j)+ p[i − 1] × p[k] × p[j] 7 if q < m[i, j] 8 then m[i, j] ← q 9 return m[i, j] ◦ Análisis del algoritmo: • Cada una de las n2 entradas de m, se calcula una sola vez por medio del llamado al algoritmo recursivo. • Todas las otras veces que se necesite su valor, se obtiene en tiempo constante. • La única vez que se calcula, toma O(n) tiempo, sin tomar en cuenta los llamados recursivos, que se toman en cuenta de manera global. Elementos de . . . La Subsucesión . . . JJ II J I Page 8 of 15 Full Screen Quit • Entonces la complejidad del algoritmo es: θ(n2 ).O(n) + O(n2 ) | {z } | {z } Cálculo de Número m[i, j] total de 1 ≤ i < j ≤ llamados n recursivos = O(n3 ) • En general, si se deben resolver todos los subproblemas al menos una vez, se prefieren las tablas dinámicas llenadas de abajo a arriba. Sino, se prefiere la técnica de memorización. 2. La Subsucesión común más larga • Dada X =< x1 , . . . , xm >, una sucesión Z =< z1 , z2 , . . . , zk > es una subsucesión de X si existen < i1 , i2 , . . . , ik >, 1 ≤ i1 < i2 < . . . < ik ≤ n, tales que xij = zj , j = 1, . . . , k. Por ejemplo:X =< A, B, C, B, D, A, B > Z =< B, C, D, B > (i1 = 2, i2 = 3, i3 = 5, i4 = 7) Elementos de . . . La Subsucesión . . . • Dadas X y Y , sucesiones, se dice que Z es una subsucesión común de X y Y , si Z es subsucesión de X y Z es una subsucesión de Y . JJ II J I Page 9 of 15 Full Screen Quit Por ejemplo X =< A, B, C, B, D, A, B > Y =< B, D, C, A, B, A > < B, C, A > es una subsucesión común de X y Y < B, C, B, A > también lo es < B, C, A, B >, < B, D, A, B > también lo son No hay una más larga. • El problema de la subsucesión común más larga (LCS) Entrada: X =< x1 , . . . , xm >, Y =< y1 , . . . , yn > Salida: La longitud de una subsucesión más larga de X y Y . Resolveremos este problema usando Programación Dinámica. Elementos de . . . • Caracterizar la estructura óptima: La Subsucesión . . . JJ II J I Page 10 of 15 Full Screen ? Sean X =< x1 , x2 , . . . , xm >, Y =< y1 , y2 , . . . , yn > y Z =< z1 , . . . , zk > una LCS de X y Y. Entonces: 1. Si xm = yn , entonces zk = xm = yn y < z1 , . . . , zk−1 > es una LCS de < x1 , . . . , xm−1 > y < y1 , . . . , yn−1 > 2. Si xm 6= yn y zk 6= xm entonces Z es una LCS de < x1 , . . . , xm−1 > y Y 3. Si xm 6= yn , y zk 6= yn entonces Z es una LCS de X y < y1 , . . . , yn−1 > Quit ? Entonces la estructura de una solución óptima al problema LCS, incluye soluciones óptimas a subproblemas del mismo problema. • Definir recursivamente el valor de una solución óptima: Sea Xi =< x1 , . . . , xi > el i-ésimo prefijo de X. De la caracterización se tiene que: 1. Si xm = yn entonces LCS (X,Y) = LCS(X_{m-1},Y_{n-1}) + 1 Elementos de . . . La Subsucesión . . . 2. Si xm 6= yn entonces LCS(X,Y) = max(LCS(X_{m-1},Y), LCS (X, Y_{n-1})) JJ II J I Entonces, si c[i, j] = “Longitud de la LCS (Xi , Yj )” : Page 11 of 15 Full Screen Quit si i = 0 o j = 0 0 c[i − 1, j − 1] + 1 si xi = yj c[i, j] = M ax{c[i − 1, j], c[i, j − 1]} si xi = 6 yj • Calcular el valor de una solución óptima: ? Existen mn subproblemas: pocos ⇒ Programación Dinánica. J n (i,j) j j-1 Elementos de . . . La Subsucesión . . . 2 Llenar C por filas !! 1 o llenar C por columnas !! I ? JJ II J I Page 12 of 15 Full Screen Quit 1 2 i-1 i m Elementos de . . . La Subsucesión . . . JJ II J I ? Longitud LCS(x,y) 1 m ← length[x] 2 n ← length[y] 3 for i → 1 to m 4 do c[i, 0] ← 0 5 for j ← 1 to n 6 do c[0, j] ← 0 7 for i ← 1 to m 8 do for j ← 1 to n 9 do if xi = yj 10 then c[i, j] ← c[i − 1, j − 1] + 1 11 b[i, j] ← “.” 12 else if c[i, j − 1] ≤ c[i − 1, j] 13 then c[i, j] ← c[i − 1, j] 14 b[i, j] ← “←” 15 else c[i, j] ← c[i, j − 1] 16 b[i, j] ← “↓” 17 return c y b Page 13 of 15 Full Screen Quit O(mn) • Construir una solución óptima ? Utilizar el arreglo b: .: xi = yj hace parte de una LCS de Xi , Yj ←: LCS (Xi , Yj ) = LCS (Xi−1 , Yj ) b[i, j] = ↓: LCS (Xi , Yj ) = LCS (Xi , Yj−1 ) Elementos de . . . La Subsucesión . . . JJ II J I ? Imprimir LCS (b, X, i, j) 1 if i = 0 or j = 0 2 then return 3 if b[i, j] = “ . ” 4 then imprimir LCS (b, X, i − 1, j − 1) 5 print “xi ” 6 else if b[i, j] = “ ← ” 7 then imprimir LCS (b, X, i − 1, j) 8 else imprimir LCS (b, X, i, j − 1) O(m + n) Page 14 of 15 Full Screen Quit • Mejorando la eficiencia ? En espacio: ◦ Eliminar b. El espacio usado sigue siendo O(mn) ◦ Guardar sola la fila i − 1 y la fila i hasta donde va. No sirve para reconstruir una solución. Elementos de . . . La Subsucesión . . . JJ II J I Page 15 of 15 Full Screen Quit