Page 391 - 《软件学报》2024年第4期
P. 391

蒋璐宇 等: 针对   MUS  求解问题的加强剪枝策略                                                    1969


                                                   seed 扩充成一个              seed 收缩为一个   MUS.
                    (2) 判断   seed 的可满足性: 若可满足, 将                MSS; 否则, 将
                    (3) 将其全部子集或全部超集标记为已探索.

                 算法  1. MARCO.
                 输入: 不可满足的子句集       C;
                 输出: 已找到的子句集      C  的  MUS  集合和  MSS  集合.
                 1. map ← BooleanFormula(nvars=|C|)
                 2. while map 是可满足的 do
                 3.  seed ← GetUnexplored(map)
                 4.  if seed is SAT then
                 5.     MSS ← Grow(seed)
                 6.     output MSS
                 7.     map ← map ∧ BlockDown(seed)
                 8.  else
                 9.     MUS ← Shrink(seed)
                 10.   output MUS
                 11.   map ← map ∧ BlockUp(seed)
                 12.  end if
                 13. end while
                    在  MARCO  算法的每一次迭代中, 都会将当前的           seed  转化为一个  MSS  或  MUS, 因此保证了每轮迭代都会有
                 一个新输出的解. 根据可满足性问题的特点可知, 一个可满足的子句集的任何一个子集也一定是可满足的, 一个不
                 可满足的子句集的任何一个超集也一定是不可满足的. 因此, 算法每输出一个                             MSS (或  MUS) 时, 将通过
                 BlockDown (或  BlockUp) 操作向公式  map  中添加相应子句以阻塞该      MSS  的全部子集    (或该  MUS  的全部超集), 从
                 而缩减了搜索空间, 避免了算法在无解空间中的探索.
                    使用极大化模型的       MARCO  算法  (算法  2) 是其作者在    2016  年对于  MARCO  算法提出的一个优化版本        [22] , 它
                 与上文提到的     MARCO  算法有两个主要差别: (1) 在每轮迭代开始时, MARCO            算法随机选择一个未探索的种子节
                 点, 而极大化模型的      MARCO  算法则选择当前哈斯图中的极大未探索种子节点. (2) 当选择的种子节点判定为可满
                 足时, MARCO   算法需要对该种子进行扩充操作, 使其转化为一个                MSS; 而极大化模型的      MARCO  算法则可以省
                 略对种子的扩充操作, 直接将该种子输出为一个                MSS, 这是由于极大化模型保证了种子节点是极大未探索子集,
                 因此无需对种子进行扩充操作. 极大化模型              MARCO  算法的伪代码描述在算法         2  中, 可以看出算法    1  和算法  2  的
                 区别也体现在第     3 行和第  5 行. 算法  1 中第  3 行通过调用  GetUnexplored 函数从  map 中选取一个子句集的未探索子集作

                 为  seed , 而算法  2 中第  3 行则调用  GetUnexploredMax 函数从  map 中选取一个子句集的极大未探索子集作为          seed ;
                 算法  1  中第  5  行对当前判定为可满足的      seed  执行了扩充操作, 得到一个极大可满足子集, 而算法             2  中第  5  行将当
                 前判定为可满足的       seed 直接作为一个极大可满足子集. 优化后的           MARCO  在算法初期更倾向于找到更多的            MUS,
                 同时省去了扩充操作的时间开销, 在一定程度上加速了枚举                   MUS  的效率.
                 算法  2. MARCO+: 使用极大化模型的优化版本.

                 输入: 不可满足的子句集       C;
                 输出: 已找到的子句集      C  的  MUS  集合和  MSS  集合.

                 1. map ← BooleanFormula(nvars=|C|)
                 2. while map 是可满足的 do
   386   387   388   389   390   391   392   393   394   395   396