文献:
Stepan Kochemazov, Oleg Zaikin, Alexander A. Semenov, Victor Kondratiev:
Speeding Up CDCL Inference with Duplicate Learnt Clauses. ECAI 2020: 339-346
代码解读:
solver.h中相关声明量 | |
// duplicate learnts version
// duplicate learnts version
// duplicate learnts version
/ duplicate learnts version |
|
1 int Solver::is_duplicate(std::vector<uint32_t>&c){ 2 auto time_point_0 = std::chrono::high_resolution_clock::now(); 3 dupl_db_size++; 4 int res = 0; 5 6 int sz = c.size(); 7 std::vector<uint32_t> tmp(c); 8 sort(tmp.begin(),tmp.end()); 9 10 uint64_t hash = 0; 11 12 for (int i =0; i<sz; i++) { 13 hash ^= tmp[i] + 0x9e3779b9 + (hash << 6) + (hash>> 2); 14 } 15 16 int32_t head = tmp[0]; 17 auto it0 = ht.find(head); 18 if (it0 != ht.end()){ 19 auto it1= ht[head].find(sz); 20 if (it1 != ht[head].end()){ 21 auto it2 = ht[head][sz].find(hash); 22 if (it2 != ht[head][sz].end()){ 23 it2->second++; 24 res = it2->second; 25 } 26 else{ 27 ht[head][sz][hash]=1; 28 } 29 } 30 else{ 31 ht[head][sz][hash]=1; 32 } 33 }else{ 34 ht[head][sz][hash]=1; 35 } 36 auto time_point_1 = std::chrono::high_resolution_clock::now(); 37 duptime += std::chrono::duration_cast<std::chrono::microseconds>(time_point_1-time_point_0); 38 return res; 39 }
|
|
1 bool Solver::simplifyLearnt_tier2() 2 { 3 int beforeSize, afterSize; 4 int learnts_tier2_size_before = learnts_tier2.size(); 5 6 int ci, cj, li, lj; 7 bool sat, false_lit; 8 unsigned int nblevels; 9 //// 10 //printf("learnts_x size : %d\n", learnts_x.size()); 11 12 //// 13 int nbSimplified = 0; 14 int nbSimplifing = 0; 15 16 for (ci = 0, cj = 0; ci < learnts_tier2.size(); ci++){ 17 CRef cr = learnts_tier2[ci]; 18 Clause& c = ca[cr]; 19 20 if (removed(cr)) continue; 21 else if (c.simplified()){ 22 learnts_tier2[cj++] = learnts_tier2[ci]; 23 //// 24 nbSimplified++; 25 } 26 else{ 27 int saved_size=c.size(); 28 // if (drup_file){ 29 // add_oc.clear(); 30 // for (int i = 0; i < c.size(); i++) add_oc.push(c[i]); } 31 //// 32 nbSimplifing++; 33 sat = false_lit = false; 34 for (int i = 0; i < c.size(); i++){ 35 if (value(c[i]) == l_True){ 36 sat = true; 37 break; 38 } 39 else if (value(c[i]) == l_False){ 40 false_lit = true; 41 } 42 } 43 if (sat){ 44 removeClause(cr); 45 } 46 else{ 47 detachClause(cr, true); 48 49 if (false_lit){ 50 for (li = lj = 0; li < c.size(); li++){ 51 if (value(c[li]) != l_False){ 52 c[lj++] = c[li]; 53 } 54 } 55 c.shrink(li - lj); 56 } 57 58 beforeSize = c.size(); 59 assert(c.size() > 1); 60 // simplify a learnt clause c 61 simplifyLearnt(c); 62 assert(c.size() > 0); 63 afterSize = c.size(); 64 65 if(drup_file && saved_size!=c.size()){ 66 67 #ifdef BIN_DRUP 68 binDRUP('a', c , drup_file); 69 // binDRUP('d', add_oc, drup_file); 70 #else 71 for (int i = 0; i < c.size(); i++) 72 fprintf(drup_file, "%i ", (var(c[i]) + 1) * (-2 * sign(c[i]) + 1)); 73 fprintf(drup_file, "0\n"); 74 75 // fprintf(drup_file, "d "); 76 // for (int i = 0; i < add_oc.size(); i++) 77 // fprintf(drup_file, "%i ", (var(add_oc[i]) + 1) * (-2 * sign(add_oc[i]) + 1)); 78 // fprintf(drup_file, "0\n"); 79 #endif 80 } 81 82 //printf("beforeSize: %2d, afterSize: %2d\n", beforeSize, afterSize); 83 84 if (c.size() == 1){ 85 // when unit clause occur, enqueue and propagate 86 uncheckedEnqueue(c[0]); 87 if (propagate() != CRef_Undef){ 88 ok = false; 89 return false; 90 } 91 // delete the clause memory in logic 92 c.mark(1); 93 ca.free(cr); 94 //#ifdef BIN_DRUP 95 // binDRUP('d', c, drup_file); 96 //#else 97 // fprintf(drup_file, "d "); 98 // for (int i = 0; i < c.size(); i++) 99 // fprintf(drup_file, "%i ", (var(c[i]) + 1) * (-2 * sign(c[i]) + 1)); 100 // fprintf(drup_file, "0\n"); 101 //#endif 102 } 103 else{ 104 105 106 nblevels = computeLBD(c); 107 if (nblevels < c.lbd()){ 108 //printf("lbd-before: %d, lbd-after: %d\n", c.lbd(), nblevels); 109 c.set_lbd(nblevels); 110 } 111 //duplicate learnts 112 int id = 0; 113 114 std::vector<uint32_t> tmp; 115 for (int i = 0; i < c.size(); i++) 116 tmp.push_back(c[i].x); 117 id = is_duplicate(tmp); 118 119 120 //duplicate learnts 121 122 if (id < min_number_of_learnts_copies+2){ 123 attachClause(cr); 124 learnts_tier2[cj++] = learnts_tier2[ci]; 125 if (id == min_number_of_learnts_copies+1){ 126 duplicates_added_minimization++; 127 } 128 if ((c.lbd() <= core_lbd_cut)||(id == min_number_of_learnts_copies+1)){ 129 //if (id == min_number_of_learnts_copies+1){ 130 cj--; 131 learnts_core.push(cr); 132 c.mark(CORE); 133 } 134 135 c.setSimplified(true); 136 } 137 } 138 } 139 } 140 } 141 learnts_tier2.shrink(ci - cj); 142 143 // printf("c nbLearnts_tier2 %d / %d, nbSimplified: %d, nbSimplifing: %d\n", 144 // learnts_tier2_size_before, learnts_tier2.size(), nbSimplified, nbSimplifing); 145 146 return true; 147 148 }
1 lbool Solver::search(int& nof_conflicts) 2 { 3 assert(ok); 4 int backtrack_level; 5 int lbd; 6 vec<Lit> learnt_clause; 7 bool cached = false; 8 starts++; 9 int conflictCs = 0; //本次重启冲突次数计数 10 11 // simplify 12 。。。。。。 13 14 15 for (;;){ 16 17 confl = propagate(); 18 19 if (confl != CRef_Undef) 20 { 21 22 //以下保持原来的search函数代码段 23 if (VSIDS){ 24 if (--timer == 0 && var_decay < 0.95) timer = 5000, var_decay += 0.01; 25 }else 26 if (step_size > min_step_size) step_size -= step_size_dec; 27 28 conflicts++; nof_conflicts--; conflictCs++; 29 //if (conflicts == 100000 && learnts_core.size() < 100) core_lbd_cut = 5; 30 ConflictData data = FindConflictLevel(confl); 31 if (data.nHighestLevel == 0) return l_False; 32 if (data.bOnlyOneLitFromHighest) 33 { 34 cancelUntil(data.nHighestLevel - 1); 35 continue; 36 } 37 38 learnt_clause.clear(); 39 if(conflicts > 50000) DISTANCE = 0; 40 else DISTANCE=1; 41 42 43 if(VSIDS && DISTANCE){ 44 mycollectFirstUIP(confl); 45 } 46 47 backtrack_level = 0; 48 49 // check chrono backtrack condition 50 if ((confl_to_chrono < 0 || confl_to_chrono <= conflicts) && chrono > -1 && (decisionLevel() - backtrack_level) >= chrono) 51 { 52 ++chrono_backtrack; 53 cancelUntil(data.nHighestLevel -1); 54 55 } 56 else // default behavior 57 { 58 ++non_chrono_backtrack; 59 cancelUntil(backtrack_level); 60 } 61 62 lbd--; 63 if (VSIDS){ 64 cached = false; 65 conflicts_VSIDS++; 66 lbd_queue.push(lbd); 67 global_lbd_sum += (lbd > 50 ? 50 : lbd); } 68 69 if (learnt_clause.size() == 1){ 70 uncheckedEnqueue(learnt_clause[0]); 71 }else{ 72 CRef cr = ca.alloc(learnt_clause, true); 73 74 ca[cr].set_lbd(lbd); 75 76 //duplicate learnts 77 int id = 0; 78 if (lbd <= max_lbd_dup){ 79 std::vector<uint32_t> tmp; 80 for (int i = 0; i < learnt_clause.size(); i++) 81 tmp.push_back(learnt_clause[i].x); 82 id = is_duplicate(tmp); 83 if (id == min_number_of_learnts_copies +1){ 84 duplicates_added_conflicts++; 85 } 86 if (id == min_number_of_learnts_copies){ 87 duplicates_added_tier2++; 88 } 89 } 90 //duplicate learnts 91 92 93 if ((lbd <= core_lbd_cut) || (id == min_number_of_learnts_copies+1)){ 94 learnts_core.push(cr); 95 ca[cr].mark(CORE); 96 }else if ((lbd <= tier2_lbd_cut)||(id == min_number_of_learnts_copies)){ 97 learnts_tier2.push(cr); 98 ca[cr].mark(TIER2); 99 ca[cr].touched() = conflicts; 100 }else{ 101 learnts_local.push(cr); 102 claBumpActivity(ca[cr]); } 103 attachClause(cr); 104 uncheckedEnqueue(learnt_clause[0], backtrack_level, cr); 105 #ifdef PRINT_OUT 106 std::cout << "new " << ca[cr] << "\n"; 107 std::cout << "ci " << learnt_clause[0] << " l " << backtrack_level << "\n"; 108 #endif 109 } 110 if (drup_file){ 111 #ifdef BIN_DRUP 112 binDRUP('a', learnt_clause, drup_file); 113 #else 114 for (int i = 0; i < learnt_clause.size(); i++) 115 fprintf(drup_file, "%i ", (var(learnt_clause[i]) + 1) * (-2 * sign(learnt_clause[i]) + 1)); 116 fprintf(drup_file, "0\n"); 117 #endif 118 } 119 120 if (VSIDS) varDecayActivity(); 121 claDecayActivity(); 122 123 // 124 125 } 126 else 127 { 128 // NO CONFLICT 129 bool restart = false; 130 if (!VSIDS) 131 restart = nof_conflicts <= 0; 132 else if (!cached){ 133 restart = lbd_queue.full() && (lbd_queue.avg() * 0.8 > global_lbd_sum / conflicts_VSIDS); 134 cached = true; 135 } 136 137 if (restart /*|| !withinBudget()*/){ 138 //return l_False; //for test 139 140 lbd_queue.clear(); 141 cached = false; 142 // Reached bound on number of conflicts: 143 progress_estimate = progressEstimate(); 144 cancelUntil(0); 145 146 return l_Undef; 147 } 148 149 // Simplify the set of problem clauses: 150 if (decisionLevel() == 0 && !simplify()){ 151 return l_False; } 152 153 if (conflicts >= next_T2_reduce){ 154 next_T2_reduce = conflicts + 10000; 155 reduceDB_Tier2(); } 156 if (conflicts >= next_L_reduce){ 157 next_L_reduce = conflicts + 15000; 158 reduceDB(); } 159 160 Lit next = lit_Undef; 161 162 163 // New variable decision: 164 decisions++; 165 next = pickBranchLit(); 166 167 if (next == lit_Undef){ 168 decisions--; 169 // Model found: 170 return l_True; 171 } 172 173 174 // Increase decision level and enqueue 'next' 175 newDecisionLevel(); 176 uncheckedEnqueue(next, decisionLevel()); 177 nextLit = next; // update on 2020-03-10 178 #ifdef PRINT_OUT 179 std::cout << "d " << next << " l " << decisionLevel() << "\n"; 180 #endif 181 } 182 } 183 }
|