Der Davis-Putnam-Logemann-Loveland (DPLL) -Algorithmus ist ein Backtracking-basierter Suchalgorithmus zur Entscheidung der Erfüllbarkeit von aussagenlogischen Formeln in konjunktiver Normalform, auch bekannt als Erfüllbarkeitsproblem oder SAT.
Jede boolesche Formel kann in konjunktiver Normalform (CNF) ausgedrückt werden, was eine Konjunktion von Klauseln bedeutet, d.h. (…) ^ (…) ^ (…)
wo eine Klausel eine Disjunktion von booleschen Variablen ist, d.h. (A v B v C' v D)
ein Beispiel für eine boolesche Formel in CNF ausgedrückt ist
(A v B v C) ^ (C' v D) ^ (D' v A)
und das Lösen des SAT-Problems bedeutet, die Kombination von Werten für die Variablen in der Formel zu finden, die sie erfüllen, wie z.B. A=1, B=0, C=0, D=0
Dies ist ein NP-vollständiges Problem. Tatsächlich ist es das erste Problem, das von Stepehn Cook und Leonid Levin als NP-vollständig nachgewiesen wurde.
Ein bestimmter Typ von SAT-Problem ist das 3-SAT, bei dem alle Klauseln drei Variablen enthalten.
Der DPLL-Algorithmus ist eine Möglichkeit, das SAT-Problem zu lösen (was praktisch von der Schwierigkeit des Inputs abhängt), der rekursiv einen Baum potenzieller Lösungen erstellt
Angenommen, Sie möchten ein 3-SAT-Problem wie dieses lösen
(A v B v C) ^ (C' v D v B) ^ (B v A' v C) ^ (C' v A' v B')
Wenn wir die Variablen nummerieren, z. B. A=1, B=2, C=3, D=4, und negative Zahlen für negierte Variablen verwenden, z. B. A' = -1, dann kann dieselbe Formel in Python wie folgt geschrieben werden
[[1,2,3],[-3,4,2],[2,-1,3],[-3,-1,-2]]
stellen Sie sich nun vor, einen Baum zu erstellen, in dem jeder Knoten aus einer Teil-Lösung besteht. In unserem Beispiel haben wir auch einen Vektor der durch die Lösung erfüllten Klauseln dargestellt
Der Wurzelknoten ist [-1,-1,-1,-1], was bedeutet, dass den Variablen noch keine Werte zugewiesen wurden, weder 0 noch 1
bei jeder Iteration:
-
wir nehmen die erste unerfüllte Klausel dann
-
wenn es keine weiteren unzugewiesenen Variablen gibt, die wir verwenden können, um diese Klausel zu erfüllen, können keine gültigen Lösungen in diesem Zweig des Suchbaums existieren und der Algorithmus gibt None zurück
-
ansonsten nehmen wir die erste unzugewiesene Variable und setzen sie so, dass sie die Klausel erfüllt und beginnen rekursiv von Schritt 1. Wenn der innere Aufruf des Algorithmus None zurückgibt, kehren wir den Wert der Variablen um, sodass sie die Klausel nicht erfüllt, und setzen die nächste unzugewiesene Variable, um die Klausel zu erfüllen. Wenn alle drei Variablen ausprobiert wurden oder keine weiteren unzugewiesenen Variablen für diese Klausel vorhanden sind, bedeutet dies, dass es keine gültigen Lösungen in diesem Zweig gibt und der Algorithmus None zurückgibt
Sehen Sie sich das folgende Beispiel an:
Vom Wurzelknoten aus wählen wir die erste Variable (A) der ersten Klausel (A v B v C) und setzen sie so, dass sie die Klausel erfüllt, dann A=1 (zweiter Knoten des Suchbaums)
fahren Sie mit der zweiten Klausel fort und wählen die erste unzugewiesene Variable (C) und setzen sie so, dass sie die Klausel erfüllt, was bedeutet, dass C=0 (dritter Knoten links)
wir tun dasselbe für die vierte Klausel (B v A' v C) und setzen B auf 1
wir versuchen dasselbe für die letzte Klausel, müssen jedoch feststellen, dass wir keine unzugewiesenen Variablen mehr haben und die Klausel immer falsch ist. Dann müssen wir in den vorherigen Teil des Suchbaums zurückgehen. Wir ändern den Wert, den wir B zugewiesen haben, und setzen B auf 0. Dann suchen wir nach einem anderen unzugewiesenen Wert, der die dritte Klausel erfüllen kann, aber es gibt keinen. Dann müssen wir wieder zum zweiten Knoten zurückkehren
Dort müssen wir die Zuweisung der ersten Variablen (C) umkehren, damit sie die Klausel nicht erfüllt, und die nächste unzugewiesene Variable (D) so setzen, dass sie diese erfüllt (d.h. C=1 und D=1). Dies erfüllt auch die dritte Klausel, die C enthält.
Die letzte zu erfüllende Klausel (C' v A' v B') hat eine unzugewiesene Variable B, die dann auf 0 gesetzt werden kann, um die Klausel zu erfüllen.
In diesem Link http://lowcoupling.com/post/72424308422/a-simple-3-sat-solver-using-dpll finden Sie auch den Python-Code zur Implementierung