博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从零开始编写SAT求解器(三)
阅读量:4170 次
发布时间:2019-05-26

本文共 3109 字,大约阅读时间需要 10 分钟。

从零开始编写SAT求解器(三)

从零开始编写SAT求解器(三)

核心算法:DPLL

//DPLL.cpp#include "DPLL.h"bool DPLL::check_sat() {
// TODO: your code here, or in the header file std::unordered_map
atomStatus;//记录节点状态0,1,2 int clause_num = phi.clauses.size();//子句数量 int atomNum = phi.num_variable;//变量数量 for(int i=1;i<=atomNum;i++) result.insert(std::make_pair(i,true)); int* nodeStatus = new int[atomNum]; for(int i=0;i
0&&nodeStatus[ptr]==2) ptr--; for(int i=ptr+1;i
result;}

其基本流程我举个例子:

假设五个变量A,B,C,D,E
我先假定A取真,其他的不确定,然后我检查输入的CNF是否为真
如果是真,那太好了,返回退出
如果不确定,那我再假定B取真,再检查
如果是假,那么回溯/取另外一个值
怎么回溯:
再举个例子:
假如ABCDE分别是1,1,1,1,null,这时发现CNF为假!
现在指针指向的是D,所以从D取另外的值,此时ABCDE分别为1,1,1,0,null
发现还是不行,CNF为假,这时就要回溯,回溯到哪?递归的搜索当前节点的父亲,直到找到这样一个节点,它还有没有取到的值(也就是说它没“脏”),或者到根节点(此时如果根节点为“脏”,证明所有情况搜索完毕,输入的CNF是不可满足的)。
回溯完成后,注意,在当前节点以下的所有节点,它们的状态都被重新标记为“干净”,也就是它们既没有取过真值,也没有取过假值,因为它们的父节点状态发生了变化,相当于它们即使与之前取同样的布尔值,ABCDE作为一个整体,这五个布尔值的组合也与之前不同。

其他文件

common.h:

#include 
#include
#include
#include
#ifndef DPLL_COMMON_H#define DPLL_COMMON_H// A literal is a atomic formula (that contains a variable). Like in dimacs,// + positive numbers denote the corresponding variables;// - negative numbers denote the negations of the corresponding variables.// Variables are numbered from 1.typedef int literal;#define POSITIVE(x) ((x) > 0)#define NEGATIVE(x) ((x) < 0)#define VAR(x) (((x) > 0) ? (x) : (-(x)))// A clause is a list of literals (meaning their disjunction).typedef std::vector
clause;// A formula is a list of clauses (meaning their conjunction).// We also specify the total number of variables, as some of them may not occur in any clause!struct formula {
int num_variable; std::vector
clauses; formula(int n, const std::vector
& clauses): num_variable(n), clauses(clauses) { }};// A satisfying model (interpretation).// e.g. `model[i] = false` means variable `i` is assigned to false.typedef std::unordered_map
model;#endif //DPLL_COMMON_H

DPLL.h:

#ifndef DPLL_DPLL_H#define DPLL_DPLL_H#include "common.h"class DPLL {
public: DPLL(const formula &phi) : phi(phi) {
} bool check_sat(); model get_model();private: formula phi; model result;};#endif //DPLL_DPLL_H

CMakeLists.txt:

# cmake_minimum_required(VERSION 
)cmake_minimum_required(VERSION 3.15)project(dpll)set(CMAKE_CXX_STANDARD 17)set(CMAKE_BUILD_TYPE "Debug")set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O2 -Wall")add_executable(dpll main.cpp DimacsParser.h common.h DPLL.cpp DPLL.h common.h DPLL.h DimacsParser.h)

测试效果

输入:

c Generated with `cnfgen`c (C) 2012-2016 Massimo Lauria 
c https://massimolauria.github.io/cnfgencp cnf 12 321 -2 0-1 2 01 3 4 01 -3 -4 0-1 3 -4 0-1 -3 4 03 -5 0-3 5 02 6 -7 02 -6 7 0-2 6 7 0-2 -6 -7 04 6 8 -9 04 6 -8 9 04 -6 8 9 04 -6 -8 -9 0-4 6 8 9 0-4 6 -8 -9 0-4 -6 8 -9 0-4 -6 -8 9 05 8 -10 05 -8 10 0-5 8 10 0-5 -8 -10 07 11 0-7 -11 09 11 -12 09 -11 12 0-9 11 12 0-9 -11 -12 010 -12 0-10 12 0

输出:

在这里插入图片描述

转载地址:http://yywai.baihongyu.com/

你可能感兴趣的文章
Sqlite 管理工具 SQLiteDeveloper及破解
查看>>
IOS设置UIView的边框为圆角
查看>>
UIView CALayer 属性不显示错误 Property cannot be found in forward class object 'CALayer
查看>>
UIView和CALayer的区别
查看>>
iOS动画效果和实现
查看>>
把两台电脑直连实现高速访问
查看>>
IOS icon的尺寸
查看>>
win7下计划任务schtasks使用详解及"错误:无法加载列资源"的解决方法
查看>>
windows下cmd命令行显示UTF8字符设置(CHCP命令)
查看>>
使用Batch_Compiler把bat,cmd命令行转成exe
查看>>
使用rsa算法制作license时出现IBM JDK 公钥解密错误
查看>>
Android中引入第三方Jar包的方法(java.lang.NoClassDefFoundError解决办法)
查看>>
没有调试日志的问题 Unable to open log device ‘/dev/log/main’: No such file or directory
查看>>
调用android系统相机拍照并保存
查看>>
android intent和intent action大全
查看>>
CentOS 网络设置修改
查看>>
Centos搭建SVN服务器三步曲
查看>>
VMware-Workstation-6.5.1-126130.x86_64.bundle 安装卸载
查看>>
centos 安装 virtualbox
查看>>
CentOS下设置MySQL的root密码
查看>>