Programación Dinámica: Problema de la Soga, Weighted Interval Scheduling, Cambio Mínimo, Seam Carving Flashcards
¿Qué es la programación dinámica?
- Es una metodología de resolución para problemas de optimización (minimización o maximización).
- Divide el problema en subproblemas con una jerarquía entre ellos de menor a mayor tamaño.
- Cada subproblema puede ser utilizado y reutilizado en diferentes subproblemas mayores.
¿Qué propiedades debe tener un problema para poder resolverse de forma óptima con programación dinámica?
Para poder resolverse de forma óptima con programación dinámica, el problema debe contener las siguientes propiedades:
- Subestructura óptima: la solución óptima global contiene en su interior las soluciones óptimas de sus subproblemas.
- Subproblemas superpuestos: en la resolución de sus subproblemas, vuelven a aparecer subproblemas previamente calculados.
¿Por qué se usa una relación de recurrencia con programación dinámica?
Se usa una relación de recurrencia porque cada problema se ramifica en un conjunto de subproblemas.
¿Qué es la memorización? ¿Qué se reduce con ella?
La memorización es la técnica fundamental para la resolución en forma eficiente de los problemas, mediante programación dinámica: consiste en almacenar los resultados de los subproblemas previamente calculados; para evitar repetir su resolución.
Se reduce la cantidad de problemas a calcular, por lo que se reduce la complejidad temporal de la solución.
Problema del Corte de la Soga: Explique
Se tiene una soga de longitud L y una tabla de precios por longitud de la soga.
Queremos saber qué cortes realizar para maximizar la ganancia.
Cada corte realizado de longitud li
nos deja con una ganancia pi
y un largo de soga L-li
.
Problema del corte de la soga: explique la solución por programación dinámica.
Lo que vamos a hacer es armar un árbol de decisión representando todas las posibilidades. El óptimo será el máximo elegido entre todas las posibles ramas de subproblemas y opciones:
-
OPT(X) = MAX { pi + OPT(X-i) } si X >0
. -
OPT(X) = 0 si X <= 0
.
Como en el árbol de decision ciertos problemas se repiten, podemos calcular una sola vez el resultado, y luego reutilizarlo almacenando en una tabla los subproblemas resueltos.
Ahora sólo se deben calcular L subproblemas, y la ganancia óptima va a estar en la última fila de nuestra tabla de memorización.
Problema de la Soga: Explique el pseudocódigo de la solución iterativa. ¿Cuál es la complejidad?
1. OPT es el vector de óptimos, OPT[0] = 0 2. Recorro con i desde 0 a L: a. OPT[i] = 0 (lo inicializo en cero) b. Con j desde 0 a i: valor = precio[j] + OPT(i-j) si valor > OPT[i]: OPT[i] = valor 3. Retornar OPT[L]
- Inicializamos un vector donde se guardan las ganancias con (0,0).
- Recorremos todos los posibles cortes i del 0 a L. Para cada uno, inicializamos el óptimo en 0. Luego, recorremos todos los posibles subcortes de 0 a i, guardando el precio del corte + el óptimo del restante (i-j). Si el valor es mayor al óptimo, mejoramos el caso previo y cambiamos el valor.
- Retornamos el valor óptimo de L.
La complejidad espacial es O(L), y la temporal es O(L^2).
Problema de la Soga: ¿Cómo podemos actualizar el pseudocódigo anterior para permitir la reconstrucción de decisiones?
Para permitir la reconstrucción de decisiones, además de actualizar el óptimo cuando el valor es mayor, guardamos la elección de j
que dió ese óptimo.
Lo hacemos en otro vector: eleccion[i] = j
.
Al finalizar, además de retornar el OPT de L, recorremos de L a 0 el vector eleccion
, restando cada uno de los valores que encontramos de eleccion[L]
hasta eleccion[0]
(no van a ser números secuenciales).
Problema de la Soga: Resolver
L = 4
long, precio:
0 , 0
1 , 2
2 , 5
3 , 7
4 , 8
[2,2] con ganancia 10
Weighted Interval Scheduling: explique el problema
Es un Interval Scheduling donde ahora cada pedido tiene un valor vi
.
Queremos seleccionar el conjunto P con tareas compatibles entre sí y que la suma de sus valores sea la mayor posible (ya no buscamos la mayor cantidad de pedidos compatibles, sino la mayor ganancia).
Weighted Interval Scheduling: explique la implementación
- El orden se mantiene: ordenamos las tareas en orden creciente de tiempo de finalización.
- Para cada tarea
i
, queremos saber cuál es la primer tarea anterior con la que es compatible el eventoP(i)
.
Sabemos que por cómo están ordenadas, todos los compatibles de un evento i van a tener un valor menor a i ( x < i, x tiene tiempo de finalización previo a i).
Weighted Interval Scheduling: ¿Cómo se define la pertenencia de una tarea al óptimo? ¿Qué pasa si un pedido no pertenece al óptimo?
- Si un pedido
i
pertenece al óptimo, ningún pedido incompatible coni
pertenece. El primero en aparecer después dei
esP(i)
, el primer anterior compatible. - Si el pedido no pertenece al óptimo, la tarea
i-1
podría hacerlo.
Weighted Interval Scheduling: Explique el uso del árbol de decisión
El arbol, para cada elemento, tiene dos ramas: una si el elemento pertenece al óptimo, la otra sino pertenece.
Si un pedido está en el óptimo, se abre la pregunta de si su anterior compatible está. Si no lo está, seguimos con el siguiente anterior compatible.
Vemos que hay problemas que se repiten.
Weighted Interval Scheduling: Explique la solución iterativa
- Si x =0, el óptimo es 0.
- Si x > 0, el óptimo se calcula como:
a. Obtenemos el valor de x
b. Obtenemos el valor del óptimo para el inmediatamente compatible de x
c. Los sumamos
d. Obtenemos el óptimo del anterior en orden de finalización: OPT(x-1).
e. Nos quedamos con el máximo de esos dos valores (la suma, o el óptimo del anterior en finalización) y lo guardamos como óptimo del evento actual. - El resultado va a estar en OPT(n).
OPT[0] = 0 Desde i=1 ... n: enOptimo = V[i] + OPT[P(i)] noEnOptimo = OPT[i-1] Si enOptimo >= noEnOptimo: OPT[i] = enOptimo Sino: OPT[i] = noEnOptimo Retornar OPT[n]
Weighted Interval Scheduling: Explique para el pseudocódigo sus complejidades temporales y espaciales.
Complejidad Temporal: O(n)
Complejidad Espacial: O(n)