Está en la página 1de 15

Programacin Dinmica

Richard Bellman es el creador de la programacin dinmica.


Parte del denominado principio de optimalidad:
En una sucesin ptima de decisiones u opciones, toda subsecuencia debe ser
tambin ptima.
Para abordar y solucionar un problema con esta tcnica hay tres componentes
esenciales:
- Detectar una relacin de recurrencia (ms algna(s) condicion(es) base).
Para calcular valores en funcin de valores ms pequeos, apelando al
principio de optimalidad. Hasta utilizar las condiciones (valores) base
establecidas explcitamente.
- Efectuar un cculo tabular (en forma de tabla o matriz), para calcular los
valores de manera eficiente y progresiva -bottom-up- (en vez de refinamientos
top-down, fciles de codificar pero muy morosos e ineficientes en tiempo de
clculo).
- Presentar un modo de rastreo (traceback), para obtener respuestas
completas.
Presentaremos algunos problemas conocidos para resolverlos con programacin
dinmica.
El Problema de la Mochila
Se tiene un conjunto de n objetos {O1,,On} (digamos que en una mesa).
El i-simo objeto tiene un peso pi y un valor vi.
Se tiene una mochila con una capacidad de peso C.
Debemos llenar la mochila con los objetos que se pueda (de la mesa):
- Siempre que no superemos la capacidad C de la mochila .
- Y MAXIMICEMOS el valor de los objetos.
Si utilizamos las variables xi donde:
1 si decidimos tomar el objeto i-simo
xi=
0 si decidimos no tomar el objeto i-simo
El problema no es otro que:
n

max{ xivi } sujeto a la restriccin


i 1

i 1

xipi C

El algoritmo voraz no funciona.


Es fcil ver eso con n=3; C=10; p1=6, v1=8; p2=5, v2=5; p3=5, v3=5.
Otros posibles casos para entender el problema y resolver a mano son:
n=4; C=5; pi=[1, 2, 3, 4]; vi=[500, 450, 400, 300]
n=6; C=100; pi=[100, 50, 45, 20, 10, 5]; vi=[40, 35, 18, 4, 10, 2]
Resolvmoslo con programacin dinmica:

Crearemos una tabla M.


M(i,j) denota el valor mximo de los objetos que llenamos en la mochila:
- Considerando la (posible) inclusin de los objetos numerados de 1 hasta i.
- Con una capacidad j.
Obviamente i llega hasta n, as como j llega hasta C.
Por supuesto deseamos el valor M(n,C).
(*) Es claro que M(0,j) = 0 para j0.
(**) Definiremos M(i,j) = - cuando j<0 (para cualquier i).
Qu posibilidades hay para M(i,j), es decir, qu hacemos con Oi, lo aadimos
o no (recuerde que tenemos ya algunos valores anteriores) ?
- No aadimos Oi a la mochila.
En cuyo caso es evidente que: M(i,j) = M(i-1,j).
- Aadimos Oi a la mochila. En cuyo caso debemos cuidarnos de restar a la
capacidad j el peso pi de Oi (pues de lo contrario sobrepasaramos j).
Es decir, partir de una mochila de valor mximo con objetos hasta i-1, con una
capacidad j-pi (para que aguante pi); aadimos Oi cuyo peso nos hace llegar
hasta j) y sumamos el valor vi de Oi. Esto es: M(i,j) = M(i-1, j-pi) + vi.
Como deseamos maximizar el valor, lo propio es:
M(i,j) = max{ M(i-1,j) , M(i-1, j-pi) + vi }
Ejemplo:
n=5; C=11; pi=[1, 2, 5, 6, 7]; vi=[1, 6, 18, 22, 28]
Las filas de nuestra matriz corresponden a los objetos Oi y las columnas a la
capacidad j=1,2,,11
Aunque en principio pensamos en M5X11, nuestra matriz M considera:
- Una fila adicional i=0 (eligiendo los objetos de 1 hasta 0 !).
- Una columna adicional j=0 (considerando una capacida 0 en la mochila, no
permitiendo objetos).
- Una columna adicional terica j = -1 (para tener valores iniciales con los
cuales calcular otros).
As, dicha matriz M, a partir de (*) y (**) y siguiendo la relacin de recurrencia,
finalmente queda as:
i=0
O1
O2
O3
O4
O5

j=-1
-
-
-
-
-
-

j=0
0
0
0
0
0
0

j=1
0
1
1
1
1
1

j=2
0
1
6
6
6
6

j=3
0
1
7
7
7
7

j=4
0
1
7
7
7
7

j=5
0
1
7
18
18
18

j=6
0
1
7
19
22
22

Luego M(n,C) = M(5,11) = 40, es el valor mximo.

j=7
0
1
7
24
24
28

j=8
0
1
7
25
28
29

j=9
0
1
7
25
29
34

j=10
0
1
7
25
29
35

j=11
0
1
7
25
40
40

La propia matriz M nos indica los objetos que se toman en cuenta:


Si M(i,j) = M(i-1,j) no se incluye Oi. Pasamos a ver M(i-1,j).
Si M(i,j) = M(i-1, j-pi) + vi si se incluye Oi. Pasamos a ver M(i-1, j-pi) + vi.
Si M(i-1,j) = M(i-1, j-pi), ambas posibilidades son igualmente vlidas.
Con eso en mente podemos hacer el rastreo desde M(5,11) comenzando la
consideracin de los objetos en O5.
En el ejemplo se incluyen los objetos: O4 y O3.

Multiplicacin encadenada de matrices


Dadas las matrices Apxq y Aqxr, es sabido que el algoritmo estndar para su
multiplicacin tiene una complejidad O(pqr).
Sean las matrices A1,..,Ai,.., An, donde Ai tiene dimensin pi-1xpi.
El siguiente caso muestra que, si queremos multiplicarlas, -en trminos de
eficiencia- no es lo mismo asociar de una o de otra forma estas matrices.
En efecto, sea A1 de 10x100, A2 de 100x5 y A3 de 5x50.
Calculando A1A2A3 as:
- A1(A2A3).
Tenemos que (A2A3) se calcula en O(100550)=25000. Y la matriz con este
resultado parcial es de dimensin 100x50.
A1 es de dimensin 10x100.
Luego, la matriz final de dimensin 10x50 se calcula en O(10x100x50) =
O(50000).
Sumando ambos subclculos, tenemos en conclusin O(75000).
- (A1A2)A3.
Tenemos que (A1A2) se calcula en O(101005)=5000. Y la matriz con este
resultado parcial es de dimensin 10x5.
A3 es de dimensin 5x50.
Luego, la matriz final de dimensin 10x50 se calcula en O(10x5x50) =
O(2500).
Sumando ambos subclculos, tenemos en conclusin O(7500).
- La diferencia en el nmero de operaciones, dependiendo de cmo se
efectan las asociaciones es dramtica.
As pues necesitamos averiguar la(s) asociacin(es) (colocando parntesis
adecuadamente) que minimicen el nmero de operaciones al multiplicar A 1...An.
Resolvmoslo con programacin dinmica.
M[i,j] : Representa el mnimo nmero de operaciones al multiplicar
Ai...Aj.
Es claro que M[i,j]=0 para i=j.
El producto (Ai...Aj) puede calcularse as:
Obteniendo (Ai...Ak), luego (Ak+1...Aj), para finalmentemultiplicar dichos
subproductos (obviamente puede ser k=i, o k=i+1,, o k=j-1).
Siguiendo el principio de Bellman, supondremos que estos subproductos son
ptimos.
Luego, la relacin de recurrencia es:
M[i,j]= minik<j { M[i,k]+M[k+1,j]+pi-1pkpj }

Ejemplo: A1
A2
A3
A4
A10x20 A20x50 A50x1 A1x100
Utilizaremos un truco: iremos por diagonales
1

3
o

4
2

4
o

o
o
o

Calculemos M[1,2] = minik<j { M[i,k] + M[k+1,j] + pi-1pkpj }


= min1k<2 { M[1,k] + M[k+1,2] + p0pkp2 }
= min1k<2 { M[1,k] + M[k+1,2] + 10pk50 }
= min1k<2 { M[1,1] + M[2,2] + 10p150 } = 0 + 0 + 102050 = 10000
1

10000

Calculemos M[2,3] = minik<j { M[i,k] + M[k+1,j] + pi-1pkpj }


= min2k<3 { M[2,k] + M[k+1,3] + p1pkp3 }
= min2k<3 { M[2,k] + M[k+1,3] + 20pk1 }
= min2k<3 { M[2,2] + M[3,3] + 20501 } = 0 + 0 + 1000 = 1000
Y as sucesivamente:
1

10000

1000
0

5000
0

Calculemos M[1,3] = minik<j { M[i,k] + M[k+1,j] + pi-1pkpj }


= min1k<3 { M[1,k] + M[k+1,3] + p0pkp3 }
= min
{M[1,1] + M[2,3] + p0p1p3, M[1,2] + M[3,1] +
p0p2p3}
= min {
0
+ 1000 + 10201, 10000 + 5000 +
10501}
= min {
1200
,
15500 }
La table llena es:
1
2
3
4

La solucin es: 2200

10000

1200

2200

1000

3000

5000
0

El libro de Cormen tiene una manera interesante de dibujar


1
1
2
3
4

2
1
0

3
o

4
2
0

4
o
o

6
5
3

o
o
o

Lo hace as:

Que obviamente se llena de abajo hacia arriba (en el clsico estilo bottom-up, eficiente y
progresivo de la programacin dinmica).

La Distancia de Edicin o de Levenshtein (Vladimir Levenshtein 1965)


Se define la distancia de edicin D entre dos cadenas C1 y C2 como el mnimo
nmero de operaciones de edicin (Inserciones I, Sustituciones S y Eliminaciones
E) necesarias para transformar C1 en C2 (note que no contamos los
eMparejamientos M).
Se llama transcripcin de edicin a la lista de operaciones para transformar C 1 en
C2.
Ejemplo:
Para C1=vintner, C2=writers:

D(vintner, writers) = 5

La transcripcin de edicin es:


SIMEMEMM I
v i n t n e r
wr i
t
e r s
Supongamos que las longitudes de las cadenas C1 y C2 son C1= n, C2= m.
Si denotamos por D(i,j) a la distancia de edicin de las subcadenas C1[1..i] y
C2[1..j], es decir, la distancia entre los primeros i smbolos de C1 y los primeros j
smbolos de C2.
Es claro que:
(*) D(i,0) = i
(*) D(0,j) = j

( i Eliminaciones )
( j Inserciones )

Suponga que D(i,j) ya est calculado y considere la transcripcin de edicin de


D(i,j). Cul puede ser el ltimo smbolo de dicha transcripcin?
Si es I: Quiere decir que lo ltimo que se hace es insertar el smbolo j de C2.
Es decir, todos los smbolos de la transcripcin de edicin excepto la
ltima I- transforman C1[1..i] en C2[1..j-1] con el mnimo nmero de
operaciones que es D(i,j-1).
Es obvio que en este caso: D(i,j) = D(i,j-1) + 1.
Si es E: Quiere decir que lo ltimo que se hace es eliminar el smbolo i de C1.
Es decir, todos los smbolos de la transcripcin de edicin excepto la
ltima E- transforman C1[1..i-1] en C2[1..j] con el mnimo nmero de
operaciones que es D(i-1,j).
Es obvio que en este caso: D(i,j) = D(i-1,j) + 1.
Si es S: Quiere decir que lo ltimo que se hace es substituir el smbolo i de C1
por el smbolo j de C2.
Es decir, todos los smbolos de la transcripcin de edicin excepto la
ltima S- transforman C1[1..i-1] en C2[1..j-1] con el mnimo nmero de
operaciones que es D(i-1,j-1).
Es obvio que en este caso: D(i,j) = D(i-1,j-1) + 1.

Si es M: Quiere decir que lo ltimo que se hace es mostrar que el smbolo i de


C1 empareja con el smbolo j de C2.
Es decir, todos los smbolos de la transcripcin de edicin excepto la
ltima M- transforman C1[1..i-1] en C2[1..j-1] con el mnimo nmero de
operaciones que es D(i-1,j-1).
Es obvio que en este caso: D(i,j) = D(i-1,j-1) + 0 = D(i-1,j-1).
Podemos unir los ltimos dos casos as: D(i,j) = D(i-1,j-1) + t(i,j).
Donde: t(i,j) = 0 si el smbolo i de C1 empareja con el smbolo j de C2
t(i,j) = 1 en otro caso.
Todo el anlisis anterior muestra que el valor de D(i,j) debe ser:
D(i,j-1) + 1, D(i-1,j) + 1 o D(i-1,j-1) + t(i,j). No hay otras posibilidades.
Adems, siempre es posible transformar C1[1..i] en C[1..j] con D(i,j-1) + 1
operaciones, lo nico que hay que hacer es transformar C1[1..i] en C[1..j-1] con el
mnimo nmero de operaciones que es D(i,j-1) y luego efectuar una operacin ms
insertando el smbolo j de C.
Tambin siempre es posible transformar C1[1..i] en C2[1..j] con D(i-1,j) + 1
operaciones, lo nico que hay que hacer es transformar C1[1..i-1] en C2[1..j] con el
mnimo nmero de operaciones que es D(i-1,j) y luego efectuar una operacin ms
eliminando el smbolo i de C1.
Tambin siempre es posible transformar C1[1..i] en C2[1..j] con D(i-1,j-1) + t(i,j)
operaciones, lo nico que hay que hacer es transformar C1[1..i-1] en C2[1..j-1] con
el mnimo nmero de operaciones que es D(i-1,j-1) y luego si es necesario
efectuar una operacin ms substituyendo el smbolo i de C1 por el smbolo j de
C2, o bien mostrando el emparejamiento del smbolo i de C1 con el smbolo j de C2.
Como queremos minimizar:
D(i,j) = min{ D(i,j-1) + 1, D(i-1,j) + 1, D(i-1,j-1) + t(i,j) }
Ejemplo (tomado de la web):
C1 = [survey]
C2 = [surgery]
La matriz M, a partir de (*) y (**) y siguiendo la relacin de recurrencia, finalmente
queda as:
j=0

i=1
i=2
i=3
i=4
i=5
i=6

s
u
r
v
e
y

j=1
0
1
2
3
4
5
6

j=2
s
1
0
1
2
3
4
5

j=3
u
2
1
0
1
2
3
4

j=4
r
3
2
1
0
1
2
3

j=5
g
4
3
2
1
1
2
3

e
5
4
3
2
2
1
2

j=6
r
6
5
4
3
4
2
2

j=7
Y
7
6
5
4
4
3
2

El rastreo se hace de manera similar.


En este caso, el rastreo nos indica que operacin se hizo (y con que smbolo),
dando lugar a la transcripcin de edicin.
En el ejemplo la transcripcin de edicin es:
MMMSM IM
s u r v e
y
s u r g e r y

LIS Longest Increasing Subsequence, Subsecuencia Creciente Ms larga


Por ejemplo para la secuencia 1 4 2 5 3 7 6 8
4 3 8 es una subsecuencia, pero no es creciente.
1 4 es una subsecuencia creciente pero no es la ms larga
1 2 3 7 8 es una subsecuencia creciente ms larga. Otra es 1 2 3 6 8
Es importante notar que la subsecuencia creciente ms larga (LIS) puede empezar
en cualquier posicin y tomar sus siguientes elementos del mismo modo.
Por ejemplo, si la secuencia de entrada empieza en 10 20 ---------10 (sin contar el 20) es posiblemente el inicio de la LIS
por ej. si la secuencia fuera 10 20 11 12 1 3 14
10 20 tambin, por ej si la secuenia fuera 10 20 21 22 23
Si la secuencia de entrada empieza en 10 20 30 ---------Tambin es posible que 10 20 30 no sean parte de la LIS, por ej. si la secuencia
fuera 10 20 30 1 2 3 4 5 6
De modo que parece razonable, ir teniendo en mente todos los posibles inicios de
subsecuencias crecientes mientras recorremos la secuencia de entrada.
Si la secuencia de entrada empezara en 10 20 15 ----------10
es un posible inicio
10 20 tambin
Obviamente 10 20 15 no, pues no es creciente.
10 15 tambin es un posible inicio quizs luego vengan 16 17 18.
Note que si luego viene 16 17 18, el posible inicio 10 20 no no sirve.
Pero tanto 10 20 como 10 15 tienen longitud 2.
Y si luego vienen los nmeros 21 22 23, ellos sirven bien al posible inicio 10 20;
pero sirven igual al posible inicio 10 15. Todo lo que extiende al inicio 10 20,
extiende igual al inicio 10 15.
Al ltimo nmero de cada posible inicio lo llamaremos final end.
Dadas dos posibles secuencias iniciales de la misma longitud, privilegiamos la que
tiene menor end: todo lo que extiende la otra, extiende sta que preferimos.
Una manera de ir anotando estos posibles inicios, hasta la posicin i, es la
siguiente. Supondremos que la secuencia de entrada est en el vector A. Sea:
L(i): la longitud creciente ms larga hasta la posicin i
Caso base: L(1) = 1
Recorremos los valore A(j) de la secuencia de entrada desde la primera posicin
hasta la i-1.
Si A(j) < A(i) entonces A(i) = A(j) + 1
Pues A(i) extiende a lo logrado hasta A(j).

Visto como relacin de recurrencia, ello puede anotarse as: de


L(i) = max { L(j) / A(j) < A(i) } + 1
1<

Ejemplo:
A
L

10
1

40
2

20
2

50
3

30
3

70
4

60
4

80
5

9
1

Ntese que el L(n) no necesariamente tiene la mxima LIS.


El valor mx{---} cuando no existe, como en el ejemplo, se asume 0.
Suponga que, al codificar, guardamos el valor.
El rastreo puede hacerse yendo de derecha a izquierda buscando la primera
posicin k ms a la derecha en L que tenga un valor igual a maxLIS en L,
anotamos A(k); luego maxLIS se decrementa.
Volvemos a hacer lo mismo, desde la posicin en que estamos, hasta llegar a 0.
En el ejemplo buscamos 5, anotamos 80; buscamos 4, anotamos 60; etc.

LIS n log n
En la solucin con programacin dinmica, al asignar el valor L(i) se recorre el
vector A desde la posicin 1 hasta la posicin i-1.
Por ello, dicha solucin es de complejidad O(n2).
Hay otro modo de hacerlo. Sea
A

81

92

94

82

83

85

84

99

98

100

Anotemos todos los posibles inicios al recorrer la secuencia de entrada:


81
81
81 92
81
81 92
81 92 94
81
81 82
81 92
81 92 94
81
81 82
81 82 83
81 92 94
81
81 82
81 82 83
81 82 83 85
81
81 82
81 82 83
81 82 83 84
81 82 83 85
2
81
81 82
81 82 83
81 82 83 84

anulamos este porque 81 82 tiene un end ms pequeo

2
2 5
81 82
81 82 83
81 82 83 84
2
2 4
2 5
81 82 83
81 82 83 84
2
2 3
2 4
81 82 83
81 82 83 84
2
2 3
2 3 6
81 82 83
81 82 83 84
2
2 3
2 3 6
81 82 83 84
81 82 83 84 99
2
2 3
2 3 6
81 82 83 84
81 82 83 84 98
81 82 83 84 99
2
2 3
2 3 6
81 82 83 84
81 82 83 84 98
81 82 83 84 98 100

Ahora recorra otra vez estos conjuntos de posibles inicios, y vea el end de cada
posible inicio.
Note que estn en orden creciente. Y que al sustituir un posible inicio por otro de
igual longitud pero con un menor end, este menor final es el A(i) que hemos
pasado a considerar y como los finales estn en orden creciente podemos buscar
su posicin mediante bsqueda binaria.
Mejor an, tendremos en un vector B, slo los posibles finales.
Ejemplo:
A

81

92

94

82

83

85

84

99

98

100

Al considerar A(1)=81
B

81

Al considerar A(2)=92, se extiende


B

81

92

Al considerar A(3)=94, se extiende


B

81

92

94

Al considerar A(4)=82, buscamos, va bsquea binaria, el menor valor > 82


B

81

82

94

Al considerar A(5)=83, buscamos, va bsqueda binaria, el menor valor > 83


B

81

82

83

Etc. el vector final es:


B

84

98

100

Que coincide con los finales del ltimo conjunto de posibles inicios de arriba.
En realidad, B conicide con los finales de cada conjunto de posibles inicios
mientras se va contruyendo.
La longitud de B es la LIS buscada.
Pero los valores de B no corresponden con la LIS. Hay que hallar otro medio para
reconstruirla.
Puede hacerse con la ayuda de un tercer vector R, de la misma dimensin que A,
el cual incluir la posicin donde A(i) se inserta en B.

81

92

94

82

83

85

84

99

98

100

...

...

Al considerar A(1)=81
B

81

...

...

...

...

...

Al considerar A(2)=92, se extiende


B

81

92

..

...

...

...

...

...

...

Al considerar A(3)=94, se extiende


B

81

92

94

...

...

...

...

...

...

Al considerar A(4)=82, buscamos, va bsquea binaria, el menor valor > 82


B

81

82

94

...

...

...

...

...

Al considerar A(5)=83, buscamos, va bsqueda binaria, el menor valor > 83


B

81

82

83

...

...

...

...

Etc. los vectores finales son:


B

84

98

100

R(n) no necesariamente tiene la mxima LIS.


El rastreo puede hacerse yendo de derecha a izquierda, como antes.
R(i): la longitud ms larga de una subsecuencia creciente hasta la posicin i,
Incluyendo A(i) como valor final

También podría gustarte