问题
有n个成员的集合s=[x0,x1,…,xn−1],其中每个成员的值为0或1。任意两个成员xi,xj之间有以下几种约束关系:
xi∨xj=1表示xi,xj中至少有一个为1(或关系,有1则1);
xi∧xj=0表示xi,xj中至少有一个为0(与关系,有0则0);
xi⊕xj=1表示xi,xj中一个为0,另一个为1(异或关系,相同为0,相异为1);
给定包含n个成员的集合s以及一组约束关系,求一个满足集合s的中所有成员的都满足该约束关系。该类问题称为2-SAT问题。
解法
将2-SAT问题转化为有向图的强连通分支问题。
首先构造拥有2×n个顶点的有向图G=<V,E>,每对顶点vi,vi+1对应集合s中的成员xi的值0和1。
对于约束xi∨xj=1,构建边ei,j+1,ej,i+1,表示:若选择顶点vi则必选择顶点vj+1(成员xi=0则必然有xj=1),若选择顶点vj则必选择顶点vi+1(成员xj=0则必然有xi=1)。
对于约束xi∧xj=0,构建边ei+1,j,ej+1,i,表示:若选择顶点vi+1则必选择顶点vj(成员xi=1则必然有xj=0),若选择顶点vj+1则必选择顶点vi(成员xj=1则必然有xi=0)。
对于约束xi⊕xj=1,构建边ei,j+1,ei+1,j,ej,i+1,ej+1,i,表示:若选择顶点vi则必选择顶点vj+1(成员xi=0则必然有xj=1),若选择顶点vi+1则必选择顶点vj(成员xi=1则必然有xj=0),若选择顶点vj则必选择顶点vi+1(成员xj=0则必然有xi=1),若选择顶点vj+1则必选择顶点vi(成员xj=1则必然有xi=0)。
显然特定的约束条件可以构造出特定的有向图G=<V,E>,图中让选取某个顶点v时,为了满足约束条件必然要选择其他对应的顶点。2-SAT构造的有向图中的所有强连通分支即为2-SAT问题的所有解,该问题转化为有向图的强连通分支求解,应用Kosaraju算法或Tarjan算法即可。
解决2-SAT问题的时间复杂度与所使用强连通分支算法的时间复杂度相同。
源码
TwoSatisfiability.h
TwoSatisfiability.cpp
测试
TwoSatisfiabilityTest.cpp