Articulo de referencia

salto hacia atrás

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...

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.incógnita1,,incógnitanorte{\displaystyle x_{1},\ldots ,x_{n}}Se utiliza, pero las mismas consideraciones se aplican a un orden de evaluación dinámico.

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.incógnita1=a1,,incógnitak=ak{\displaystyle x_{1}=a_{1},\ldots ,x_{k}=a_{k}}es la asignación parcial actual y todos los valores paraincógnitak+1{\displaystyle x_{k+1}}Se han intentado sin encontrar una solución, retrocediendo se concluye que no hay ninguna solución que extienda incógnita1=a1,,incógnitak=ak{\displaystyle x_{1}=a_{1},\ldots ,x_{k}=a_{k}}existe. El algoritmo luego "sube" aincógnitak{\displaystyle x_{k}}, cambiandoincógnitak{\displaystyle x_{k}}valor 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 deincógnitak+1{\displaystyle x_{k+1}}conduce a una solución. En particular, un prefijo de la asignación parcial puede tener la misma propiedad, es decir, existe un índice.j<k{\displaystyle j<k}de tal manera queincógnita1,,incógnitaj=a1,,aj{\displaystyle x_{1},\ldots ,x_{j}=a_{1},\ldots ,a_{j}}no se puede extender para formar una solución con cualquier valor paraincógnitak+1{\displaystyle x_{k+1}}. Si el algoritmo puede demostrar este hecho, puede considerar directamente un valor diferente paraincógnitaj{\displaystyle x_{j}}en lugar de reconsiderarincógnitak{\displaystyle x_{k}}como lo haría normalmente.

La eficiencia de un algoritmo de retroceso depende de cuán alto sea capaz de retroceder. Idealmente, el algoritmo podría saltar desdeincógnitak+1{\displaystyle x_{k+1}}a cualquier variableincógnitaj{\displaystyle x_{j}}es tal que la asignación actual aincógnita1,,incógnitaj{\displaystyle x_{1},\ldots ,x_{j}}no se puede extender para formar una solución con ningún valor deincógnitak+1{\displaystyle x_{k+1}}Si este es el caso,j{\displaystyle j}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 igualesincógnitak+1{\displaystyle x_{k+1}}son incompatibles con la solución parcial actualincógnita1,,incógnitak=a1,,ak{\displaystyle x_{1},\ldots ,x_{k}=a_{1},\ldots ,a_{k}}Se denomina callejón sin salida de hoja . Esto ocurre exactamente cuando la variableincógnitak+1{\displaystyle x_{k+1}}es 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 deincógnitak+1{\displaystyle x_{k+1}}Se 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 valorak+1{\displaystyle a_{k+1}}, el prefijo más corto deincógnita1,,incógnitak=a1,,ak{\displaystyle x_{1},\ldots ,x_{k}=a_{1},\ldots ,a_{k}}incompatible conincógnitak+1=ak+1{\displaystyle x_{k+1}=a_{k+1}}. En otras palabras, siak+1{\displaystyle a_{k+1}}es un valor posible paraincógnitak+1{\displaystyle x_{k+1}}El 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 siincógnitak+1=ak+1{\displaystyle x_{k+1}=a_{k+1}}eran el único valor posible paraincógnitak+1{\displaystyle x_{k+1}}Dado 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 deincógnitak+1=ak+1{\displaystyle x_{k+1}=a_{k+1}}.

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 deincógnitak+1{\displaystyle x_{k+1}}Se 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ónincógnitak+1=ak+1{\displaystyle x_{k+1}=a_{k+1}}no formar parte de una solución con la evaluación parcial actualincógnita1,,incógnitak{\displaystyle x_{1},\ldots ,x_{k}}Se 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 otras palabras, cuando todos los valores deincógnitak+1{\displaystyle x_{k+1}}Se han intentado, el algoritmo puede retroceder a una variable anterior.incógnitai{\displaystyle x_{i}}siempre que la evaluación de la verdad actual deincógnita1,,incógnitai{\displaystyle x_{1},\ldots ,x_{i}}es inconsistente con todas las evaluaciones de verdad deincógnitak+1,incógnitak+2,...{\displaystyle x_{k+1},x_{k+2},...}en los nodos hoja que son descendientes del nodoincógnitak+1{\displaystyle x_{k+1}}.

Simplificaciones

Mientras buscaba un posible salto hacia atrás paraincógnitak+1{\displaystyle x_{k+1}}o uno de sus ancestros, todos los nodos en el área sombreada pueden ignorarse.

Debido al número potencialmente alto de nodos que se encuentran en el subárbol deincógnitak+1{\displaystyle x_{k+1}}, la información que es necesaria para retroceder de forma segura desdeincógnitak+1{\displaystyle x_{k+1}}se 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 deincógnital{\displaystyle x_{l}}que se hayan omitido mediante un salto hacia atrás pueden ignorarse mientras se busca un salto hacia atrás paraincógnital{\displaystyle x_{l}}. Más precisamente, todos los nodos omitidos mediante un salto hacia atrás desde el nodoincógnitametro{\displaystyle x_{m}}hasta el nodoincógnital{\displaystyle x_{l}}son irrelevantes para el subárbol enraizado enincógnitametro{\displaystyle x_{m}}y también son irrelevantes sus otros subárboles.

De hecho, si un algoritmo se cayó del nodoincógnital{\displaystyle x_{l}}aincógnitametro{\displaystyle x_{m}}a través de un camino pero retrocede en su camino de regreso, entonces podría haber ido directamente desdeincógnital{\displaystyle x_{l}}aincógnitametro{\displaystyle x_{m}}en cambio. De hecho, el salto hacia atrás indica que los nodos entreincógnital{\displaystyle x_{l}}yincógnitametro{\displaystyle x_{m}}son irrelevantes para el subárbol enraizado enincógnitametro{\displaystyle x_{m}}En 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 desdeincógnital{\displaystyle x_{l}}o de uno de sus antepasados.

Las variables cuyos valores son suficientes para demostrar la insatisfacibilidad en el subárbol con raíz en un nodo se recogen en el nodo y se envían (después de eliminar la variable del nodo) al nodo superior al retraerse.

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 variablesincógnita1,,incógnitak{\displaystyle x_{1},\ldots ,x_{k}}están en una restricción con las variablesincógnitak+1,incógnitak+2,...{\displaystyle x_{k+1},x_{k+2},...}que se instancian en los nodos hoja. Para cada nodo hoja y cada variableincógnitai{\displaystyle x_{i}}índicei>k{\displaystyle i>k}que se instancia allí, los índices menores o iguales ak{\displaystyle k}cuya variable está en una restricción conincógnitai{\displaystyle x_{i}}se puede utilizar para encontrar saltos seguros. En particular, cuando todos los valores paraincógnitak+1{\displaystyle x_{k+1}}Se 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 enincógnitak+1{\displaystyle x_{k+1}}Como 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óndo{\displaystyle C}es preferido sobre otroD{\displaystyle D}si el índice más alto de una variable endo{\displaystyle C}pero no enD{\displaystyle D}es inferior al índice más alto de una variable enD{\displaystyle D}pero no endo{\displaystyle C}En 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.i{\displaystyle i}de tal manera queincógnita1,,incógnitai{\displaystyle x_{1},\ldots ,x_{i}}es 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 quek+1{\displaystyle k+1}De esta forma, cuando el algoritmo vuelva a la variableincógnitak+1{\displaystyle x_{k+1}}El í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 dek{\displaystyle k}En 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

  • 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 .