Algorithm DPLL算法定义

Algorithm DPLL算法定义,algorithm,artificial-intelligence,Algorithm,Artificial Intelligence,我在理解DPLL算法时遇到了一些问题,我想知道是否有人可以向我解释,因为我认为我的理解是错误的 我理解它的方式是,我取一些文本集,如果某个子句为真,则模型为真,但如果某个子句为假,则模型为假 我通过查找unit子句递归地检查模型,如果有,我设置unit子句的值使其为真,然后更新模型。删除所有现在为true的子句并删除所有现在为false的文本 当没有留下任何单位子句时,我选择任何其他文本并为该文本赋值,使其为真,使其为假,然后再次删除所有现在为真的子句和所有现在为假的文本。DPLL要求以析取范式

我在理解DPLL算法时遇到了一些问题,我想知道是否有人可以向我解释,因为我认为我的理解是错误的

我理解它的方式是,我取一些文本集,如果某个子句为真,则模型为真,但如果某个子句为假,则模型为假

我通过查找unit子句递归地检查模型,如果有,我设置unit子句的值使其为真,然后更新模型。删除所有现在为true的子句并删除所有现在为false的文本


当没有留下任何单位子句时,我选择任何其他文本并为该文本赋值,使其为真,使其为假,然后再次删除所有现在为真的子句和所有现在为假的文本。

DPLL要求以析取范式说明问题,即作为一组子句,每一项都必须得到满足

每个子句都是一组字面值
{l1,l2,…,ln}
,表示这些字面值的析取(即,至少有一个字面值必须为true才能满足子句的要求)

每个文本
l
断言某个变量为真(
x
)或为假(
~x

如果子句中的任何文字为真,则满足该子句

如果一个子句中的所有文字都为false,则该子句是不可满足的,因此问题是不可满足的

解决方案是将真/假值分配给变量,以便满足每个子句。DPLL算法是针对此类解决方案的优化搜索

DPLL本质上是一种在三种策略之间交替进行的深度优先搜索。在搜索的任何阶段都有部分赋值(即,将值赋值给变量的某个子集)和一组未确定的子句(即,尚未满足的子句)

(1) 第一种策略是纯文字消除:如果未赋值变量
x
仅以其正形式出现在未确定子句集中(即,文字
~x
不出现在任何地方),那么我们可以将
x=true
添加到赋值中,并满足包含文字
x
的所有子句(类似地,如果
x
仅以负数形式出现,
~x
,我们可以将
x=false
添加到作业中)

(二)第二种策略是单元传播:如果一个未决定子句中除了一个以外的所有文本都是false,那么剩下的一个必须是true。如果剩下的文本是
x
,我们将
x=true
添加到赋值中;如果剩下的文本是
~x
,我们将
x=false
添加到赋值中。这个赋值可以为单位传播带来更多机会

(3) 第三种策略是简单地选择一个未赋值变量
x
并分支搜索:一方尝试
x=true
,另一方尝试
x=false

如果在任何时候,我们以一个不可满足的条款结束,那么我们已经到达了一个死胡同,必须回溯

有各种各样聪明的进一步优化,但这是几乎所有SAT解算器的核心


希望这能有所帮助。

Davis–Putnam–Logemann–Loveland(DPLL)算法是一种基于回溯的搜索算法,用于确定合取范式中命题逻辑公式的可满足性,也称为可满足性问题或SAT

任何布尔公式都可以用合取范式(CNF)表示,这意味着子句的合取,即(…)^(…)^(…)

其中,子句是布尔变量的析取,即(a v B v C’v D)

以CNF表示的布尔公式示例如下:

(A v B v C)^(C'v D)^(D'v A)

解决SAT问题意味着在公式中找到满足它的变量值的组合,比如A=1,B=0,C=0,D=0

这是一个NP完全问题。实际上,这是Stepehn Cook和Leonid Levin证明的第一个NP完全问题

SAT问题的一种特殊类型是3-SAT,这是一种所有子句都有三个变量的SAT

DPLL算法是解决SAT问题(实际上取决于输入的硬度)的一种方法,它递归地创建一个潜在解决方案树

假设你想解决这样一个3-SAT问题

(A v B v C)(C'v D v B)(B v A'v C)(C'v A'v B))

如果我们枚举A=1 B=2 C=3 D=4这样的变量,并为A'=-1这样的负数,那么同样的公式也可以用Python编写,如下所示

[1,2,3],-3,4,2],[2,-1,3],-3,-1,-2]]

现在设想创建一棵树,其中每个节点由一个部分解组成。在我们的示例中,我们还描述了该解满足的子句向量

根节点是[-1,-1,-1,-1],这意味着尚未为变量0或1分配任何值

在每次迭代中:

  • 那么,我们接受第一个不满意的条款

  • 如果没有更多的未分配变量可以用来满足该子句,那么在搜索树的这个分支中就不会有有效的解,算法将返回无

  • 否则,我们取第一个未赋值变量,并将其设置为满足子句,然后从步骤1递归开始。如果算法的内部调用返回None,我们翻转变量的值,使其不满足子句,并设置下一个未赋值变量以满足子句。如果所有三个变量已尝试les,或者该子句没有更多未分配变量,这意味着该分支中没有有效的解决方案,算法将返回None

  • 请参见以下示例:

    我们从根节点选择第一个子句(avb)的第一个变量(A)