2-SAT

来源:互联网 发布:弹性光网络 编辑:程序博客网 时间:2024/06/05 07:32

给定一个布尔方程,判断是否存在一组布尔变量的真值指派使整个方程为真的问题,被称为布尔方程的可满足性问题(SAT)。如果合取范式的每个子句中的文字个数都不超过两个,那么对应的SAT问题又称为2-SAT问题。(具体例子看代码)

利用强连通分量分解点击打开链接,可以在布尔公式子句数的线性时间内解决2-SAT问题。首先,把每个子句(a∨b)改写成等价形式(¬a=>b∧¬b=>a),这样就把原布尔公式以=>关系为边建立有向图。此时,显然该图中同一个强连通分量所含布尔值均相同。如果存在某个布尔变量x,¬x均在同一个强连通分量中,则显然无法令整个布尔公式的值为真。反之,如果不存在这样的布尔变量,那么对于每个布尔变量x,x所在的强连通分量的拓扑序在¬x所在的强连通分量之后<=>x为真


代码:

int main(){          //布尔公式为(a∨¬b)∧(b∨c)∧(¬c∨¬a)时          //构造6个顶点,分别对应a,b,c,¬a,¬b,¬c          V=6;                    //a∨¬b转成¬a=>b∧b=>a          add_edge(3,4);//从¬a连一条到¬b的边          add_edge(1,0);//从b连一条到a的边          //同上          add_edge(4,2);//略          add_edge(5,1);//略          //同上          add_edge(2,3);//略          add_edge(0,5);//略                    //进行强连通分量分解          scc();                    //判断是否可满足          for(int i=0;i<3;i++)          {                   if(cmp[i]==cmp[3+i])                   {                              printf("NO");                              return 0;                   }           }                     //如果可满足,则给出一组解          printf("YES\n");          for(int i=0;i<3;i++)                     if(cmp[i]>cmp[3+i])                                  printf("true\n");                     else                                  printf("false\n");                       return 0;}



原创粉丝点击