2019年求解器Maple LCM OnlineDel给出了在线管理学习子句规模的方法

    (1)将新增的学习子句与学习子句集中指定的子句进行替换,保证学习子句集的规模一定。

     (2)每个学习子句的Q值初始为0;当参与冲突分析时,会按照一定规则增加其值;

     (3)最新的学习子句生成后,原学习子句集中指定被替换的学习子句是如何选出来的?

                       (3-1)依次加入l冲突分析得到的学习子句进入earnt_local学习子句集,维持一定数量规模(如80000个);

                        (3-2)学习子句集中的子句表示为learnts_local[CDelTag] 。CDelTag为循环增加的位置序号。按照一个方向排查每一个学习子句:对于.usedRecDel() >= 2的子句,设置其值为0,SETusedRecDel(0)。排查一遍后,CDelTag停驻的地方(没有.usedRecDel() >= 2的子句在学习子句集中时刻)即为需要被替换的学习子句位置。

 

在search函数中,实现代码如下:

 1  。。。
 2                     if (learnts_local.size() < Learnts_Size_threshold){
 3                          learnts_local.push(cr);
 4                      }else{
 5                          CRef DelClauseCandidate ;
 6                          DelClauseCandidate = learnts_local[CDelTag] ;
 7                          while (!ca[DelClauseCandidate].removable() || locked(ca[DelClauseCandidate]) ||  ca[DelClauseCandidate].usedRecDel() >= 2  ) {
 8                              if(!ca[DelClauseCandidate].removable())   ca[DelClauseCandidate].removable(true);
 9                              ca[DelClauseCandidate].SETusedRecDel(0) ;
10                              CDelTag = (CDelTag+1) % learnts_local.size()  ;
11                              DelClauseCandidate = learnts_local[CDelTag] ; 
12                          }
13                          ca[DelClauseCandidate].SETusedRecDel(0) ;
14                          DeletionCnt++ ;
15                          if (ca[DelClauseCandidate].mark() == LOCAL)      removeClause(DelClauseCandidate) ;
16                          learnts_local[CDelTag] = cr ;
17                          CDelTag = (CDelTag+1) % learnts_local.size()  ; 
18                    }
19                 }

在analyze函数中,参与冲突分析的学习子句的值 c.usedRecDel() + inc_val  做增加,具体代码如下:

  1 void Solver::analyze(CRef confl, vec<Lit>& out_learnt, int& out_btlevel, int& out_lbd)
  2 {
  3     int pathC = 0;
  4     Lit p     = lit_Undef;
  5 
  6     // Generate conflict clause:
  7     //
  8     out_learnt.push();      // (leave room for the asserting literal)
  9     int index   = trail.size() - 1;
 10     int nDecisionLevel = level(var(ca[confl][0]));
 11     assert(nDecisionLevel == level(var(ca[confl][0])));
 12 
 13     do{
 14         assert(confl != CRef_Undef); // (otherwise should be UIP)
 15         Clause& c = ca[confl];
 16 
 17         // For binary clauses, we don't rearrange literals in propagate(), so check and make sure the first is an implied lit.
 18         if (p != lit_Undef && c.size() == 2 && value(c[0]) == l_False){
 19             assert(value(c[1]) == l_True);
 20             Lit tmp = c[0];
 21             c[0] = c[1], c[1] = tmp; }
 22 
 23         // Update LBD if improved.
 24         if (c.learnt() && c.mark() != CORE){
 25             int lbd = computeLBD(c);
 26             if (lbd < c.lbd()){
 27                 if (c.lbd() <= 30) c.removable(false); // Protect once from reduction.
 28                 c.set_lbd(lbd);
 29                 if (lbd <= 3){
 30                     learnts_core.push(confl);
 31                     c.mark(CORE); 
 32                 }
 33             }
 34         }
 35 
 36         double inc_val = 12 / double(c.lbd()) ;        
 37         double used_so_far = c.usedRecDel() + inc_val ; //Sima        
 38         c.SETusedRecDel(used_so_far) ; //Sima
 39         
 40 
 41         for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){
 42             Lit q = c[j];
 43 
 44             if (!seen[var(q)] && level(var(q)) > 0){
 45                 if (VSIDS){
 46                     varBumpActivity(var(q), .5);
 47                     add_tmp.push(q);
 48                 }else
 49                     conflicted[var(q)]++;
 50                 seen[var(q)] = 1;
 51                 if (level(var(q)) >= nDecisionLevel){
 52                     pathC++;
 53                 }else
 54                     out_learnt.push(q);
 55             }
 56         }
 57         
 58         // Select next clause to look at:
 59         do {
 60             while (!seen[var(trail[index--])]);
 61             p  = trail[index+1];
 62         } while (level(var(p)) < nDecisionLevel);
 63         
 64         confl = reason(var(p));
 65         seen[var(p)] = 0;
 66         pathC--;
 67 
 68     }while (pathC > 0);
 69     out_learnt[0] = ~p;
 70 
 71     // Simplify conflict clause:
 72     //
 73     int i, j;
 74     out_learnt.copyTo(analyze_toclear);
 75     if (ccmin_mode == 2){
 76         uint32_t abstract_level = 0;
 77         for (i = 1; i < out_learnt.size(); i++)
 78             abstract_level |= abstractLevel(var(out_learnt[i])); // (maintain an abstraction of levels involved in conflict)
 79 
 80         for (i = j = 1; i < out_learnt.size(); i++)
 81             if (reason(var(out_learnt[i])) == CRef_Undef || !litRedundant(out_learnt[i], abstract_level))
 82                 out_learnt[j++] = out_learnt[i];
 83         
 84     }else if (ccmin_mode == 1){
 85         for (i = j = 1; i < out_learnt.size(); i++){
 86             Var x = var(out_learnt[i]);
 87 
 88             if (reason(x) == CRef_Undef)
 89                 out_learnt[j++] = out_learnt[i];
 90             else{
 91                 Clause& c = ca[reason(var(out_learnt[i]))];
 92                 for (int k = c.size() == 2 ? 0 : 1; k < c.size(); k++)
 93                     if (!seen[var(c[k])] && level(var(c[k])) > 0){
 94                         out_learnt[j++] = out_learnt[i];
 95                         break; }
 96             }
 97         }
 98     }else
 99         i = j = out_learnt.size();
100 
101     max_literals += out_learnt.size();
102     out_learnt.shrink(i - j);
103     tot_literals += out_learnt.size();
104 
105     out_lbd = computeLBD(out_learnt);
106     if (out_lbd <= 6 && out_learnt.size() <= 30) // Try further minimization?
107         if (binResMinimize(out_learnt))
108             out_lbd = computeLBD(out_learnt); // Recompute LBD if minimized.
109 
110     // Find correct backtrack level:
111     //
112     if (out_learnt.size() == 1)
113         out_btlevel = 0;
114     else{
115         int max_i = 1;
116         // Find the first literal assigned at the next-highest level:
117         for (int i = 2; i < out_learnt.size(); i++)
118             if (level(var(out_learnt[i])) > level(var(out_learnt[max_i])))
119                 max_i = i;
120         // Swap-in this literal at index 1:
121         Lit p             = out_learnt[max_i];
122         out_learnt[max_i] = out_learnt[1];
123         out_learnt[1]     = p;
124         out_btlevel       = level(var(p));
125     }
126 
127     if (VSIDS){
128         for (int i = 0; i < add_tmp.size(); i++){
129             Var v = var(add_tmp[i]);
130             if (level(v) >= out_btlevel - 1)
131                 varBumpActivity(v, 1);
132         }
133         add_tmp.clear();
134     }else{
135         seen[var(p)] = true;
136         for(int i = out_learnt.size() - 1; i >= 0; i--){
137             Var v = var(out_learnt[i]);
138             CRef rea = reason(v);
139             if (rea != CRef_Undef){
140                 const Clause& reaC = ca[rea];
141                 for (int i = 0; i < reaC.size(); i++){
142                     Lit l = reaC[i];
143                     if (!seen[var(l)]){
144                         seen[var(l)] = true;
145                         almost_conflicted[var(l)]++;
146                         analyze_toclear.push(l); } } } } }
147 
148     for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0;    // ('seen[]' is now cleared)
149 }

       具体可以参考:Sima Jamali、David Mitchell2019年SAT竞赛求解器Maple LCM OnlineDel,以及他们发表的文章:S. Jamali and D. Mitchell, ”Simplifying CDCL Clause Database Reduction,” in Proceedings of SAT, 2019。

 

posted on 2020-04-02 14:02  海阔凭鱼跃越  阅读(183)  评论(0编辑  收藏  举报