zoukankan      html  css  js  c++  java
  • 2SAT

          所谓2-SAT就是2元可满足性问题。首先,作为众所周知的,任何布尔表达式,都可以化为合取范式的形式,即化为:   () and () and () ...and () 其中括号里面的是用析取符号or 连接的变量或者变量的非的形式。我们一般称,变量或者变量的非为“文字”,而括号里的叫做子句。可满足性问题是要给所有的变量一个赋值(真或假)使得表达式值为真。而2元可满足性问题,就是化为合取范式后,每个子句最多有两个文字的可满足性问题。
     
          cook定理已经说明,一般地可满足性问题是NPC的。但是值得注意的是,2-SAT却是P的。简单分析一下2-SAT: 它要求每个子句的值都是真。考虑一个子句,a or b ,显然如果a取false,则b一定取true,反之亦然。先给出算法:
     
          假设2-SAT问题中有N个变量,则构造一个有向图包含2n个节点。每个节点代表一个变量或者变量的非(即代表一个文字)。对每个子句a or b,在途中加2条有向边 (~a,b)和(~b,a)  (其中~表示变量的非)。然后对这个有向图求强连通分量,把每个强连通分量看作一个点(缩点),这样新的有向图是无环的(无环有向图又叫DAG)。如果一个强连通分量里同时包含了同一个变量以及它的非,则原问题是不可满足的。否则,我们可以构造解,对这个DAG可以进行拓扑排序,按照节点的拓扑排序顺序的倒序进行如下操作:找到此顺序中第一个没有标记的节点,把此节点标记成true,并且把和此节点矛盾的节点(一个节点包含了a,另外一个节点包含了~a,则称它们是矛盾的),以及祖先标记成false,直到所有节点都有标记,结束。这些标记也对应着变量的取值。
     
         大概不严谨地证明一下,首先同一个强连通分量里的文字是等价的。因为对一个子句a or b,按照一个取假,另外一个一定取真的意思,连的边表示逻辑中的“蕴含”关系,即有~a->b  ,~b->a。这样一个强连通分量里的文字互相蕴含,所以是等价的。于是,当存在a->~a->a时,显然原问题不可满足。
     
         第二,因为每标记一个true,立刻把与它矛盾的并且“反向蕴含”的点都设置为false,所以,这样的赋值不会产生矛盾。
     
          第三,不会把一个变量和它的非都设置为false。
     
        这是因为,考虑设置变量为false时,假设设置a为true,沿着“反向蕴含链”把x设置为false了,这说明有x->~a,由于对称性,有a->~x  (这里的->表示有路相连,并不一定是一条边),按照算法流程必须要先考虑~x (拓扑排序的逆序),可见这时~x应该已经被设置为true了,因为否则的话,如果~x=false,则会沿着“反向蕴含链”把a也设置为false的,根本不会到考虑a为true的这一步骤了。于是,设置false是安全的。
     
        综上所述,该算法可以找到一组2-SAT的可行解,或者判断无解。该算法的复杂度:求强连通分量、拓扑排序、以及遍历图都是O(m)的,其中m是边数。
  • 相关阅读:
    CSS input
    CSS 伪类选择器
    input placeholder 文字颜色修改
    css flex弹性布局学习总结
    jqGrid使用方法
    GridView控件RowDataBound事件的一个实例
    GridView控件RowDataBound事件中获取列字段值的几种途径 !!!
    .net中ckeditor的应用
    博客第一天
    用python实现数学多元数学方程式计算
  • 原文地址:https://www.cnblogs.com/Christine/p/2861134.html
Copyright © 2011-2022 走看看