¿Qué es el retroceso en un diseño de algoritmo?

Backtracking es un método de diseño de algoritmos recursivos. Está formado por dos partes:

  1. En un punto de ramificación (donde se debe tomar una decisión), comienza un ciclo que prueba secuencialmente todas las posibilidades para la decisión.
  2. El algoritmo se llama de forma recursiva en el subproblema que queda después de tomar esa decisión.

Por ejemplo, si estabas tratando de resolver un laberinto y llegaste a un cuadrado con tres salidas diferentes, podrías

  1. Elija la salida izquierda, luego llame a su algoritmo de resolución de laberinto de forma recursiva.
  2. Si eso no llegó a la salida del laberinto, intente seguir recto y llame al algoritmo de resolución del laberinto de forma recursiva.
  3. Si eso no llegó a la salida del laberinto, intente ir a la derecha y llame al algoritmo de resolución del laberinto de forma recursiva.
  4. Si ninguno de esos funciona, devuelva el fracaso y permita que algunas decisiones previamente tomadas se vuelvan atrás.

(Esto se conoce como una búsqueda de profundidad primero).

Otro buen ejemplo es la solución propuesta por Google Code Jam para “Cerrar coincidencia”, sobre la cual puede leer aquí:

Panel de control – Ronda 1B 2016 – Google Code Jam

Me gustaría explicarlo con un algoritmo clásico de resolución de rompecabezas de N-Queens .

Problema: dado un tablero de ajedrez NxN (supongamos que 8 × 8 por ahora), debes colocar N reinas en él para que no se ataquen dos. (Supongo que sabes cómo se mueve la reina en el ajedrez).

El retroceso funciona creando una “solución candidata” de forma incremental. En el caso de un problema de N-Queens, las reinas se colocan de forma incremental y se aseguran de que no haya dos reinas que se ataquen entre sí. Es decir, coloca a la primera reina en alguna posición, digamos P1. Si la primera reina está en la posición P1, ¿cómo puedes colocar la segunda mientras satisfaces las condiciones? Piénsalo para la tercera, cuarta y finalmente la enésima reina.

Si la solución candidata no cumple las condiciones en algún momento, entonces ” se borran los cambios en algunos pasos anteriores” y se prueban otros candidatos. Recuerda que todo N! las permutaciones no son soluciones para N-Queens, pero el algoritmo intenta todo eso. Muchos de ellos fallan.

Si desea visualizar la ejecución, piense en el árbol de llamadas recursivas. Cuando caminas por el árbol eligiendo alguna rama, haces ciertos cambios. Esos cambios se ” deshacen” cuando subes por el árbol para probar alguna otra rama.

def n_queens (k):
si k es (N + 1), entonces la solución es válida. Imprímelo.
para i: = 1 a N:
si colocar kth queen en (fila k, col i) es seguro:
colocar reina en (fila k, col i)
n_queens (k + 1)
eliminar reina de (fila k, col i)

Eso es todo. Haga cambios antes de hacer una llamada recursiva. Deshacer los cambios después de esa llamada.

Backtracking es un paradigma de diseño de algoritmos. Por paradigma me refiero a un enfoque para la resolución de problemas. Es una familia de algoritmos realmente. Es una forma de agotar sistemáticamente un espacio de búsqueda cuando el problema en cuestión requiere búsqueda. Entonces, esto es una especie de prueba de que una solución de retroceso es correcta porque busca en todo el espacio de estados. Como consecuencia, el tiempo de ejecución de su algoritmo dependerá del tamaño del espacio de búsqueda.

La recursión es útil cuando desea aplicar el retroceso para resolver un problema. Llamo a mi función de backtrack y backtrack y toma un state como entrada. El estado depende del problema, podría ser un tablero de ajedrez parcialmente lleno, parte de una permutación, etc. Lo primero que hago es verificar si el estado de entrada es un goal state , final state o lo que quieras nombrar, esto responde a la pregunta: ¿es el estado una solución al problema? Si ese es el caso, entonces proceso ese estado (podría ser: imprimir algo, incrementar un contador, etc.). Si este no es el caso, entonces tengo que continuar la búsqueda y la forma en que lo hago es tener una función que generate candidate states desde el estado de entrada y luego recursively call backtrack a los estados recién generados. Esto nos acerca un paso más a una solución (si la hay).

Esto es como la primera búsqueda en profundidad, excepto que la estructura del gráfico es implícita. La creatividad en una solución de retroceso no es el algoritmo en sí, es mecánico; la creatividad está en cómo va a representar a los estados y cómo va a generar estados candidatos. Dependiendo de la representación que use, su algoritmo puede terminar tomando enormes cantidades de tiempo para terminar o tomar solo unos segundos para terminar (también depende del tamaño del problema).

Por favor, eche un vistazo a este artículo. Creo que esto te ayudará. 🙂

Explicación recursiva hacia atrás

More Interesting

¿Cómo funciona la clasificación bayesiana? ¿Cuáles son algunas de sus aplicaciones?

¿Qué tipo de algoritmos se utilizan en DSP (plataforma del lado de la demanda)?

Cómo medir la precisión de un algoritmo de planificación de ruta

Cómo inicializar una matriz

¿Cuáles son los mini proyectos que se pueden hacer en el algoritmo para el procesamiento de imágenes y videos?

¿En cuánto tiempo puedo ser un profesional en la resolución de problemas en algoritmos y estructuras de datos si empiezo hoy sin ningún conocimiento previo?

Cómo recorrer un trabajo de búsqueda binaria e imprimirlo en orden

Tengo la cadena de entrada, también tengo la cadena encriptada. ¿Cómo averiguo qué algoritmo de cifrado se utilizó?

Cómo implementar prácticamente algoritmos enseñados por Andrew Ng en su curso de aprendizaje automático

¿Debo ir a un curso de algoritmos o comenzar a resolver problemas en TopCoder / CodeChef, etc.?

En programación, ¿un generador de números aleatorios es realmente aleatorio? ¿O son los números aleatorios generados por un algoritmo oculto?

¿Cuáles son algunos problemas de nivel intermedio en los que es imprescindible comprender la corrección de los algoritmos (y por qué)?

¿Cuáles son las desventajas del algoritmo genético?

Cómo encontrar el número máximo de árboles de expansión mínima en un gráfico

¿Debo aprender el concepto profundo del aprendizaje automático como el curso de Andrew Ng o es suficiente para saber qué algoritmo se utiliza cuando?