Está en la página 1de 5

PROGRAMACION DINAMICA

PROGRAMACIN DINMICA

5.1 INTRODUCCIN
Existe una serie de problemas cuyas soluciones pueden ser expresadas recursivamente en trminos matemticos, y
posiblemente la manera ms natural de resolverlos es mediante un algoritmo recursivo. Sin embargo, el tiempo de
ejecucin de la solucin recursiva, normalmente de orden exponencial y por tanto impracticable, puede mejorarse
substancialmente mediante la Programacin Dinmica.
En el diseo Divide y Vencers del captulo 3 veamos cmo para resolver un problema lo dividamos en subproblemas
independientes, los cuales se resolvan de manera recursiva para combinar finalmente las soluciones y as resolver el
problema original. El inconveniente se presenta cuando los subproblemas obtenidos no son independientes sino que existe
solapamiento entre ellos; entonces es cuando una solucin recursiva no resulta eficiente por la repeticin de clculos que
conlleva. En estos casos es cuando la Programacin Dinmica nos puede ofrecer una solucin aceptable. La eficiencia de
esta tcnica consiste en resolver los subproblemas una sola vez, guardando sus soluciones en una tabla para su futura
utilizacin.
La Programacin Dinmica no slo tiene sentido aplicarla por razones de eficiencia, sino porque adems presenta un
mtodo capaz de resolver de manera eficiente problemas cuya solucin ha sido abordada por otras tcnicas y ha fracasado.
Donde tiene mayor aplicacin la Programacin Dinmica es en la resolucin de problemas de optimizacin. En este tipo de
problemas se pueden presentar distintas soluciones, cada una con un valor, y lo que se desea es encontrar la solucin de
valor ptimo (mximo o mnimo).
La solucin de problemas mediante esta tcnica se basa en el llamado principio de ptimo enunciado por Bellman en 1957 y
que dice: En una secuencia de decisiones ptima toda subsecuencia ha de ser tambin ptima.
Hemos de observar que aunque este principio parece evidente no siempre es aplicable y por tanto es necesario verificar que
se cumple para el problema en cuestin. Un ejemplo claro para el que no se verifica este principio aparece al tratar de
encontrar el camino de coste mximo entre dos vrtices de un grafo ponderado.
Para que un problema pueda ser abordado por esta tcnica ha de cumplir dos condiciones:
La solucin al problema ha de ser alcanzada a travs de una secuencia de decisiones, una en cada etapa.
Dicha secuencia de decisiones ha de cumplir el principio de ptimo.
En grandes lneas, el diseo de un algoritmo de Programacin Dinmica consta de los siguientes pasos:
1. Planteamiento de la solucin como una sucesin de decisiones y verificacin de que sta cumple el principio de ptimo.
2. Definicin recursiva de la solucin.
3. Clculo del valor de la solucin ptima mediante una tabla en donde se almacenan soluciones a problemas parciales para
reutilizar los clculos.
4. Construccin de la solucin ptima haciendo uso de la informacin contenida en la tabla anterior.
5.2 CLCULO DE LOS NMEROS DE FIBONACCI
Antes de abordar problemas ms complejos veamos un primer ejemplo en el cual va a quedar reflejada toda esta problemtica.
Se trata del clculo de los trminos de la sucesin de nmeros de Fibonacci. Dicha sucesin podemos expresarla recursivamente
en trminos matemticos de la siguiente manera:
Fib(n) =
1 si n = 0,1
Fib(n1)+ Fib(n 2) si n >1
Por tanto, la forma ms natural de calcular los trminos de esa sucesin es mediante un programa recursivo:
PROCEDURE FibRec(n:CARDINAL):CARDINAL;
BEGIN
IF n<=1 THEN RETURN 1
ELSE
RETURN FibRec(n-1) + FibRec(n-2)
END
END FibRec; El inconveniente
Para este problema es posible disear un algoritmo que en tiempo lineal lo resuelva mediante la construccin de una tabla que permita ir almacenando los clculos realizados hasta el
momento para poder reutilizarlos:
Fib(0) Fib(1) Fib(2) ... Fib(n)
El algoritmo iterativo que calcula la sucesin de Fibonacci utilizando tal tabla es:
TYPE TABLA = ARRAY [0..n] OF CARDINAL
PROCEDURE FibIter(VAR T:TABLA;n:CARDINAL):CARDINAL;
VAR i:CARDINAL;
BEGIN
IF n<=1 THEN RETURN 1
ELSE
T[0]:=1;
T[1]:=1:
FOR i:=2 TO n DO
T[i]:=T[i-1]+T[i-2]
END;
RETURN T[n]
END
END FibIter;
Existe an otra mejora a este algoritmo, que aparece al fijarnos que nicamente son necesarios los dos ltimos valores calculados para determinar cada trmino, lo que permite eliminar
la tabla entera y quedarnos solamente con dos variables para almacenar los dos ltimos trminos:
PROCEDURE FibIter2(n: CARDINAL):CARDINAL;
VAR i,suma,x,y:CARDINAL; (* x e y son los 2 ultimos terminos *)
BEGIN
IF n<=1 THEN RETURN 1
ELSE
x:=1; y:=1;
FOR i:=2 TO n DO
suma:=x+y; y:=x; x:=suma;
END;
RETURN suma
END
END FibIter2;
Aunque esta funcin sea de la misma complejidad temporal que la anterior
(lineal), consigue una complejidad espacial menor, pues de ser de orden O(n) pasa a ser O(1) ya que hemos eliminado la tabla.
El uso de estructuras (vectores o tablas) para eliminar la repeticin de los clculos, pieza clave de los algoritmos de Programacin Dinmica, hace que en
este captulo nos fijemos no slo en la complejidad temporal de los algoritmos estudiados, sino tambin en su complejidad espacial.
En general, los algoritmos obtenidos mediante la aplicacin de esta tcnica consiguen tener complejidades (espacio y tiempo) bastante razonables,
pero debemos evitar que el tratar de obtener una complejidad temporal de orden polinmico conduzca a una complejidad espacial demasiado
elevada, como veremos en alguno de los ejemplos de este captulo.
5.3 CLCULO DE LOS COEFICIENTES BINOMIALES
En la resolucin de un problema, una vez encontrada la expresin recursiva que define su solucin, muchas veces la dificultad estriba en la creacin
del vector o la tabla que ha de conservar los resultados parciales. As en este segundo ejemplo, aunque tambin sencillo, observamos que vamos a
necesitar una tabla bidimensional algo ms compleja. Se trata del clculo de los coeficientes binomiales, definidos como:
1
0
n
.
El algoritmo recursivo que los calcula resulta ser de complejidad exponencial por la repeticin de los clculos que realiza. No obstante, es posible
disear un algoritmo con un tiempo de ejecucin de orden O(nk) basado en la idea del Tringulo de Pascal. Para ello es necesario la creacin de una
tabla bidimensional en la que ir almacenando los valores intermedios que se utilizan posteriormente:
0 1 2 3 ... k-1 k
01
111
2121
31331
... ... ... ... ... ...
... ... ... ... ... ... ...
n-1 C(n-1,k-1) + C(n-1,k)
n C(n,k)
Iremos construyendo esta tabla por filas de arriba hacia abajo y de izquierda a derecha mediante el siguiente algoritmo de complejidad polinmica:

También podría gustarte