2-SAT 2-SAT问题

问题

nn个成员的集合s=[x0,x1,,xn1]s = [x_{0}, x_{1}, \dots, x_{n-1}],其中每个成员的值为0011。任意两个成员xi,xjx_i, x_j之间有以下几种约束关系:

xixj=1x_i \vee x_j = 1表示xi,xjx_i, x_j中至少有一个为11(或关系,有1则1);

xixj=0x_i \wedge x_j = 0表示xi,xjx_i, x_j中至少有一个为00(与关系,有0则0);

xixj=1x_i \oplus x_j = 1表示xi,xjx_i, x_j中一个为00,另一个为11(异或关系,相同为0,相异为1);

给定包含nn个成员的集合ss以及一组约束关系,求一个满足集合ss的中所有成员的都满足该约束关系。该类问题称为2-SAT问题。

解法

将2-SAT问题转化为有向图的强连通分支问题。

首先构造拥有2×n2 \times n个顶点的有向图G=<V,E>G = <V,E>,每对顶点vi,vi+1v_{i}, v_{i+1}对应集合ss中的成员xix_{i}的值0011

对于约束xixj=1x_i \vee x_j = 1,构建边ei,j+1,ej,i+1e_{i,j+1}, e_{j,i+1},表示:若选择顶点viv_{i}则必选择顶点vj+1v_{j+1}(成员xi=0x_{i} = 0则必然有xj=1x_{j} = 1),若选择顶点vjv_{j}则必选择顶点vi+1v_{i+1}(成员xj=0x_{j} = 0则必然有xi=1x_{i} = 1)。

对于约束xixj=0x_i \wedge x_j = 0,构建边ei+1,j,ej+1,ie_{i+1,j}, e_{j+1,i},表示:若选择顶点vi+1v_{i+1}则必选择顶点vjv_{j}(成员xi=1x_{i} = 1则必然有xj=0x_{j} = 0),若选择顶点vj+1v_{j+1}则必选择顶点viv_{i}(成员xj=1x_{j} = 1则必然有xi=0x_{i} = 0)。

对于约束xixj=1x_i \oplus x_j = 1,构建边ei,j+1,ei+1,j,ej,i+1,ej+1,ie_{i,j+1}, e_{i+1,j}, e_{j,i+1}, e_{j+1,i},表示:若选择顶点viv_{i}则必选择顶点vj+1v_{j+1}(成员xi=0x_{i} = 0则必然有xj=1x_{j} = 1),若选择顶点vi+1v_{i+1}则必选择顶点vjv_{j}(成员xi=1x_{i} = 1则必然有xj=0x_{j} = 0),若选择顶点vjv_{j}则必选择顶点vi+1v_{i+1}(成员xj=0x_{j} = 0则必然有xi=1x_{i} = 1),若选择顶点vj+1v_{j+1}则必选择顶点viv_{i}(成员xj=1x_{j} = 1则必然有xi=0x_{i} = 0)。

显然特定的约束条件可以构造出特定的有向图G=<V,E>G = <V,E>,图中让选取某个顶点vv时,为了满足约束条件必然要选择其他对应的顶点。2-SAT构造的有向图中的所有强连通分支即为2-SAT问题的所有解,该问题转化为有向图的强连通分支求解,应用Kosaraju算法或Tarjan算法即可。

解决2-SAT问题的时间复杂度与所使用强连通分支算法的时间复杂度相同。

源码

TwoSatisfiability.h

TwoSatisfiability.cpp

测试

TwoSatisfiabilityTest.cpp

Last updated