2-SAT学习总结
来源:互联网 发布:淘宝千牛客服怎么设置 编辑:程序博客网 时间:2024/06/06 01:32
2-SAT 图论算法:
理解:
给定一个布尔方程,判断是否存在一组布尔变量的取值方案,使得整个方程值为真的问题,被称为布尔方程的可满足性问题(SAT)。SAT 问题是NP 完全的,但对于一些特殊形式的SAT 问题我们可以有效求解。
我们将下面这种布尔方程称为合取范式:
其中称为文字,它是一个布尔变量或其否定。像这样用连接的部分称为子句。如果合取范式的每个子句中的文字个数都不超过两个,那么对应的SAT 问题又称为2-SAT 问题。
思想:
对于给定的2-SAT ,首先将每个子句 (a || b) = 1 改写成等价形式(!a => b || !b => a) 我们可以简单的理解为,若a为不为真,则b一定为假。对于每个变量x, 构造两个顶点分别代表x, !x,用推出的关系为边建立有向图, 如果图中的a能到达b,则当a为真时,b一定为真。因此我们可以认为该图中同一个强连通分量中所含的所有变量的bool 值均相同。
若存在某个变量x, x 和 !x 的两个顶点在同一个强连通分量中,原bool 表达式的值就不能为真,反之,若没有这样的情况,我们可以进行强连通分量的缩点,构新图,显然,新图是一个dag(有向无环图,即拓扑图),我们求出它的一个拓扑序。那么对于每个变量x,存在。x所在的强连通分量(新图)的拓扑序在 !x 所在的强连通分量之后ó x为真。 这就是使得当前bool表达式成立的一组bool变量取值。
算法优化:
如果有用心学tarjan, 你应该能够发现一点,其实
tarjan 求SCC 就是按照头拓扑序逆序来求的。
证明:其实具体的证明应该不是太简单,但是我有一个形象的说明方法,考虑这么一个问题,我们进行tarjan-dfs 时,我们是根据边的指向不断层数加深的,那么,我们先找到的一定是递归层数最深的,也就是拓扑序最大的了。所以事情就变得简单了许多,我们可以用 scc_id[u] < scc_id[v]ó top[u] > top[v] 来等价。
时间复杂度:
若bool变量的个数为n, 子句个数为m, 那么用tarjan 求解的时间复杂度就是O(n + m)。
建图规则:
常见的2-SAT 建图中的bool子句一般就是用三种符号连接,&(and), |(or), ^(xor), 下面我们来分别讨论。
1、(a & b) = true
ð a = true, b = true (强制为true)
ð !a -> a, !b -> b
解释:显然我们要强制要求a, b 均为true, 所以如果我们想达成这个目的我们就需要在即使选中!a 为真的情况下,也要让a 为真,所以直接!a -> a( 由!a 到a 连边, 表示当!a = trueè a = true)。
2、(a & b) = false
ð a = false or b = false or a, b = false
ð a = true -> b = false, b = true -> a = false
ð a -> !b, b -> !a
解释:显然我们要强制要求a, b 中有一个为false, 也就是说选择了一个为true 后, 另一个一定为false, 所以由 a -> !b, b -> !a 连边。
3、(a | b) = true
ð a = true or b = true or a, b = true
ð a = false -> b = true, b = false -> a = true
ð !a -> b, !b -> a
解释:显然我们要强制要求a, b 中有一个为true, 也就是说选择了一个为flase 后, 另一个一定为true, 所以由 !a -> b, !b -> a 连边。
4、(a | b) = false
ð a = false ans b = false (强制为false)
ð a -> !a, b -> !b
解释:显然因为我们要强制要求a, b 均为false, 所以如果我们想达成这个目的我们就需要在即使选中a为真的情况下,也要让!a为真,所以直接a -> !a( 由a 到!a 连边, 表示当a = trueè !a = true)。
5、(a ^ b) = true
ð a != b
ð a = true -> b = false, a = false -> b = true, b = true -> a = false, b = false -> a = true
ð a -> !b, !a -> b, b -> !a, !b -> a
解释:显然我们要强制要求a, b 不相同, 所以如果我们想达成这个目的我们就需要其中一个确定之后,确定另一个与它相反,所以直接a -> !b, !a -> b, b -> !a, !b -> a 连边即可。
6、(a ^ b) = false
ð a == b
ð a = true -> b = true, a = false -> b = false, b = true -> a = true, b = false -> a = false
ð a -> b, b -> a, !a -> !b, !b -> !a
解释:显然我们要强制要求a, b 相同, 所以如果我们想达成这个目的我们就需要其中一个确定之后,确定另一个与它相同,所以直接!a -> !b, a -> b, !b -> !a, b -> a 连边即可。
适用例题:
poj 3678
题目大意 : 给出一堆bool 表达式, 询问是否有满足全部的可行解,有就输出YES ,没有就输出NO 。
分析:显然这就是一道2-SAT 裸题(毫不掩饰),直接上就好,只不过呢,这道题有一个好处就是可以锻炼建图。
Source:
- 2-SAT学习总结
- 2 – SAT 总结
- 【总结】2-SAT
- 2-sat总结
- 2-sat总结
- 2-sat问题总结
- 2-sat总结
- 2-sat概括性总结
- 2-SAT总结
- 【图论】2-sat总结
- 2-SAT总结
- 2SAT总结
- 2-sat总结
- 【2-SAT】POJ 2-SAT总结
- 2-SAT 学习笔记
- 2-SAT学习资料
- 2-SAT学习笔记
- [学习笔记]2-SAT
- zoj2321
- Oracle数据库查看表的高水位线
- 网络配置及远程管理
- Spring Boot的数据访问
- linux驱动:i2c驱动(一)
- 2-SAT学习总结
- 连接池-DBCP-C3P0
- 米洛个人修炼术:情绪的四种常用处理方式,其实都是有问题的
- Listener监听器
- Ajax.java
- R语言中的负整数索引
- Filter过滤器
- 170115
- Oracle数据库中会话、连接、进程3者之间的关系