Estructuras de datos de soporte para búsqueda local SAT

20

WalkSAT y GSAT son algoritmos de búsqueda locales bien conocidos y simples para resolver el problema de satisfacción booleana. El pseudocódigo para el algoritmo GSAT se copia de la pregunta Implementación del algoritmo GSAT: ¿cómo seleccionar qué literal voltear? y presentado a continuación.

procedure GSAT(A,Max_Tries,Max_Flips)
  A: is a CNF formula
  for i:=1 to Max_Tries do
    S <- instantiation of variables
    for j:=1 to Max_Iter do
      if A satisfiable by S then
        return S
      endif
      V <- the variable whose flip yield the most important raise in the number of satisfied clauses;
      S <- S with V flipped;
    endfor
  endfor
  return the best instantiation found
end GSAT

Aquí volteamos la variable que maximiza el número de cláusulas satisfechas. ¿Cómo se hace esto de manera eficiente? El método ingenuo es voltear cada variable, y para cada paso a través de todas las cláusulas y calcular cuántas de ellas quedan satisfechas. Incluso si se pudiera consultar la satisfacción de una cláusula en tiempo constante, el método ingenuo seguiría ejecutándose en tiempo , donde V es el número de variables y C el número de cláusulas. Estoy seguro de que podemos hacerlo mejor, de ahí la pregunta:O(VC)VC

Muchos algoritmos de búsqueda locales cambian la asignación de la variable que maximiza el número de cláusulas satisfechas. En la práctica, ¿con qué estructuras de datos se respalda esta operación de manera eficiente?

Esto es algo que siento que los libros de texto a menudo omiten. Un ejemplo es incluso el famoso libro de Russell y Norvig .

Juho
fuente
Bueno, estos tipos lo construyen en hardware. Aparentemente , los enfoques probabilísticos y heurísticos son más populares; eso sugeriría que no puedes elegir la variable "mejor" (después de todo, solo es codiciosa) rápidamente, o que esta elección no es buena en general.
Raphael
@Raphael Quizás tengas razón en que uno no puede elegirlo muy rápido, pero no me atrevería a decir "la elección no es buena en general". Tal vez entendí mal su punto de vista, pero estoy bastante seguro de que elegir la variable "correcta" tiene un gran impacto. Gracias, profundizaré un poco más. Creo que uno de los autores de las diapositivas que vinculaste (Hoos) tiene un libro sobre el tema.
Juho
El "correcto" sería óptimo, pero ¿hay alguna razón para creer que el que ahora maximiza es el correcto? Después de todo, el problema no es solucionable por codicioso (canónico).
Raphael

Respuestas:

9

La estructura de datos necesaria es una lista de ocurrencia , una lista para cada variable que contiene las cláusulas en las que aparece la variable. Estas listas se crean una vez, cuando se lee el CNF por primera vez. Se utilizan en los pasos 3 y 5 a continuación para evitar escanear toda la fórmula CNF para contar cláusulas satisfechas.

Un mejor algoritmo que voltear cada variable es:

  1. Haga una lista de solo las variables que ocurren en las cláusulas insatisfechas.
  2. X
  3. X
  4. X
  5. X
  6. X
  7. X
  8. Repita los pasos 2-7 para el resto de las variables encontradas en el paso 1.
  9. Voltee la variable con el número más alto registrado en el paso 7.

Una referencia para la estructura de datos (a menudo también conocida como una lista de adyacencia) es, por ejemplo, Lynce y Marques-Silva, Efficient Data Structures for Backtracking SAT soluvers, 2004.

Kyle Jones
fuente