Cómo utilizar el algoritmo Smith-Watman para mostrar todas las rutas en programación dinámica
var anteriorFib:= 0, actualFib:= 1
si n = 0
devuelve 0
más si n = 1
devuelve 1
repite n-1 veces
var newFib := anteriorFib actualFib
anteriorFib := actualFib
currentFib := newFib
return currentFib
En ambos ejemplos, solo calculamos fib(2) una vez y luego lo usamos para calcular fib(3 ) y fib (4) en lugar de volver a calcular cada vez.
Existen al menos tres algoritmos posibles para resolver este problema: fuerza bruta, retroceso y programación dinámica. El método de fuerza bruta enumera todas las opciones de asignación y encuentra las que satisfacen las condiciones de equilibrio una por una. Dado que *** hay soluciones C(n, n/2)^n (en una fila, el número de combinaciones que contienen n/2 0 y n/2 1 es C(n, n/2), lo que equivale a comenzando desde Seleccione n/2 posiciones para poner 0 entre n posiciones, y el resto son naturalmente 1). Cuando n = 6, el método exhaustivo es casi inviable. El método de retroceso asigna algunos elementos en la matriz a 0 o 1, luego verifica los elementos no asignados en cada fila y columna y los asigna, de modo que el número de 0 y 1 en cada fila y columna sea n/2. El método de retroceso es más inteligente que el método exhaustivo, pero aún necesita recorrer todas las soluciones para determinar el número de soluciones. Se puede ver que cuando n = 8, el número de soluciones del problema ha llegado a 116963796250. Programación dinámica La programación dinámica no necesita atravesar todas las soluciones para determinar el número de soluciones (esto significa que después de dividir los subproblemas, se pueden evitar de manera efectiva los cálculos repetidos de varios subproblemas).
El proceso de resolución de problemas mediante programación dinámica es sorprendentemente sencillo. Considere una submatriz k*n(1lt;=klt;=n), cada fila contiene n/2 0 y n/2 1, y una función f que se asigna a un vector de acuerdo con las posibles asignaciones de cada fila, cada vector consta de n pares de números enteros. Los dos números enteros en el par de números enteros correspondientes a cada columna del vector representan el número de ceros y unos en la columna y la fila respectivamente. El problema se transforma en encontrar f((n/2, n/2), (n/2, n/2),..., (n/2, n/2)) (que contiene n parámetros o n elementos vectoriales ). La estructura de su subproblema es la siguiente:
1) La fila superior (k-ésima fila) tiene asignación C(n, n/2);
2) Según el asignación de cada columna en la fila superior (0 o 1), el valor del elemento correspondiente en el par de enteros correspondiente es menos 1;
3) Si cualquier elemento en cualquier par de enteros es un valor negativo, la asignación es ilegal y no puede considerarse correcta Solución;
4) De lo contrario, complete la asignación de la fila superior de la submatriz k*n, tome k=k-1 y calcule la asignación de las submatrices restantes (k-1)*n;
5) El caso base es un subproblema refinado de 1*n. En este caso, el número de soluciones al subproblema es 0 o 1. , dependiendo de si su vector es disposición n/2 (0 ,1) y n/2 (1,0).
2) (1, 2) (2, 1) (2, 1) (2, 1)) k = 3
1 0 1 0 0 0 0 0 1 1
((1, 1) (1, 1) (1, 1) (1, 1) (1, 1) (1, 1)) (0, 2) (0, 2) (0, 2) (0, 2) (0, 0) (2, 0)) k = 2
0 0 1 1 0 0 0 0
((0, 1) (1, 1) ( 0, 1) (1, 1) (1, 0)) ((0, 1) (0, 1) (1, 0) (1, 0)) k = 1
1 0 1 0 1 1 0 0 0
((0, 0) (0, 0) (0, 0) (0, 0) (0, 0) (0, 0) (0, 0) ( 0, 0) (0, 0)), (0, 0) (0, 0))
La programación dinámica es relevante porque evita calcular repetidamente la misma f.
El número de soluciones a este problema (secuencia a058527 en OEIS) es 1, 2, 90, 297200, 116963796250, 6736218287430460752, ...
Los siguientes enlaces externos contienen el retroceso método de implementación de código fuente Perl, así como implementaciones MAPLE y C de métodos de programación dinámica.
3. Tablero de ajedrez
Considere un tablero de ajedrez n*n y la función de costo C(i, j), que devuelve el costo.
Comience desde el primer nivel (fila) de cualquier cuadrado en el tablero de ajedrez, encuentre el camino más corto hasta el último nivel (minimice la suma de los costos de todos los cuadrados pasados), suponiendo que solo se mueve un cuadrado. diagonalmente hacia la izquierda, diagonalmente hacia la derecha o verticalmente. Es decir, la solución global a todo el problema depende de las soluciones a los subproblemas. Defina la función q(i, j): q(i, j) representa el costo mínimo para alcanzar el cuadrado (i, j).
Si podemos encontrar los valores de q(i,j) para todos los cuadrados de orden n, entonces podemos obtener el camino más corto simplemente tomando el valor mínimo e invirtiendo el camino.
Por ejemplo, registre q(i, j) como cuadrado (i, j) a los siguientes tres cuadrados ((i-1, j-1), (i-1, j), la suma del coste mínimo de (i-1, j), (i-1, j 1)) y c(i, j):
5 |
4 A
3 | B C D
2 |
1 |