2-CNF 问题解决方案

本篇文章主要是根据上届一个东大学长谢文艳写的一篇《给定2CNF可满足性问题》自己重新总结了一下,然后把所有的代码都调试了一遍,不过有一点要注意的是,文章中的方法能够判断问题是有具有解,能给出该问题的一种可行解,但并不能给出所有的解。

我自己总结为两个部分,图论问题和算法的详解。

一、将问题转换为图论问题 

首先,将2CNF的问题转换为图论问题。

下面的规则说明了如何把一个2CNF转化为一个有向图G=<V,E>

u    2CNF的每个变量及这个变量的非都作为图G的顶点。显然若这个2CNF3个变量,那么将有6个顶点。

 

u   

 

第一步首先为那些有到自己的非的有向路径的变量赋值,即如果图G中有从x到的有向路径,那么将变量x赋值为false。如果图G中有从到x的有向路径,则将变量x赋值为true。将在这个步骤中被赋了值的变量称为一级变量。

如下所示:

 

 

 

 

第二步依次从与每一个一级变量对应的节点出发(如果一级变量x被赋值为true,则从与x对应的节点出发;如果x被赋值为false, 则从与对应的节点出发),将所有能到达的、还没有被赋值的节点赋值为true(如果该节点对应于y,则将y赋值为true;如果该节点对应于,则将y赋值为false)。将在这个步骤中被赋了值的变量称为二级变量。

如下所示:

 

第三步:依次检查还没有被赋值的变量,如s,如果与s对应的顶点出度不为0(有指向其它节点的有向边),则将s赋值为true,然后从与s对应的顶点出发,将所有能到达的、还没有被赋值的节点赋值为true;如果与s对应的顶点出度为0,则将s赋值为false,从与s对应的顶点出发,将所有能到达的、还没有被赋值的节点赋值为true。将在这个步骤中被赋了值的变量称为三级变量。

如下所示:

    

 

 

   

二、算法的详解

 

 

1.        先构图,并将图表示为邻接矩阵。思想主要是将每一个字句用邻接矩阵edges表示,如字句xUy,输入的时候表示为:1 1然后,将该字句表示 在数据结构中表示为edges[n+1][2]=1以及edges[2][n+1]=1

2.        并找出一级变量。主要思想是调用isSatisfiable函数,利用广度优先从顶点i到顶点n+i看看是否能走通,同时,也判断从顶点n+i到顶点i,如果都走通了,说明误解,否则判定这n个点后,不存在两个条件都满足的情况,则表示有解了。同时,在判断的过程中,找出一级变量。

 

3.        找出二级变量和三级变量。从每一个一级变量出发,根据原则,利用广度优先的算法,把所有能达到的变量变为true,这些变量就是二级变量了。然后再获取三级变量,通过一个循环,将没有访问过的变量,利用的原则来将所有的所能达到的置为true

 

4.        自此,算法结束,输出所有变量的值。(注意:该算法只能获得一组可行解,但不能获得所有的解)

 

 

 

如果输入:  

格式如下:

4 3//第一个参数是行数 第二个是变量个数

//记下来是字句输入 表示为-1 2

 

-1 2

-2 3

1 -3

3 2

得出结果:

有可行解

1:1

2:1

3:1

 

 

又例如输入:

 

 

 

 

 

得出结果:

 

1:1 //X1:1
2:0 //x2:0
3:0 //x3:0
4:1 //x4:1
5:0 //x5:0

 

 

点击这里下载完整代码

若有问题欢迎发邮件给我:chen-hongqin@163.com

 

展开阅读全文

没有更多推荐了,返回首页