En la programación con restricciones y la resolución de problemas SAT , el retroceso (también conocido como retroceso no cronológico [ 1 ] o retroceso inteligente [ 2 ] ) es una mejora para los algoritmos de retroceso que reduce el espacio de búsqueda . Mientras que el retroceso siempre sube un nivel en el árbol de búsqueda cuando se han probado todos los valores de una variable, el retroceso puede subir más niveles. En este artículo, se establece un orden fijo de evaluación de variables.Se utiliza, pero las mismas consideraciones se aplican a un orden de evaluación dinámico.
Un árbol de búsqueda visitado mediante retroceso regular.
Un salto hacia atrás: el nodo gris no se visita.
Definición
Siempre que el retroceso haya probado todos los valores para una variable sin encontrar ninguna solución, reconsidera la última de las variables asignadas previamente, cambiando su valor o retrocediendo aún más si no hay otros valores que probar.es la asignación parcial actual y todos los valores paraSe han intentado sin encontrar una solución, retrocediendo se concluye que no hay ninguna solución que extienda existe. El algoritmo luego "sube" a, cambiandovalor de si es posible, retrocediendo de nuevo en caso contrario.
La asignación parcial no siempre es necesaria en su totalidad para probar que ningún valor deconduce a una solución. En particular, un prefijo de la asignación parcial puede tener la misma propiedad, es decir, existe un índice.de tal manera queno se puede extender para formar una solución con cualquier valor para. Si el algoritmo puede demostrar este hecho, puede considerar directamente un valor diferente paraen lugar de reconsiderarcomo lo haría normalmente.
Un ejemplo en el que la asignación actual aSe ha intentado sin éxito con todos los valores posibles de. El retroceso nos lleva de vuelta a, intentando asignarle un nuevo valor.
En lugar de retroceder, el algoritmo realiza una elaboración adicional, demostrando que las evaluaciones,, yno forman parte de ninguna solución.
Como resultado, la evaluación actual deno forma parte de ninguna solución, y el algoritmo puede retroceder directamente a, probando un nuevo valor para ello.
La eficiencia de un algoritmo de retroceso depende de cuán alto sea capaz de retroceder. Idealmente, el algoritmo podría saltar desdea cualquier variablees tal que la asignación actual ano se puede extender para formar una solución con ningún valor deSi este es el caso,Se denomina salto seguro .
Determinar si un salto es seguro no siempre es factible, ya que los saltos seguros se definen en términos del conjunto de soluciones, que es precisamente lo que el algoritmo intenta encontrar. En la práctica, los algoritmos de retroceso utilizan el índice más bajo que pueden demostrar eficientemente que corresponde a un salto seguro. Los distintos algoritmos emplean diferentes métodos para determinar la seguridad de un salto. Estos métodos tienen distintos costes, pero un mayor coste para encontrar un salto seguro de mayor nivel puede compensarse con una menor cantidad de búsqueda debido a la omisión de partes del árbol de búsqueda.
Retroceso en los nodos de las hojas
La condición más simple en la que es posible el retroceso es cuando se ha demostrado que todos los valores de una variable son inconsistentes sin ramificaciones adicionales. En la satisfacción de restricciones , una evaluación parcial es consistente si y solo si satisface todas las restricciones que involucran a las variables asignadas, e inconsistente en caso contrario. Puede darse el caso de que una solución parcial consistente no pueda extenderse a una solución completa consistente porque algunas de las variables no asignadas no pueden asignarse sin violar otras restricciones.
La condición en la que todos los valores de una variable dada son igualesson incompatibles con la solución parcial actualSe denomina callejón sin salida de hoja . Esto ocurre exactamente cuando la variablees una hoja del árbol de búsqueda (que corresponde a los nodos que tienen solo hojas como hijos en las figuras de este artículo).
El algoritmo de retroceso de John Gaschnig realiza un retroceso solo en los callejones sin salida de las hojas. [ 3 ] En otras palabras, funciona de manera diferente al retroceso solo cuando cada valor posible deSe ha probado y ha dado como resultado inconsistente sin necesidad de ramificar sobre otra variable.
Se puede encontrar un salto seguro simplemente evaluando, para cada valor, el prefijo más corto deincompatible con. En otras palabras, sies un valor posible paraEl algoritmo comprueba la coherencia de las siguientes evaluaciones:
El índice más pequeño (el más bajo de la lista) para el cual las evaluaciones son inconsistentes sería un salto seguro sieran el único valor posible paraDado que cada variable suele poder tomar más de un valor, el índice máximo que resulta de la comprobación de cada valor es un salto seguro, y es el punto donde salta el algoritmo de John Gaschnig.
En la práctica, el algoritmo puede verificar las evaluaciones anteriores al mismo tiempo que verifica la consistencia de.
Retroceso en nodos internos
El algoritmo anterior solo retrocede cuando se puede demostrar que los valores de una variable son inconsistentes con la solución parcial actual sin ramificaciones adicionales. En otras palabras, solo permite retroceder en los nodos hoja del árbol de búsqueda.
Un nodo interno del árbol de búsqueda representa una asignación de variable consistente con las anteriores. Si ninguna solución extiende esta asignación, el algoritmo anterior siempre retrocede: en este caso no se realiza ningún salto hacia atrás.
El backjumping en nodos internos no se puede realizar como en los nodos hoja. De hecho, si algunas evaluaciones deSe requiere ramificación porque son consistentes con la asignación actual. Como resultado, la búsqueda de un prefijo que sea inconsistente con estos valores de la última variable no tiene éxito.
En tales casos, lo que demostró una evaluaciónno formar parte de una solución con la evaluación parcial actualSe trata de una búsqueda recursiva . En concreto, el algoritmo "sabe" que no existe ninguna solución a partir de este punto porque regresa a este nodo en lugar de detenerse tras haber encontrado una solución.
Este retorno se debe a varios callejones sin salida , puntos donde el algoritmo ha demostrado que una solución parcial es inconsistente. Para retroceder aún más, el algoritmo debe tener en cuenta que la imposibilidad de encontrar soluciones se debe a estos callejones sin salida. En particular, los saltos seguros son índices de prefijos que aún hacen que estos callejones sin salida sean soluciones parciales inconsistentes.
En este ejemplo, el algoritmo vuelve a, después de probar todos sus valores posibles, debido a los tres puntos cruzados de inconsistencia.
El segundo punto sigue siendo inconsistente incluso si los valores deyse eliminan de su evaluación parcial (tenga en cuenta que los valores de una variable están en sus hijos)
Las otras evaluaciones inconsistentes siguen siendo así incluso sin,, y
El algoritmo puede retroceder aya que esta es la variable más baja que mantiene todas las inconsistencias. Un nuevo valor paraSe intentará.
En otras palabras, cuando todos los valores deSe han intentado, el algoritmo puede retroceder a una variable anterior.siempre que la evaluación de la verdad actual dees inconsistente con todas las evaluaciones de verdad deen los nodos hoja que son descendientes del nodo.
Simplificaciones

Debido al número potencialmente alto de nodos que se encuentran en el subárbol de, la información que es necesaria para retroceder de forma segura desdese recopila durante la visita a su subárbol. Encontrar un salto seguro se puede simplificar mediante dos consideraciones. La primera es que el algoritmo necesita un salto seguro, pero aún así funciona con un salto que no es el salto seguro más alto posible.
La segunda simplificación es que los nodos en el subárbol deque se hayan omitido mediante un salto hacia atrás pueden ignorarse mientras se busca un salto hacia atrás para. Más precisamente, todos los nodos omitidos mediante un salto hacia atrás desde el nodohasta el nodoson irrelevantes para el subárbol enraizado eny también son irrelevantes sus otros subárboles.
De hecho, si un algoritmo se cayó del nodoaa través de un camino pero retrocede en su camino de regreso, entonces podría haber ido directamente desdeaen cambio. De hecho, el salto hacia atrás indica que los nodos entreyson irrelevantes para el subárbol enraizado enEn otras palabras, un backjump indica que la visita a una región del árbol de búsqueda fue un error. Por lo tanto, esta parte del árbol de búsqueda puede ignorarse al considerar un posible backjump desdeo de uno de sus antepasados.

Este hecho puede aprovecharse recopilando, en cada nodo, un conjunto de variables previamente asignadas cuya evaluación basta para demostrar que no existe solución en el subárbol con raíz en dicho nodo. Este conjunto se construye durante la ejecución del algoritmo. Al retroceder desde un nodo, se elimina la variable de este conjunto y se agrega al conjunto del destino del retroceso o salto hacia atrás. Dado que los nodos que se omiten en el salto hacia atrás nunca se retrocede, sus conjuntos se ignoran automáticamente.
Retroceso basado en grafos
La lógica del backjumping basado en grafos es que se puede encontrar un salto seguro comprobando cuál de las variablesestán en una restricción con las variablesque se instancian en los nodos hoja. Para cada nodo hoja y cada variableíndiceque se instancia allí, los índices menores o iguales acuya variable está en una restricción conse puede utilizar para encontrar saltos seguros. En particular, cuando todos los valores paraSe han intentado, este conjunto contiene los índices de las variables cuyas evaluaciones permiten demostrar que no se puede encontrar ninguna solución visitando el subárbol con raíz enComo resultado, el algoritmo puede retroceder al índice más alto de este conjunto.
El hecho de que los nodos omitidos mediante retroceso puedan ignorarse al considerar un retroceso posterior puede ser aprovechado por el siguiente algoritmo. Al retroceder desde un nodo hoja, se crea el conjunto de variables que están en restricción con él y se "envía" de vuelta a su padre, o ancestro en caso de retroceso. En cada nodo interno, se mantiene un conjunto de variables. Cada vez que se recibe un conjunto de variables de uno de sus hijos o descendientes, sus variables se añaden al conjunto mantenido. Al retroceder o retroceder desde el nodo, la variable del nodo se elimina de este conjunto, y el conjunto se envía al nodo que es el destino del retroceso o del retroceso. Este algoritmo funciona porque el conjunto mantenido en un nodo recopila todas las variables que son relevantes para probar la insatisfacibilidad en las hojas que son descendientes de este nodo. Dado que los conjuntos de variables solo se envían al retroceder desde los nodos, los conjuntos recopilados en los nodos omitidos mediante retroceso se ignoran automáticamente.
Retroceso basado en el conflicto
El retroceso basado en conflictos ( también conocido como retroceso dirigido por conflictos) es un algoritmo más refinado que, en ocasiones, permite realizar retrocesos de mayor alcance. Se basa en comprobar no solo la presencia común de dos variables en la misma restricción, sino también si dicha restricción ha provocado alguna inconsistencia. En concreto, este algoritmo recopila una de las restricciones violadas en cada hoja. En cada nodo, el índice más alto de una variable presente en una de las restricciones recopiladas en las hojas constituye un salto seguro.
Si bien la restricción violada elegida en cada hoja no afecta la seguridad del salto resultante, elegir restricciones con los índices más altos posibles aumenta la altura del salto. Por esta razón, el método de retroceso basado en conflictos ordena las restricciones de tal manera que se prefieren las restricciones sobre variables de índices más bajos a las restricciones sobre variables de índices más altos.
Formalmente, una restricciónes preferido sobre otrosi el índice más alto de una variable enpero no enes inferior al índice más alto de una variable enpero no enEn otras palabras, excluyendo las variables comunes, se prefiere la restricción que tiene todos los índices inferiores.
En un nodo hoja, el algoritmo elige el índice más bajo.de tal manera quees inconsistente con la última variable evaluada en la hoja. Entre las restricciones que se violan en esta evaluación, elige la más preferida y recopila todos sus índices menores queDe esta forma, cuando el algoritmo vuelva a la variableEl índice más bajo registrado identifica un salto seguro.
En la práctica, este algoritmo se simplifica al recopilar todos los índices en un solo conjunto, en lugar de crear un conjunto para cada valor deEn concreto, el algoritmo recopila, en cada nodo, todos los conjuntos provenientes de sus descendientes que no hayan sido omitidos mediante el retroceso. Al retroceder desde este nodo, este conjunto se elimina de la variable del nodo y se añade al destino del retroceso.
El backjumping dirigido por conflictos fue propuesto para problemas de satisfacción de restricciones por Patrick Prosser en su artículo fundamental de 1993. [ 4 ]
Véase también
Notas y referencias
Bibliografía
- Dechter, Rina (2003). Procesamiento de restricciones . Morgan Kaufmann Publishers . ISBN 1-55860-890-7.
- Gaschnig, John (1977). "Un algoritmo general de retroceso que elimina la mayoría de las pruebas redundantes" (PDF) . Actas de la 5.ª Conferencia Internacional Conjunta sobre Inteligencia Artificial (IJCAI-77) . Vol. 1. Cambridge, Massachusetts, EE. UU.: Conferencias Internacionales Conjuntas sobre Inteligencia Artificial. págs. 457–457 .
- Möhle, S.; Biere, A. (2019). "Backing backtracking". Theory and Applications of Satisfiability Testing – SAT 2019: 22nd International Conference, SAT 2019, Lisboa, Portugal, 9–12 de julio de 2019, Proceedings . Springer International Publishing. pp. 250–266 .
- Prosser, Patrick (1993). "Algoritmos híbridos para el problema de satisfacción de restricciones" (PDF) . Inteligencia Computacional .
- Programación con restricciones
- Algoritmos de búsqueda