我无法理解用于检查命题逻辑中句子的可满足性的DPLL算法。
http://books.google.co.in/books?id=4fyShrIFXg4C&pg=PA250&lpg=PA250&dq=DPLL+algorithm+from+artificial+intelligence+A+modern+approach&source=bl&ots=oOoZsT8KFd&sig=pdmyUsQZZWw76guWY9eFJKyNsH0&hl=en&sa=X&ei=vBFeUOf1EMLrrQeanoG4DQ&ved=0CD0Q6AEwAw#v=onepage&q&f=false
该算法摘自人工智能现代方法。我发现这很多功能递归真的很混乱。特别是EXTEND()
函数做了什么,递归调用DPLL()
背后的目的是什么?
答案 0 :(得分:16)
DPLL本质上是回溯算法,这是递归调用背后的主要思想。
该算法正在尝试分配时构建解决方案,您有一个部分解决方案,可能会在您继续时成功或不成功。算法的天赋是如何构建部分解决方案。
首先,让我们定义单位子句是什么:
单元子句是一个子句,它只有一个文本仍然是未分配的,而另一个(赋值的)文字 - 都被赋值为false。
该子句的重要性在于,如果当前赋值有效 - 您可以确定未赋值的文字中变量的值是什么 - 因为文字必须为真。
例如:如果我们有一个公式:
(x1 \/ x2 \/ x3) /\ (~x1 \/ ~x4 \/ x5) /\ ( ~x1 \/ x4)
我们已经分配了:
x1=true, x4=true
然后(~x1 \/ ~x4 \/ x5)
是一个单元子句,因为您必须指定x5=true
才能在当前的部分赋值中满足此子句。
该算法的基本思想是:
<强>终止:强>
您还可以查看these lecture slides以获取更多信息和示例。 (忽略第一张希伯来语幻灯片,接下来都是英语;你可能也想忽略最后的“学习”,直到你更好地理解基础知识)
用法示例和重要性:
虽然50岁的DPLL仍然是大多数SAT解决者的基础。
SAT求解器对于解决难题非常有用,例如软件验证中的一个例子 - 您将模型表示为一组公式,以及您要验证的条件 - 并通过它调用SAT求解器。虽然指数最坏的情况 - 平均情况足够快并且在业界广泛使用(主要用于验证硬件组件)
答案 1 :(得分:4)
我会注意到DPLL中使用的技术是复杂性理论中的证明中使用的常用技术,在这里你猜测对事物进行部分分配,然后尝试填写其余的。有关DPLL为何如此工作的更多参考或灵感,您可以尝试阅读一些围绕SAT的复杂性理论材料(在任何关于复杂性理论的优秀教科书中)。
使用DPLL“现成”实际上会导致一个非常糟糕的解决方案,并且有一些关键技巧可以让你做得更好!与Amit的答案一起,我将提供一些实用的参考资料来理解DPLL的实际工作原理:
{x1,...,xn}
的公式,您会发现DPLL算法将更快地终止(在公式 可满足的情况下)取决于您选择哪个变量。您还会发现选择正确(显然)更有帮助。因此,从理论的角度来看,SAT是一个非常重要的问题(通过Karp的第一次NP完全减少,任何复杂性书籍将引入的有趣且繁琐的建设性技术),但也非常实用模型检查和软件验证中的应用程序。如果您对如何快速解决NP完全问题的经典示例感兴趣,请看看工业强度SAT求解器的实现,这很有趣!