DPLL算法
DPLL算法是一种判断逻辑语句(CNF)是否可满足的算法。
实际上也是枚举算法,即改进的真值表枚举算法。首先找到纯符号、递归,再找单元子句、递归,最后去除了纯符号和单元子句后的语句进行枚举。思想是只要部分符号有效就可以推导出语句有真值,而不需要讨论全部符号。
比枚举算法的改进
①、及早终止算法:
如果其中任意一个文字为真则一个子句是真;如果搜索的文字都为假则一个子句为假
②、纯符号启发式:
纯符号是某个文字在所有的子句中都是正或者负(只有一种情况)。找到纯符号可以通过对纯符号的赋值使语句为真,即只要进行一次赋值就可以把带有纯符号的所有子句全部消掉。纯符号可以优先进行赋值。
③、单元子句启发式:
单元子句是指子句中除了某个文字外其他文字都是假的子句。可知单元子句中的文字必须为真。单元子句可以优先进行赋值,需要已知某个值为真。
注意,伪代码中的renturn中的连接词是or而不是and,因为验证的是可满足性,只要找到一条即可,如果是and是验证所有的即验证有效性。
时间复杂度为2^n
walksat算法
判断是否可满足
和爬山法类似,是不完整的局部搜索算法
评估函数是最小化不满足的子句数量(可理解为当前有几个子句为真)
加入随机概率P进行反转后就属于一种典型的模拟退火算法
接近线性时间复杂度,与命题个数有关
步骤:
①、随机生成一个模型(对变量赋值)
②、考察子句的真假情况
③、考察他的邻近状态(对某一个变量的值进行翻转,注意设置一个最大的翻转次数),考察邻近状态下的子句的真假情况
④、跳转到评估函数最好的邻近状态,继续
⑤、可以加入一个概率导致对某一个变量随机发生翻转,从而实现退火
过约束问题:使得语句得到满足的模型数量很少且很可能无解,设置m/n,m为子句的数目,n为变量的数目,这个指标越小越容易满足。