2-SAT适定性(Satisfiability)问题知识点详解

SAT是适定性(Satisfiability)问题的简称。一般形式为k-适定性问题,简称 k-SAT。而当k>2时该问题为NP完全的,所以我们只研究k=2时情况。

2-SAT问题

现有一个由N个布尔值组成的序列A,给出一些限制关系,比如A[x] AND A[y]=0、A[x] OR A[y] OR A[z]=1等,要确定A[0…N-1]的值,使得其满足所有限制关系。这个称为SAT问题,特别的,若每种限制关系中最多只对两个元素进行限制,则称为2-SAT问题。通俗来说就是有一些集合,每个集合中有且仅有两个元素,且不能同时选取两个元素,集合间的元素存在一定的选择关系,求解可行性及可行方案。

由于在2-SAT问题中,最多只对两个元素进行限制,所以可能的限制关系共有11种:
注意:
这里的OR是指两个条件至少有一个是正确的
比如x1和x2一共有三种组合满足“x1为真或x2为假”:
x1=1,x2=1
x1=1,x2=0
x1=0,x2=0
A[x]
NOT A[x]
A[x] AND A[y]
A[x] AND NOT A[y]
A[x] OR A[y]
A[x] OR NOT A[y]
NOT (A[x] AND A[y])
NOT (A[x] OR A[y])
A[x] XOR A[y]
NOT (A[x] XOR A[y])
A[x] XOR NOT A[y]
进一步,A[x] AND A[y]相当于(A[x]) AND (A[y])(也就是可以拆分成A[x]与A[y]两个限制关系),NOT(A[x] OR A[y])相当于NOT A[x] AND NOT A[y](也就是可以拆分成NOT A[x]与NOT A[y]两个限制关系)。因此,可能的限制关系最多只有9种。

首先我们考虑将2-SAT问题往图论的方向靠,我们发现每个点要么取0,要么取1。因此对于ai,我们建两个点2i−1与2i分别表示ai取0和1

然后我们考虑建边来表示这些关系,我们令一条有向边的意义:x→y表示如果选择了x就必须选y

那么我们可以举一些简单的例子来总结下连边的规律(用i′表示i的反面):

i,j不能同时选:选了i就要选j′,选j就要选i′。故i→j′,j→i′。一般操作即为aixoraj=1
i,j必须同时选:选了i就要选j,选j就要选i。故i→j,j→i。一般操作即为aixoraj=0
i,j任选(但至少选一个)选一个:选了i就要选j′,选j就要选i′,选i′就要选j,选j′就要选i。故i→j′,j→i′,i′→j,j′→i。一般操作即为aioraj=1
i必须选:直接i′→i,可以保证无论怎样都选i。一般操作为给出的ai=1或aiandaj=1
建好图然后就是考虑怎么用图论的方式解决2-SAT了。

在实际问题中,2-SAT问题在大多数时候表现成以下形式:有N对物品,每对物品中必须选取一个,也只能选取一个,并且它们之间存在某些限制关系(如某两个物品不能都选,某两个物品不能都不选,某两个物品必须且只能选一个,某个物品必选)等,这时,可以将每对物品当成一个布尔值(选取第一个物品相当于0,选取第二个相当于1),如果所有的限制关系最多只对两个物品进行限制,则它们都可以转化成9种基本限制关系,从而转化为2-SAT模型。

【建模】

其实2-SAT问题的建模是和实际问题非常相似的。
建立一个2N阶的有向图,其中的点分为N对,每对点表示布尔序列A的一个元素的0、1取值(以下将代表A[i]的0取值的点称为i,代表A[i]的1取值的点称为i’)。显然每对点必须且只能选取一个。然后,图中的边具有特定含义。若图中存在边<i, j>,则表示若选了i必须选j。可以发现,上面的9种限制关系中,后7种二元限制关系都可以用连边实现,比如NOT(A[x] AND A[y])需要连两条边<x, y’>和<y, x’>,A[x] OR A[y]需要连两条边<x’, y>和<y’, x>。而前两种一元关系,对于A[x](即x必选),可以通过连边<x’, x>来实现,而NOT A[x](即x不能选),可以通过连边<x, x’>来实现。

【O(NM)算法:求字典序最小的解】

算法 1、连边

2、跑tarjan

3、判可行性,即同一集合中的两个点是否同属一个强连通块

4、缩点建新图,连反边

5、拓扑序,若当前点没有被访问过,则选择该点,不选择其另外的点

连边 2-SAT算法本身并不难,关键是连边,不过只需要充分理解好边的概念:a->b即选a必选b。

a、b不能同时选:选了a就要选b’,选了b就要选a’。

a、b必须同时选:选了a就要选b,选了b就要选a,选了a’就要选b’,选了b’就要选a’。

a、b必须选一个:选了a就要选b’,选了b就要选a’,选了a’就要选b,选了b’就要选a。

※a必须选:a’->a。

根据2-SAT建成的图中边的定义可以发现,若图中i到j有路径,则若i选,则j也要选;或者说,若j不选,则i也不能选;
因此得到一个很直观的算法:
(1)给每个点设置一个状态V,V=0表示未确定,V=1表示确定选取,V=2表示确定不选取。称一个点是已确定的当且仅当其V值非0。设立两个队列Q1和Q2,分别存放本次尝试选取的点的编号和尝试不选的点的编号。
(2)若图中所有的点均已确定,则找到一组解,结束,否则,将Q1、Q2清空,并任选一个未确定的点i,将i加入队列Q1,将i’加入队列Q2;
(3)找到i的所有后继。对于后继j,若j未确定,则将j加入队列Q1;若j’(这里的j’是指与j在同一对的另一个点)未确定,则将j’加入队列Q2;
(4)遍历Q2中的每个点,找到该点的所有前趋(这里需要先建一个补图),若该前趋未确定,则将其加入队列Q2;
(5)在(3)(4)步操作中,出现以下情况之一,则本次尝试失败,否则本次尝试成功:
<1>某个已被加入队列Q1的点被加入队列Q2;
<2>某个已被加入队列Q2的点被加入队列Q1;
<3>某个j的状态为2;
<4>某个i’或j’的状态为1或某个i’或j’的前趋的状态为1;
(6)若本次尝试成功,则将Q1中的所有点的状态改为1,将Q2中所有点的状态改为2,转(2),否则尝试点i’,若仍失败则问题无解。
该算法的时间复杂度为O(NM)(最坏情况下要尝试所有的点,每次尝试要遍历所有的边),但是在多数情况下,远远达不到这个上界。
具体实现时,可以用一个数组vst来表示队列Q1和Q2。设立两个标志变量i1和i2(要求对于不同的i,i1和i2均不同,这样可以避免每次尝试都要初始化一次,节省时间),若vst[i]=i1则表示i已被加入Q1,若vst[i]=i2则表示i已被加入Q2。不过Q1和Q2仍然是要设立的,因为遍历(BFS)的时候需要队列,为了防止重复遍历,加入Q1(或Q2)中的点的vst值必然不等于i1(或i2)。中间一旦发生矛盾,立即中止尝试,宣告失败。

该算法虽然在多数情况下时间复杂度到不了O(NM),但是综合性能仍然不如下面的O(M)算法。不过,该算法有一个很重要的用处:求字典序最小的解!
如果原图中的同一对点编号都是连续的(01、23、45……)则可以依次尝试第0对、第1对……点,每对点中先尝试编号小的,若失败再尝试编号大的。这样一定能求出字典序最小的解(如果有解的话),因为一个点一旦被确定,则不可更改。
如果原图中的同一对点编号不连续(比如03、25、14……)则按照该对点中编号小的点的编号递增顺序将每对点排序,然后依次扫描排序后的每对点,先尝试其编号小的点,若成功则将这个点选上,否则尝试编号大的点,若成功则选上,否则(都失败)无解。

推荐博客

1> https://blog.csdn.net/jarjingx/article/details/8521690
2> https://www.cnblogs.com/kangkang-/p/11370313.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/309788.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

温故知新:Docker基础知识知多少?

【云原生】| 作者/Edison Zhou这是恰童鞋骚年的第233篇原创文章记得之前曾经粗略的写过一篇Docker的基础及ASP.NET Core部署Docker示例的入门文章&#xff0c;但那个时候刚刚学习对Docker的认知还比较浅&#xff0c;现在重新来温故知新一下。本文预计阅读时间为10min。1容器的用…

自动备份html文件,windows下定期自动备份本地文件(文件夹)

虽然网上有一些免费的文件自动备份软件&#xff0c;但是没有自己编写一段批处理来完成备份任务来的放心&#xff0c;而且不用占用系统资源。就给大家讲一下如何利用批处理完成本地文件或者文件夹的备份。1、批处理脚本该方法可把某文件夹下的文件同步到另外的文件夹&#xff0c…

Dreamoon and Ranking Collection CodeForces - 1330A (贪心)

题意&#xff1a; 大意就是给一个序列&#xff0c;可能有重复数字&#xff0c;有x次机会为这个序列填上一个数字&#xff0c;问最终从里面获得的1~v连续子序列的v最大是多少。 题目: Dreamoon is a big fan of the Codeforces contests. One day, he claimed that he will …

[C++11]lambda表达式语法

代码如下: #include <iostream> using namespace std;void func(int x, int y) {int a;int b;[]() {int c a;//使用了外部变量&#xff0c;[]里面加个 int d x;}; }int main() {return 0; }lambda表达式的注意事项: 以上图片来自下面链接: https://subingwen.cn/cpp…

[翻译]欢迎使用C#9.0

本文由公众号[开发者精选资讯](微信号&#xff1a;yuantoutiao)翻译首发&#xff0c;转载请注明来源C# 9.0 is taking shape, and I’d like to share our thinking on some of the major features we’re adding to this next version of the language.C&#xff03;9.0初具规…

android环境搭建出错,androidstudio配置环境遇到的各种错误(持续更新中)

AndroidStudio3.0,gradle4.1&#xff0c;新建工程&#xff0c;遇到如下错误&#xff1a;Error:Unable to resolve dependency for :appdebugAndroidTest/compileClasspath: Could not resolve com.android.support.test:runner:1.0.1.Error:Unable to resolve dependency for :…

操作系统第四章习题

操作系统第四章习题 1.对一个将页表放在内存中的分页系统&#xff1a; (1) 如果访问内存需要0.2μs&#xff0c;有效访问时间为多少? (2) 如果加一快表&#xff0c;且假定在快表中找到页表的几率高达90%&#xff0c;则有效访问时间又是多少&#xff08;假定查快表需花的时间…

[C++11]右值和右值引用

代码如下: #include <iostream> using namespace std;int main() {//左值int num 9;//左值引用int &a num;//右值const int N 5;//右值引用int && b 8;//常量左值引用const int &c num;//常量右值引用const int &&d 6;//const int &&…

用html写出生日蛋糕,纯HTML5+CSS3制作生日蛋糕代码

.birthday .container{width:600px;height:600px;margin:0px auto;background: #fafafa;border-radius:5px;position: relative;}/**** 顶层的**/.birthday .top-one{position: absolute;width:280px;height: 280px;bottom: 200px;left:160px;}.birthday .top-one .bottom{posi…

我们为什么推荐在Json中使用string表示Number属性值

在这篇简短的文章中&#xff0c;我将解释在使用JSON传输数据时&#xff0c;为什么浮点数或大十进制值应表示为字符串 。long类型引发的诡异情况长话短说&#xff0c;同事在利用swagger对接后端API时&#xff0c;诡异的发现swaggerUI中显示的json属性值并不是api返回的值。[Http…

并查集+基础知识点详解

并查集概念 并查集单看名字大家也能猜到这个算法的作用&#xff0c;是用来对集合进行合并和查找操作 并查集是一种树型的数据结构&#xff0c;用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。——来自百度百科 就是将原本不一样的集合&#xff0c;但是由于某种关系有…

[C++11]move资源的转移

从实现上讲&#xff0c;std::move 基本等同于一个类型转换&#xff1a;static_cast<T&&>(lvalue);&#xff0c;函数原型如下: template<class _Ty> _NODISCARD constexpr remove_reference_t<_Ty>&& move(_Ty&& _Arg) _NOEXCEPT { …

网址导航html5源码图标版,最新仿hao123网址导航(晓风网址导航系统) v4.2

使用说明 采用aspaccess架构&#xff0c;简单易用 access数据库已做防下载处理&#xff0c;安全放心 程序不能放到子目录&#xff0c;否则无法生成全站 上传程序进入后台设置一下网站信息&#xff0c;生成所有HTML页面 首页网站标志LOGO目录位置&#xff1a;/images/logo_140.g…

基于 abp vNext 和 .NET Core 开发博客项目 - 统一规范API,包装返回模型

上一篇文章使用自定义仓储完成了简单的增删改查案例&#xff0c;有心的同学可以看出&#xff0c;我们的返回参数一塌糊涂&#xff0c;显得很不友好。在实际开发过程中&#xff0c;每个公司可能不尽相同&#xff0c;但都大同小异&#xff0c;我们的返回数据都是包裹在一个公共的…

奔小康赚大钱 HDU - 2255( 二分图匹配KM算法详解)

题目 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革&#xff1a;重新分配房子。 这可是一件大事,关系到人民的住房问题啊。村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住&#xff08;如果有老百姓没房子住的话&#xff0c;容易引起不安定因素&…

记一次排查线上程序内存的忽高忽低,又是大集合惹祸了

一&#xff1a;背景1. 讲故事昨天继续还技术债&#xff0c;优化一轮后的程序拉到线上后内存继续忽高忽低&#xff0c;低的时候20G&#xff0c;高的时候30G&#xff0c;过了一会又下降了几个G&#xff0c;毫无疑问&#xff0c;程序中有什么集合或者什么操作占用了大量内存&#…

[C++11]forward完美转发

// 函数原型 template <class T> T&& forward (typename remove_reference<T>::type& t) noexcept; template <class T> T&& forward (typename remove_reference<T>::type&& t) noexcept;// 精简之后的样子 std::forward…

广州计算机专业王健,王健-计算机与信息工程学院

2.在国内外公开发行刊物上发表的学术论文(1)Jian Wang. A Novel K-NN Classification Algorithm for Privacy Preserving in Cloud Computing. Research Journal of Applied Sciences, Engineering and Technology, Vol. 4, Issue: 22, 2012 (EI源刊).(2)Jian Wang. Experimen…

Pipe HDU - 2150(判断线段相交+向量叉乘线代详解)

题目&#xff1a; 经过激烈的争夺&#xff0c;Lele终于把那块地从Yueyue的手里抢了回来。接下来&#xff0c;Lele要开始建造他的灌溉系统。 通过咨询Lele的好友——化学系的TT&#xff0c;Lele决定在田里挖出N条沟渠&#xff0c;每条沟渠输送一种肥料。 每条沟渠可以看作是一…

win7如何将计算机移至桌面,如何将win7电脑桌面的文件转移到其他盘中?

想必很多朋友都和小编一样&#xff0c;是一个嫌麻烦的人&#xff0c;是一个不怎么爱收拾的人吧?这种人有一个通病&#xff0c;那就是喜欢将一些重要的文件放置在win7 64位纯净版下载的桌面上&#xff0c;这样的话&#xff0c;不仅容易找到&#xff0c;而且方便使用&#xff0c…