Sei sulla pagina 1di 26

Programacin dinmica o a

Alberto Verdejo Dpto. de Sistemas Informticos y Computacin a o Universidad Complutense de Madrid Noviembre 2010

Alberto Verdejo (UCM)

MTP 2010-2011

1 / 51

Programacin dinmica o a

Bibliograf a

R. Neapolitan y K. Naimipour. Foundations of Algorithms using C++ pseudocode. Tercera edicin. Jones and Bartlett Publishers, 2004. o Cap tulo 3 E. Horowitz, S. Sahni y S. Rajasekaran. Computer Algorithms. Tercera edicin. Computer Science Press, 1998. o Cap tulo 5 N. Mart Oliet, Y. Ortega Malln y J. A. Verdejo Lpez. Estructuras de e o datos y mtodos algor e tmicos: ejercicios resueltos. Coleccin Prentice o Practica, Pearson/Prentice Hall, 2003. Cap tulo 13

Alberto Verdejo (UCM)

MTP 2010-2011

2 / 51

Programacin dinmica o a

Motivacin o
n r

1 1 (n1 ) + (n1) r r

si r = 0 r = n si 0 < r < n
6 4

5 3 4 2 3 1 2 0 1 0 2 1 1 1 1 0 2 1 1 1 3 2 2 2 1 0 2 1 1 1 3 2 2 2 1 0 4 3 3 3 2 1 1 1 3 2 2 2 4 3

5 4 4 4 3 3

Alberto Verdejo (UCM)

MTP 2010-2011

3 / 51

Programacin dinmica o a

Funciones con memoria


Aadir a la funcin un parmetro que es una tabla con los valores ya calculados. n o a La tabla est inicializada con valores diferentes, por ejemplo 1. a proc nm-comb (e n, r : nat, C[0..n, 0..r] de ent, s nc : nat) u si r = 0 r = n entonces nc : = 1 si no si C[n, r] = 1 entonces nc : = C[n, r] si no nm-comb (n 1, r 1, C, nc1) u nm-comb (n 1, r, C, nc2) u nc : = nc1 + nc2 ; C[n, r] : = nc fsi fsi fproc C[0..n, 0..r] : = [1] nm-comb (n, r, C, nc) u Inicializacin con tiempo en (1). Es posible? o
Alberto Verdejo (UCM) MTP 2010-2011 4 / 51

Programacin dinmica o a

Mtodo ascendente e

Comenzar por resolver todos los subproblemas ms pequeos que se puedan a n necesitar, para ir combinndolos hasta llegar a resolver el problema original. a

(0) 0 ( 1) (1 ) 1 0 (2 ) ( 2 ) ( 2) 0 1 2 ( 3) ( 3) (3 ) (3 ) 0 1 2 3 . . .. . .. . .
La base de la programacin dinmica es el uso de una tabla para ir o a almacenando los resultados correspondientes a instancias ms sencillas del a problema a resolver.

Alberto Verdejo (UCM)

MTP 2010-2011

5 / 51

Programacin dinmica o a

Esquema de programacin dinmica o a

Identicacin o
Especicacin de la funcin que representa el problema a resolver. o o Determinacin de las ecuaciones recurrentes para calcular dicha o

funcin. o Comprobacin del alto coste de clculo de dicha funcin debido a o a o la repeticin de subproblemas a resolver. o Construccin o
Sustitucin de la funcin por una tabla. o o Inicializacin de la tabla segn los casos base de la denicin o u o

recursiva de la funcin. o Sustitucin, en las ecuaciones, de las llamadas recursivas por o consultas a la tabla. Planicacin del orden de llenado de la tabla, de forma que se o respeten las necesidades de cada entrada de la tabla. Posible optimizacin en espacio. o

Alberto Verdejo (UCM)

MTP 2010-2011

6 / 51

Programacin dinmica o a

Nmeros combinatorios u

0 1 2 . . . n

0 1 1 1 . . . 1

1 0 1 2 . . . n

2 0 0 1 . . . (n ) 2

... ... ... ... .. . ...

r 0 0 0 . . . (n) r

fun pascal (n, r : nat ) dev c : nat var C[0..n, 0..r] de nat C[0, 0] : = 1 C[0, 1..r] : = [0] para i = 1 hasta n hacer C[i, 0] : = 1 para j = 1 hasta r hacer C[i, j] : = C[i 1, j 1] + C[i 1, j] fpara fpara c : = C[n, r] un

Alberto Verdejo (UCM)

MTP 2010-2011

7 / 51

Programacin dinmica o a

Nmeros combinatorios, mejorar espacio adicional u


Dejando aparte los casos bsicos, para calcular cada entrada (i, j) en la tabla se a necesitan las entradas (i 1, j 1) e (i 1, j) de la la anterior, por lo que el espacio adicional se puede reducir a un vector que se rellena de derecha a izquierda.
i1 i j

fun pascal2(n, r : nat ) dev c : nat var C[0..r] de nat C[0] : = 1 ; C[1..r] : = [0] para i = 1 hasta n hacer para j = r hasta 1 paso 1 hacer C [ j ] : = C [ j ] + C [ j 1] fpara fpara c : = C[ r] un
Alberto Verdejo (UCM) MTP 2010-2011 8 / 51

Programacin dinmica o a

El campeonato mundial
Competicin entre dos equipos, A y B, en la que el ganador es el primer o

equipo que consiga n victorias. No hay empates, los resultados de todos los partidos son independientes, y para cualquier partido dado hay una probabilidad constante p de que lo gane el equipo A (y por tanto una probabilidad constante q = 1 p de que lo gane el equipo B). Queremos calcular la probabilidad que tiene el equipo A de ganar la competicin, antes del primer partido. o Denimos la funcin o P(i, j) = probabilidad de que A gane la competicin si a A le faltan o i victorias para ganar y a B le faltan j victorias.

El valor que nos interesa calcular es P(n, n). Denicin recursiva: o P(i, j) = pP(i 1, j) + qP(i, j 1) Los casos bsicos son a P(0, j) P(i, 0)
Alberto Verdejo (UCM)

= =

1 0

1jn 1in
9 / 51

MTP 2010-2011

Programacin dinmica o a

fun competicin (n : nat+ , p : real ) dev probabilidad-A : real o var P[0..n, 0..n] de real P[0, 1..n] : = [1] P[1..n, 0] : = [0] para i = 1 hasta n hacer para j = 1 hasta n hacer P[i, j] : = p P[i 1, j] + (1 p) P[i, j 1] fpara fpara probabilidad-A : = P[n, n] un

{ ( n2 ) }

Alberto Verdejo (UCM)

MTP 2010-2011

10 / 51

Programacin dinmica o a

Podemos reducir el espacio adicional utilizado?


i1 i j

Rellenar de izquierda a derecha. fun competicin2 (n : nat+ , p : real ) dev probabilidad-A : real o var P[0..n] de real P [ 0] : = 0 P[1..n] : = [1] para i = 1 hasta n hacer para j = 1 hasta n hacer P [ j ] : = p P [ j ] + (1 p) P [ j 1] fpara fpara probabilidad-A : = P[n] un

{ (n ) }

Alberto Verdejo (UCM)

MTP 2010-2011

11 / 51

Programacin dinmica o a

El campeonato mundial, generalizacin o


Qu ocurre cuando existe una probabilidad p de que A gane un partido, q de e que lo pierda, y r (con p + q + r = 1) de que haya empate? Un empate no supone una victoria para ningn equipo y siguen siendo u necesarias n victorias para ganar la competicin. o Hay que modicar la frmula anterior como sigue: o P(i, j) = pP(i 1, j) + qP(i, j 1) + rP(i, j) donde el tercer caso indica que al haber empatado, tanto a A como a B les faltan las mismas victorias que antes de jugar ese partido. Podemos despejar P(i, j) obteniendo P(i, j) = p q P(i 1, j) + P(i, j 1), 1r 1r

que se puede resolver exactamente de la misma forma que en el caso anterior.

Alberto Verdejo (UCM)

MTP 2010-2011

12 / 51

Programacin dinmica o a

Problema del cambio

Se dispone de un conjunto nito M = {m1 , m2 , . . . , mn } de tipos de


monedas, donde cada mi es un nmero natural. u

Existe una cantidad ilimitada de monedas de cada valor. Se quiere pagar una cantidad C > 0 utilizando el menor nmero posible de u
monedas. monedas(n, C) = nmero m u nimo de monedas para pagar la cantidad C considerando los tipos de monedas del 1 al n.

u Se cumple el principio de optimalidad de Bellman segn el cual para conseguir una solucin ptima basta considerar subsoluciones ptimas. o o o

Alberto Verdejo (UCM)

MTP 2010-2011

13 / 51

Programacin dinmica o a

Denicin recursiva: o monedas(i, j)

monedas(i 1, j) mn{monedas(i 1, j), monedas(i, j mi ) + 1}

si mi > j si mi j

donde 1 i n y 1 j C. Casos bsicos: a monedas(i, 0) monedas(0, j)


monedas 0 1 i1 i n 0

= =

0 +
j

0in 1jC
C

j mi

Alberto Verdejo (UCM)

MTP 2010-2011

14 / 51

Programacin dinmica o a

fun devolver-cambio1 (M[1..n] de nat+ , C : nat ) dev numero : nat { numero es la cantidad de monedas en la solucin ptima } o o { numero es + cuando no existe solucin } o var monedas[0..n, 0..C] de nat { inicializacin } o monedas[0, 1..C] : = [+ ] monedas[0..n, 0] : = [0] { rellenar la matriz } para i = 1 hasta n hacer para j = 1 hasta C hacer si M[i] > j entonces monedas[i, j] : = monedas[i 1, j] si no monedas[i, j] : = mn(monedas[i 1, j], monedas[i, j M[i]] + 1) fsi fpara fpara numero : = monedas[n, C] un Coste: (nC) tanto en tiempo como en espacio adicional.

Alberto Verdejo (UCM)

MTP 2010-2011

15 / 51

Programacin dinmica o a

Problema del cambio: Ejemplo

C = 8, n = 3, m1 = 1, m2 = 4 y m3 = 6. 0 0 0 0 0 1 + 1 1 1 2 + 2 2 2 3 + 3 3 3 4 + 4 1 1 5 + 5 2 2 6 + 6 3 1 7 + 7 4 2 8 + 8 2 2

0 1 2 3

Alberto Verdejo (UCM)

MTP 2010-2011

16 / 51

Programacin dinmica o a

Problema del cambio: clculo de la solucin ptima a o o


Adems del nmero total de monedas en la solucin optima, queremos conocer a u o tambin dicha solucin, es decir, cuntas monedas de cada tipo la forman. e o a monedas(i, j) = mn{monedas(i 1, j), monedas(i, j mi ) + 1}
no cogemos moneda mi s cogemos moneda mi

Por tanto, sabemos que si monedas(i, j) = monedas(i 1, j) es porque podemos no coger ninguna moneda de tipo i para pagar la cantidad j, mientras que si monedas(i, j) = monedas(i 1, j) debemos coger al menos una moneda de tipo i para pagar la cantidad j.

Alberto Verdejo (UCM)

MTP 2010-2011

17 / 51

Programacin dinmica o a

{ monedas[n, C] = + } fun calcular-monedas1 (M[1..n] de nat+ , monedas[0..n, 0..C] de nat ) dev cu ntas[1..n] de nat a { cu ntas[i] es el nmero de monedas de tipo i cogidas } a u cu ntas[1..n] : = [0] a i := n ; j := C mientras j > 0 hacer { no hemos pagado todo } si M[i] j monedas[i, j] = monedas[i 1, j] entonces { tomamos una moneda de tipo i } cu ntas[i] : = cu ntas[i] + 1 a a j : = j M[ i ] si no { no tomamos ms monedas de tipo i } a i := i 1 fsi fmientras un

{ (C ) }

Alberto Verdejo (UCM)

MTP 2010-2011

18 / 51

Programacin dinmica o a

Problema del cambio: mejorar espacio adicional


i1 i j

fun devolver-cambio2 (M[1..n] de nat+ , C : nat ) dev numero : nat var monedas[0..C] de nat { inicializacin } o monedas[0] : = 0 monedas[1..C] : = [+ ] { hacer las actualizaciones } para i = 1 hasta n hacer para j = M[i] hasta C hacer monedas[j] : = mn(monedas[j], monedas[j M[i]] + 1) fpara fpara numero : = monedas[C] un Coste: (nC) en tiempo y (C) en espacio adicional.
Alberto Verdejo (UCM) MTP 2010-2011 19 / 51

Programacin dinmica o a

Podemos optimizar en espacio y seguir calculando la solucin ptima? o o La ultima la contiene la informacin sobre el nmero de monedas m o u nimo para cada cantidad, con el sistema monetario completo. Si monedas(n, j) = monedas(n, j mi ) + 1 para algn j y algn i, sabemos que podemos coger una moneda de tipo i para u u conseguir una solucin ptima para pagar j. o o Adems, como el nmero de monedas de cada tipo es ilimitado, el sistema a u monetario no cambia y se puede iterar el proceso para j mi haciendo comparaciones de nuevo en la ultima la, es decir, el vector. Para implementar este proceso, al principio j vale C e i vale n; la cantidad j decrece tal y como se van cogiendo monedas y, cuando la ecuacin anterior no o es cierta y por tanto no se puede coger ninguna moneda ms de tipo i, se a decrementa i pasando a considerar el tipo de moneda anterior i 1.

Alberto Verdejo (UCM)

MTP 2010-2011

20 / 51

Programacin dinmica o a

{ monedas[C] = + } fun calcular-monedas2 (M[1..n] de nat+ , monedas[0..C] de nat ) { (C ) } dev cu ntas[1..n] de nat a { cu ntas[i] es el nmero de monedas de tipo i cogidas } a u cu ntas[1..n] : = [0] a i := n ; j := C mientras j > 0 hacer { no hemos pagado todo } si M[i] j c monedas[j] = monedas[j M[i]] + 1 entonces { tomamos una moneda de tipo i } cu ntas[i] : = cu ntas[i] + 1 a a j : = j M[i] si no { no tomamos ms monedas de tipo i } a i := i 1 fsi fmientras un

Alberto Verdejo (UCM)

MTP 2010-2011

21 / 51

Programacin dinmica o a

Problema de la mochila (versin entera) o

Cuando Al -Bab consigue por n entrar en la Cueva de los Cuarenta a Ladrones encuentra all gran cantidad de objetos muy valiosos. A pesar de su pobreza, Al -Bab conoce muy bien el peso y valor de a cada uno de los objetos en la cueva. Debido a los peligros que tiene que afrontar en su camino de vuelta, solo puede llevar consigo aquellas riquezas que quepan en su pequea n mochila, que soporta un peso mximo conocido. a Suponiendo que los objetos no se pueden fraccionar y que los pesos son nmeros naturales positivos, determinar qu objetos debe elegir u e Al -Bab para maximizar el valor total de lo que pueda llevarse en su a mochila.

Alberto Verdejo (UCM)

MTP 2010-2011

22 / 51

Programacin dinmica o a

En la cueva hay n objetos, cada uno con un peso (natural) pi > 0 y un valor (real) vi > 0 para todo i entre 1 y n. La mochila soporta un peso total (natural) mximo M > 0. a El problema consiste en maximizar

xi vi
i=1

con la restriccin o

xi pi M,
i=1

donde xi {0, 1} indica si hemos cogido (1) o no (0) el objeto i.

Alberto Verdejo (UCM)

MTP 2010-2011

23 / 51

Programacin dinmica o a

Denimos una funcin o mochila(i, j) = mximo valor que podemos poner en la mochila de a peso mximo j considerando los objetos del 1 al i. a

Denicin recursiva o mochila(i, j)

mochila(i 1, j) m x{mochila(i 1, j), mochila(i 1, j pi ) + vi } a

si pi > j si pi j

con 1 i n y 1 j M. Los casos bsicos son: a mochila(0, j) mochila(i, 0) Problema inicial: mochila(n, M).

= =

0 0

0jM 0 i n.

Alberto Verdejo (UCM)

MTP 2010-2011

24 / 51

Programacin dinmica o a

mochila 0 1 i1 i n

j pi

Recorrer la matriz por las de arriba abajo y cada la de izquierda a derecha. Si solo quisiramos el valor mximo alcanzable, podr e a amos optimizar el espacio adicional utilizando solo un vector que recorrer amos de derecha a izquierda. Si queremos devolver los objetos que forman parte de la solucin optima no o interesa optimizar, porque en ese caso las comparaciones que hacemos para llenar una posicin siempre se reeren a posiciones de la la anterior: o mochila(i, j) = m x{mochila(i 1, j), mochila(i 1, j pi ) + vi } a
no cogemos el objeto i s cogemos el objeto i

Alberto Verdejo (UCM)

MTP 2010-2011

25 / 51

Programacin dinmica o a

fun mochila-pd (P[1..n] de nat+ , V [1..n] de real + , M : nat+ ) dev valor : real, cu les[1..n] de 0..1 a { cu les[i] indica si hemos cogido o no el objeto i } a var mochila[0..n, 0..M] de real { inicializacin } o mochila[0..n, 0] : = [0] mochila[0, 1..M] : = [0] { rellenar la matriz } para i = 1 hasta n hacer para j = 1 hasta M hacer si P[i] > j entonces mochila[i, j] : = mochila[i 1, j] si no mochila[i, j] : = mx(mochila[i 1, j], mochila[i 1, j P[i]] + V [i]) a fsi fpara fpara valor : = mochila[n, M]

Alberto Verdejo (UCM)

MTP 2010-2011

26 / 51

Programacin dinmica o a

{ clculo de los objetos } a resto : = M para i = n hasta 1 paso 1 hacer si mochila[i, resto] = mochila[i 1, resto] entonces cu les[i] : = 0 a si no { s coger objeto i } cu les[i] : = 1 ; resto : = resto P[i] a fsi fpara un
Coste: (nM) tanto en tiempo como en espacio adicional.

{ no coger objeto i }

Alberto Verdejo (UCM)

MTP 2010-2011

27 / 51

Programacin dinmica o a

Formas de poner sellos

El pa de Fanfanisn emite n sellos diferentes de valores naturales s a positivos s1 , s2 , . . . , sn . Se quiere enviar una carta y se sabe que la correspondiente tarifa postal es T. De cuntas formas diferentes se puede franquear exactamente la a carta, si el orden de los sellos no importa?

formas(n, T )

nmero de formas de franquear T con n tipos de sellos. u

Alberto Verdejo (UCM)

MTP 2010-2011

28 / 51

Programacin dinmica o a

formas(i, j)

formas(i 1, j) formas(i 1, j) + formas(i, j si )

si si > j si si j

con 1 i n y 1 j T. formas(0, j) = 0 formas(i, 0) = 1 1jT 0in

Alberto Verdejo (UCM)

MTP 2010-2011

29 / 51

Programacin dinmica o a

fun sellos(S[1..n] de nat+ , T : nat+ ) dev num-formas : nat var formas[0..T ] de nat { inicializacin } o formas[0] : = 1 formas[1..T ] : = [0] { actualizaciones del vector } para i = 1 hasta n hacer para j = S[i] hasta T hacer formas[j] : = formas[j] + formas[j S[i]] fpara fpara num-formas : = formas[T ] un Coste: (nT ) en tiempo y (T ) en espacio adicional.

Alberto Verdejo (UCM)

MTP 2010-2011

30 / 51

Programacin dinmica o a

Reparto del bot n

El Maqui y el Popeye acaban de desvalijar la reserva nacional de oro. Los lingotes estn empaquetados en n cajas de diferentes pesos a naturales positivos pi para i entre 1 y n. Como no tienen tiempo de desempaquetarlos para dividir el bot n, deciden utilizar los pesos de cada una de las cajas para distribuir el bot a medias. n Al cabo de un buen rato todav no han conseguido repartirse el bot a n, por lo cual acuden al Teclas para saber si el bot se puede dividir en n dos partes iguales sin desempaquetar las cajas con los lingotes.

Alberto Verdejo (UCM)

MTP 2010-2011

31 / 51

Programacin dinmica o a

Considerando P = n 1 pi , el problema es equivalente a comprobar si es i= posible, sumando algunos de los pesos, obtener P/2.

se-puede(i, j)

booleano que indica si es posible sumar la cantidad j eligiendo algunas de las i primeras cajas.

se-puede(i, j)

se-puede(i 1, j) se-puede(i 1, j) se-puede(i 1, j pi )

si pi > j si pi j

con 1 i n y 1 j P/2 se-puede(0, j) se-puede(i, 0)

= =

falso cierto

1 j P/2 0 i n.

Alberto Verdejo (UCM)

MTP 2010-2011

32 / 51

Programacin dinmica o a

Utilizamos una matriz se-puede[0..n, 0..P/2] para calcular los valores de la recurrencia. Si solo queremos saber si se puede o no sumar la cantidad P/2, y no los objetos necesarios para sumar tal cantidad, podemos optimizar el espacio adicional utilizando solo un vector, se-puede[0..P/2]. Ya que las dos posiciones necesarias para calcular se-puede(i, j) se encuentran en la la anterior,

i1 i j

el vector tiene que recorrerse de derecha a izquierda, para no perder valores de la la anterior que se necesitan despus. e

Alberto Verdejo (UCM)

MTP 2010-2011

33 / 51

Programacin dinmica o a

{ P = P/2 } fun repartir-botn-par-pd (peso[1..n] de nat+ , P : nat+ ) dev respuesta : bool var se-puede[0..P ] de bool { inicializacin } o se-puede[0] : = cierto se-puede[1..P ] : = [falso] { actualizaciones del vector } para i = 1 hasta n hacer para j = P hasta peso[i] paso 1 hacer se-puede[j] : = se-puede[j] se-puede[j peso[i]] fpara fpara respuesta : = se-puede[P ] un { P = n=1 peso[i] } i fun repartir-botn-pd (peso[1..n] de nat+ , P : nat+ ) dev respuesta : bool si impar(P) entonces respuesta : = falso si no respuesta : = repartir-botn-par-pd (peso, P div 2) fsi un
Alberto Verdejo (UCM) MTP 2010-2011 34 / 51

Programacin dinmica o a

Caminos m nimos: algoritmo de Floyd


Dado un grafo dirigido cuyas aristas estn valoradas con nmeros positivos, a u calcular el coste (del camino) m nimo entre cada par de vrtices del grafo. e El grafo viene dado por su matriz de adyacencia G[1..n, 1..n] si i = j 0 coste si hay arista de i a j G[i, j] = + si no hay arista de i a j Ck (i, j) = coste m nimo para ir de i a j pudiendo utilizar como vrtices intermedios aquellos entre 1 y k. e

Denicin de la funcin o o

La recurrencia, con 1 k, i, j n, es Ck (i, j) = mn{Ck1 (i, j), Ck1 (i, k) + Ck1 (k, j)}. El caso bsico se presenta cuando k = 0: a C0 (i, j) = G[i, j] 0 si i = j si i = j

El coste m nimo entre i y j ser Cn (i, j). a


Alberto Verdejo (UCM) MTP 2010-2011 35 / 51

Programacin dinmica o a

En principio necesitamos n + 1 matrices n n, con un espacio adicional en (n3 ). Pero se puede mejorar. Para calcular la matriz Ck solo necesitamos la matriz Ck1 y las actualizaciones se pueden ir realizando sobre la misma matriz.
k k j j

Ck 1

Ck

Pero la la k y la columna k no cambian cuando actualizamos de Ck1 a Ck . Para la la k tenemos Ck (k, j) = mn{Ck1 (k, j), Ck1 (k, k) + Ck1 (k, j)} = Ck1 (k, j), ya que Ck1 (k, k) = 0. Y de igual forma Ck (i, k) = Ck1 (i, k) para la columna k. Solo utilizamos una matriz C[1..n, 1..n], en la que nalmente se devuelve la solucin, de modo que el coste en espacio adicional est en (1). o a
Alberto Verdejo (UCM) MTP 2010-2011 36 / 51

Programacin dinmica o a

fun Floyd(G : grafo-val[ n] ) dev C[1..n, 1..n] de real , camino[1..n, 1..n] de 0..n { inicializacin } o C : = G ; camino[1..n, 1..n] : = [0] para i = 1 hasta n hacer C[i, i] : = 0 fpara { actualizaciones de la matriz } para k = 1 hasta n hacer para i = 1 hasta n hacer para j = 1 hasta n hacer temp : = C[i, k] + C[k, j] si temp < C[i, j] entonces C[i, j] : = temp camino[i, j] : = k fsi fpara fpara fpara un Coste: (n3 ) en tiempo y (1) en espacio adicional.

Alberto Verdejo (UCM)

MTP 2010-2011

37 / 51

Programacin dinmica o a

proc imprimir-caminos (e C[1..n, 1..n] de real , e camino[1..n, 1..n] de 0..n) para i = 1 hasta n hacer para j = 1 hasta n hacer si C[i, j] < + entonces imprimir(camino de, i, a, j) imprimir(i) ; imp-camino-int (i, j, camino) ; imprimir (j) fsi fpara fpara fproc proc imp-camino-int (e i, j : 1..n, e camino[1..n, 1..n] de 0..n) k : = camino[i, j] si k > 0 entonces { hay un camino no directo } imp-camino-int (i, k, camino) ; imprimir(k) ; imp-camino-int (k, j, camino) fsi fproc

Alberto Verdejo (UCM)

MTP 2010-2011

38 / 51

Programacin dinmica o a

Cadena de productos de matrices


El producto de una matriz Apq y una matriz Bqr es una matriz Cpr cuyos elementos son
q

cij =

aik bkj .
k=1

Se necesitan pqr multiplicaciones entre escalares para calcular C. Para multiplicar una secuencia de matrices M1 M2 Mn (Mi tiene dimensiones di1 di ) el orden de las matrices no se puede alterar pero s el de los productos a realizar, ya que la multiplicacin de matrices es asociativa. o Cul es la mejor forma de insertar parntesis en la secuencia de matrices de a e forma que el nmero total de multiplicaciones entre escalares sea m u nimo? Ejemplo: A135 , B589 , C893 , D334

((A B) C) D
5785 3471 1326
Alberto Verdejo (UCM)

10582

(A (B C ) ) D
1335 195 1326

2856

MTP 2010-2011

39 / 51

Programacin dinmica o a

( M1 . . . Mk ) ( Mk + 1 . . . Mn )
d0 dk dk dn

Utilizamos la funcin o matrices(i, j) = nmero m u nimo de multiplicaciones escalares para realizar el producto matricial Mi Mj .

La recurrencia solo tiene sentido cuando i j. El caso recursivo, i < j, se dene de la siguiente manera: matrices(i, j)

ik j1

mn {matrices(i, k) + matrices(k + 1, j) + di1 dk dj }.

El caso bsico se presenta cuando solo tenemos una matriz, esto es, i = j: a matrices(i, i) = 0. Problema inicial: matrices(1, n).

Alberto Verdejo (UCM)

MTP 2010-2011

40 / 51

Programacin dinmica o a

Utilizaremos una tabla matrices[1..n, 1..n], de la cual solo necesitaremos la mitad superior por encima de la diagonal principal.
matrices i j

... . . .

Rellenar la matriz recorrindola por diagonales. e

Alberto Verdejo (UCM)

MTP 2010-2011

41 / 51

Programacin dinmica o a

matrices 1 2 3 4 5 6 7 8

d = 7 (n 7 = 1 elemento) . ..

d=2 d = 1 (n 1 = 7 elementos)

Las diagonales se numeran desde d = 1 hasta d = n 1 en el orden en el que tienen que recorrerse. Cada diagonal tiene n d elementos que numeraremos del i = 1 al i = n d. As este ndice nos sirve directamente para conocer la la en la que se encuentra el elemento por el que vamos. La columna podemos calcularla mediante j = i + d.

Alberto Verdejo (UCM)

MTP 2010-2011

42 / 51

Programacin dinmica o a

fun multiplica-matrices (D[0..n] de nat+ ) dev num-mn : nat, P[1..n, 1..n] de 0..n var matrices[1..n, 1..n] de nat para i = 1 hasta n hacer { inicializacin, diagonal principal } o matrices[i, i] : = 0 ; P[i, i] : = 0 fpara { recorrido por diagonales } para d = 1 hasta n 1 hacer { recorre diagonales } para i = 1 hasta n d hacer { recorre elementos dentro de la diagonal } j := i + d { calcular m nimo } matrices[i, j] : = + para k = i hasta j 1 hacer temp : = matrices[i, k] + matrices[k + 1, j] + D[i 1] D[k] D[j] si temp < matrices[i, j] entonces matrices[i, j] : = temp ; P[i, j] : = k fsi fpara fpara Coste: en tiempo (n3 ) fpara en espacio (n2 ) num-mn : = matrices[1, n] un
Alberto Verdejo (UCM) MTP 2010-2011 43 / 51

Programacin dinmica o a

{1ijn} proc escribir-parn (e i, j : nat, e P[1..n, 1..n] de nat ) e si i = j entonces imprimir (Mi ) si no k : = P[i, j] si k > i entonces imprimir (() ; escribir-parn (i, k, P) ; imprimir ()) e si no imprimir (Mi ) fsi imprimir (*) si k + 1 < j entonces imprimir(() ; escribir-parn (k + 1, j, P) ; imprimir ()) e si no imprimir (Mj ) fsi fsi fproc

Alberto Verdejo (UCM)

MTP 2010-2011

44 / 51

Programacin dinmica o a

Arboles binarios de bsqueda ptimos u o


Sean c1 < c2 < < cn un conjunto de claves distintas ordenadas, y sea pi la probabilidad con que se pide buscar la clave ci y su informacin asociada. o Queremos encontrar un arbol de bsqueda que minimice el nmero medio de u u comparaciones necesarias para realizar una bsqueda, suponiendo que u a n 1 pi = 1, es decir, que todas las peticiones se reeren a claves que estn en i= el rbol. a Ejemplo: c1 = David, 3 p1 = 8 , Isabel David Rafa Teresa
7 4

c2 = Isabel, p2 = 3 , 8

c3 = Rafa, 1 p3 = 8 ,

c4 = Teresa p4 = 1 8 Rafa

Isabel David
18 8

Teresa

Alberto Verdejo (UCM)

MTP 2010-2011

45 / 51

Programacin dinmica o a

ck

c1 , . . . , ck1

ck+1 , . . . , cn

Consideremos un arbol de bsqueda a para las claves {c1 , . . . , cn } en el que la u clave ck est en la ra a z. Utilizamos la funcin o compa (1, n) = nmero medio de comparaciones para realizar una bsqueda u u en a en las condiciones del enunciado.

Alberto Verdejo (UCM)

MTP 2010-2011

46 / 51

Programacin dinmica o a

El nmero medio de comparaciones viene dado por: u

compa (1, n)

= = = = =

pl nivela (cl )
l=1 k1

pk + pk + pk +
n

pl nivela (cl ) +
l=k +1

pl nivela (cl )

l=1 k1

pl (nivelhi(a) (cl ) + 1) + pl +

l=k +1

pl (nivelhd(a) (cl ) + 1)

l=1 k1

l=k +1

k1

pl +

pl nivelhi(a) (cl ) +

l=k +1

pl nivelhd(a) (cl )

l=1

l=1

l=1

pl + comphi(a) (1, k 1) + comphd(a) (k + 1, n)

Alberto Verdejo (UCM)

MTP 2010-2011

47 / 51

Programacin dinmica o a

comp(i, j)

nmero medio m u nimo de comparaciones en un rbol a de bsqueda conteniendo las claves ci+1 , . . . , cj . u

El caso que nos interesa, para un arbol con n claves, ser comp(0, n): a comp (0, n)

l=1

n pl + 1mn{comp(0, k 1) + comp(k, n)}. k

En el caso general, la recurrencia se dene para 0 i < j n:


j

comp(i, j)

l=i+1

pl + mn {comp(i, k 1) + comp(k, j)}.


i+1k j

El caso bsico es comp(i, i) = 0, donde 0 i n, que corresponde al rbol a a vac o.

Alberto Verdejo (UCM)

MTP 2010-2011

48 / 51

Programacin dinmica o a

Recorrido por diagonales. Matriz adicional prob[0..n, 0..n]. Con la denicin o


j

prob[i, j] =

l=i+1

pl ,

se puede calcular la matriz mediante la frmula o prob[i, j] = prob[i, j 1] + pj , teniendo como caso bsico prob[i, i] = 0. a Guardamos en una tercera matriz raz[0..n, 0..n] las decisiones sobre las ra ces de los rboles ptimos a o raz[i, j] ser la ra del rbol de bsqueda ptimo con las claves ci+1 , . . . , cj . a z a u o

Alberto Verdejo (UCM)

MTP 2010-2011

49 / 51

Programacin dinmica o a

{ C [ 1 ] < < C [ n ] i : 1 i n : 0 P [ i] 1 } fun rbol-bsqueda-ptimo (C[1..n] de clave, P[1..n] de real ) a u o dev num-comp : real, raz[0..n, 0..n] de 0..n var comp[0..n, 0..n] de real , prob[0..n, 0..n] de real para i = 0 hasta n hacer comp[i, i] : = 0 ; prob[i, i] : = 0 ; raz[i, i] : = 0 fpara para d = 1 hasta n hacer { recorre diagonales } para i = 0 hasta n d hacer { recorre elementos dentro de la diagonal } j := i + d prob[i, j] : = prob [i, j 1] + P[j] { calcular m nimo } mnimo : = + para k = i + 1 hasta j hacer temp : = comp[i, k 1] + comp[k, j] si temp < mnimo entonces mnimo : = temp ; raz [i, j] : = k fsi fpara comp[i, j] : = mnimo + prob[i, j] fpara fpara Coste: en tiempo (n3 ) num-comp : = comp[0, n] en espacio (n2 ) un

Alberto Verdejo (UCM)

MTP 2010-2011

50 / 51

Programacin dinmica o a

{ C [ 1] < < C [ n ] i j } fun construir-rbol (C[1..n] de clave, raz[0..n, 0..n] de 0..n, i, j : 0..n) a dev arbol : rbol-bb[clave] a var iz, dr : rbol-bb[clave] a si raz[i, j] = 0 entonces arbol : = abb-vaco () si no k : = raz[i, j] iz : = construir-rbol (C, raz, i, k 1) a dr : = construir-rbol (C, raz, k, j) a arbol : = plantar (iz, C[k], dr) fsi un
Llamada inicial construir-rbol (C, raz, 0, n). a Coste en tiempo: (n)

Alberto Verdejo (UCM)

MTP 2010-2011

51 / 51

Potrebbero piacerti anche