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

  • 从零开始编写SAT求解器(一)
    • 源起
    • 背景知识
      • SAT问题
      • DIMACS文件
      • DPLL算法
    • 项目架构

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

源起

最近在github上看到了非常有名的cryptominisat开源项目。目前的SAT问题自动求解器有在线版的MiniSAT,但是这个需要科学上网。正好最近一直在写Java和python,C++有点生疏,而网上有大神用Haskell实现了简易的SAT求解器,就想用C++写一个自己的SAT求解器。(C++是最棒的语言)

背景知识

SAT问题

SAT问题是布尔可满足性问题(又名命题可满足性问题)的缩写,即给定一个布尔公式,判断是否存在满足它的解释的问题。SAT问题是第一个被证明的NP问题。这里,我把问题简化为:输入一个析取范式(CNF),输出一个布尔值表示它是否是可满足的,若它是可满足的,再输出一个使它为真的解释。

DIMACS文件

DIMACS文件是对于CNF形式的命题公式的一种简单的ASCII表示,它的结构为:

  • 开头是几行注释,以字符’c’开头
  • 注释行之后,是一个文件头,格式为p cnf nvars nclauses,这里nvars是公式中变量的数量,nclauses是命题中子句的数量
  • 在文件头之后,每一行代表一个子句。一个子句是一系列空格分隔的非零整数,最后以0结尾。一个正数代表对应的变量(从1到nvars),一个负数代表对应变量的非。

举个例子:

 c A simple examplep cnf 3 3-1 2 0-2 3 0-1 -3 0

它代表的公式是
(¬P1∨P2)∧(¬P2∨P3)∧(¬P1∨¬P3)(\neg{P_1}\vee{P_2})\wedge(\neg{P_2}\vee{P_3})\wedge(\neg{P_1}\vee{\neg{P_3}})(¬P1​∨P2​)∧(¬P2​∨P3​)∧(¬P1​∨¬P3​)

DPLL算法

DPLL算法是一个判断命题公式可满足性的算法,本质上是一个深度优先搜索算法。基本思想为:首先假定一个变量的值(真/假),然后检查当前条件下命题公式是否为真,若为真,程序退出,返回可满足以及一个使命题公式为真的解释;若为假,则回溯(可能改变当前变量的假定值,或退到之前的某个变量);若为假且没有变量可以回溯,程序退出,返回该公式是不可满足的。

项目架构

main函数如下:

#include <chrono>#include "common.h"
#include "DimacsParser.h"
#include "DPLL.h"int main(int argc, char **argv) {//argc=2;if (argc < 2) {std::cerr << "error: no input files" << std::endl;return 1;}for (int i = 1; i < argc; i++) {std::string f(argv[i]);//std::string f="tests\\test5.dimacs";std::cout << f << std::endl;formula phi = DimacsParser::parse(f);// timer startauto start = std::chrono::steady_clock::now();DPLL solver(phi);bool sat = solver.check_sat();model m;if (sat) {m = solver.get_model();}auto end = std::chrono::steady_clock::now();// timer endif (sat) {std::cout << "  sat" << std::endl;for (const auto &p : m) {std::cout << "    " << p.first << " -> " << p.second << std::endl;}} else {std::cout << "  unsat" << std::endl;}auto duration = std::chrono::duration_cast<std::chrono::duration<double>>(end - start);std::cout << "  time: " << duration.count() << std::endl;}return 0;
}

采用命令行输入,首先判断参数合法性,若合法,读入文件,将文件解析,返回自定义的formula对象。接着调用DPLL方法,返回是否可解;若可解,输出一个可行的解。可行解使用map存储。
那么,接下来的任务就是实现文件解析、DPLL核心算法。

从零开始编写SAT求解器(一)相关推荐

  1. windows下编译以及运行cryptominisat 求解器(sat求解器)

    cryptominisat是由msoos所开发的一款sat求解器,sat的具体问题另外一篇博客里有详细介绍点击打开链接,本篇文章只介绍如何在windows下运行cryptominisat,将自己遇到的 ...

  2. sat求解器解哈密顿回路

    资料:https://ozanerdem.github.io/jekyll/update/2019/11/17/representation-in-sat.html https://modref.gi ...

  3. 基于DPLL的SAT求解器

    SAT问题 什么是SAT问题? SAT问题即命题逻辑公式的可满足性问题(satisfiability problem),是计算机科学与人工智能基本问题,是一个典型的NP完全问题. 对于任一布尔变元x, ...

  4. Flow Free solver[连线游戏求解器]

    Fast automated solver for Flow Free puzzles written in C.  用C语言编写的连线游戏的快速自动求解器. GIF of the final pro ...

  5. JAX-FLUIDS:可压缩两相流的完全可微高阶计算流体动力学求解器

    原文来自微信公众号"编程语言Lab":论文精读 | JAX-FLUIDS:可压缩两相流的完全可微高阶计算流体动力学求解器 搜索关注"编程语言Lab"公众号(HW ...

  6. 2-2 组合优化问题-常用模型与通用求解器

    组合优化问题常用模型 组合优化问题常常难以求解,我们可以把这些转化为目前已经有成熟求解器的模型. 1. 可满足性问题(Satisfiability, SAT) 上一节已经讲过,SAT 是一个 NPC ...

  7. 开尔文函数 matlab,KELVIN二维/ RS传热求解器

    原标题:KELVIN二维/ RS传热求解器 本文由中国科学软件网翻译整理 KELVIN是一款2D/RS热分析工具,使用图形和轮廓,剖面图和箭头图显示温度.热流密度和温度梯度.探索一切省时省时.性价比高 ...

  8. 强化学习 求解迷宫问题_使用天真强化学习的迷宫求解器

    强化学习 求解迷宫问题 This is a short maze solver game I wrote from scratch in python (in under 260 lines) usi ...

  9. matlab 读取图片后分区域编号_你的第一个有限元求解器——仅十行MATLAB代码

    有限元分析话题中有不少讨论有限元求解器的问题,但大都停留在概念层面,未见实际代码.望本文能略起抛砖引玉之作用. 以下代码是基于MATLAB编写. 问题描述 考虑一平面有界区域 ,设其边界为 .我们求解 ...

最新文章

  1. Linux 的内存管理工具和调优参数
  2. 使用Android Studio搭建Android集成开发环境
  3. 重新分区_手机DATA重新分区教程(超详细)
  4. Docker 安装JDK1.8
  5. 糟糕!HttpClient 连接池设置引发的一次雪崩!
  6. 视频格式转换工具使用
  7. Android RelativeLayout和LinearLayout性能分析
  8. FileFilter过滤器的原理和使用
  9. CloudCC:2017年下半年企业移动CRM市场风向窥测
  10. PHP危险函数被禁止怎么绕过,PHP危险函数(disable_functions)设置
  11. ajax卡死new formdata(),使用FormData和jQuery上传Ajax大文件无法发布数据
  12. SQL Sever 数据完整性
  13. 云更新网吧系统服务器,云更新网吧服务器环境要求
  14. YOLOX安装及训练
  15. JAVA串口通信开发
  16. 数实融合激变时刻,与长期主义同行
  17. eyebeam电话呼叫软件使用及配置方法
  18. 剑指Offer——京东实习笔试题汇总
  19. 以后你们就要给张一鸣还“花呗”了
  20. 基于Docker-compose搭建Redis高可用集群-哨兵模式(Redis-Sentinel)

热门文章

  1. Axure RP 8 闪退问题解决方案
  2. 力扣45跳跃游戏II(难)JAVA
  3. Java子类访问父类私有变量的思考
  4. boostrap老黄历代码的实现
  5. [从源码学设计]蚂蚁金服SOFARegistry之时间轮的使用
  6. 谈一谈数据如何到知识以及DIKW模型的应用
  7. QComboBox 输入后捕获enter键
  8. 小体积台式计算机,全新碉堡小体积台式电脑T09尽显商务范
  9. 破10亿用户的支付宝给支付生态的启示
  10. 黑马程序员 网络编程2