He estado trabajando en programación dinámica por algún tiempo. La forma canónica de evaluar una recursión de programación dinámica es creando una tabla de todos los valores necesarios y llenándola fila por fila. Ver por ejemplo Cormen, Leiserson et al: "Introducción a los algoritmos" para una introducción.
Me concentro en el esquema de cálculo basado en tablas en dos dimensiones (relleno fila por fila) e investigo la estructura de las dependencias de las celdas, es decir, qué celdas deben hacerse antes de que se pueda calcular otra. Denotamos con el conjunto de índices de celdas de las que depende la celda . Tenga en cuenta que necesita estar libre de ciclos.i Γ
Extracto de la función real que se calcula y me concentro en su estructura recursiva. Formalmente, considero que una recurrencia es programación dinámica si tiene la forma
con , y alguna función (computable) que no utiliza que no sea a través de .˜ Γ d ( i ) = { ( j , d ( j ) ) ∣ j ∈ Γ d ( i ) } f d ˜ Γ d
Al restringir la granularidad de a áreas rugosas (a la izquierda, arriba a la izquierda, arriba, arriba a la derecha, ... de la celda actual) se observa que existen esencialmente tres casos (hasta simetrías y rotación) de validez Recurrencias de programación dinámica que informan cómo se puede llenar la tabla:
Las áreas rojas denotan (sobre aproximaciones de) . Los casos uno y dos admiten subconjuntos, el caso tres es el peor de los casos (hasta la transformación del índice). Tenga en cuenta que no es estrictamente necesario que todas las áreas rojas estén cubiertas por ; Algunas celdas en cada parte roja de la tabla son suficientes para pintarla de rojo. Se requiere explícitamente que las áreas blancas no contengan ninguna celda requerida.Γ
Ejemplos para el caso uno son la distancia de edición y la subsecuencia común más larga , el caso dos se aplica a Bellman & Ford y CYK . Entre los ejemplos menos obvios se incluyen los que funcionan en las diagonales en lugar de las filas (o columnas), ya que pueden rotarse para ajustarse a los casos propuestos; Vea la respuesta de Joe como ejemplo.
¡Sin embargo, no tengo un ejemplo (natural) para el caso tres! Entonces mi pregunta es: ¿Cuáles son los ejemplos para el caso tres de recurrencias / problemas de programación dinámica?