/************************************=== CCAnr ===*************************************** ** CCAnr is a local search solver for the Boolean Satisfiability (SAT) problem, ** which is especially designed for non-random instances. ** CCAnr is designed and implemented by Shaowei Cai (email: shaoweicai.cs@gmail.com), *****************************************************************************************/ /*****************************=== Develpment history ===************************************* ** 2011.5 ** SWCC (Smoothed Weighting and Configuration Checking) by Shaowei Cai ** New Idea: Configuration Checking (CC) ** A variable is configuration changed, if since its last flip, at least one of its ** neighboring var has been flipped. ** In the greedy mode, Swcc picks the best Configuration Changed Decreasing var to flip. ** In the random mode, it updates weights, and flips the oldest var in a random unsat clause. ** 2011.9 ** SWCCA (Smoothed Weighting and Configuration Checking with Aspiration) by Shaowei Cai ** New Idea: CC with Aspiration (CCA) ** Modification: in greedy mode, it first prefers to flip the best CCD var. If there is ** no CCD variable, then flip the best significant decreasing var, i.e., with a great ** positive score (in Swcca, bigger than averaged clause weight), if there exsit such vars. ** 2013.4 ** CCAnr (CCA for non-random SAT) ** Modifications: Generalize the smoothig fomula as w(ci)=w(ci)*p+ave_w*q; pick the greediest ** variable in the diversification mode. ************************************************************************************************/ #ifndef _CCA_H_ #define _CCA_H_ #include "basis.h" #define pop(stack) stack[--stack ## _fill_pointer] #define push(item, stack) stack[stack ## _fill_pointer++] = item inline void unsat(int clause) { index_in_unsat_stack[clause] = unsat_stack_fill_pointer; push(clause,unsat_stack); //update appreance count of each var in unsat clause and update stack of vars in unsat clauses int v; for(lit* p=clause_lit[clause]; (v=p->var_num)!=0; p++) { unsat_app_count[v]++; if(unsat_app_count[v]==1) { index_in_unsatvar_stack[v] = unsatvar_stack_fill_pointer; push(v,unsatvar_stack); } } } inline void sat(int clause) { int index,last_unsat_clause; //since the clause is satisfied, its position can be reused to store the last_unsat_clause last_unsat_clause = pop(unsat_stack); index = index_in_unsat_stack[clause]; unsat_stack[index] = last_unsat_clause; index_in_unsat_stack[last_unsat_clause] = index; //update appreance count of each var in unsat clause and update stack of vars in unsat clauses int v,last_unsat_var; for(lit* p=clause_lit[clause]; (v=p->var_num)!=0; p++) { unsat_app_count[v]--; if(unsat_app_count[v]==0) { last_unsat_var = pop(unsatvar_stack); index = index_in_unsatvar_stack[v]; unsatvar_stack[index] = last_unsat_var; index_in_unsatvar_stack[last_unsat_var] = index; } } } //initiation of the algorithm void init() { int v,c; int i,j; int clause; //Initialize edge weights for (c = 0; c0)// && conf_change[v]==1) { already_in_goodvar_stack[v] = 1; push(v,goodvar_stack); } else already_in_goodvar_stack[v] = 0; } //setting for the virtual var 0 time_stamp[0]=0; //pscore[0]=0; this_try_best_unsat_stack_fill_pointer = unsat_stack_fill_pointer; } void flip(int flipvar) { cur_soln[flipvar] = 1 - cur_soln[flipvar]; int i,j; int v,c; lit* clause_c; int org_flipvar_score = score[flipvar]; //update related clauses and neighbor vars for(lit *q = var_lit[flipvar]; (c=q->clause_num)>=0; q++) { clause_c = clause_lit[c]; if(cur_soln[flipvar] == q->sense) { ++sat_count[c]; if (sat_count[c] == 2) //sat_count from 1 to 2 score[sat_var[c]] += clause_weight[c]; else if (sat_count[c] == 1) // sat_count from 0 to 1 { sat_var[c] = flipvar;//record the only true lit's var for(lit* p=clause_c; (v=p->var_num)!=0; p++) score[v] -= clause_weight[c]; sat(c); } } else // cur_soln[flipvar] != cur_lit.sense { --sat_count[c]; if (sat_count[c] == 1) //sat_count from 2 to 1 { for(lit* p=clause_c; (v=p->var_num)!=0; p++) { if(p->sense == cur_soln[v] ) { score[v] -= clause_weight[c]; sat_var[c] = v; break; } } } else if (sat_count[c] == 0) //sat_count from 1 to 0 { for(lit* p=clause_c; (v=p->var_num)!=0; p++) score[v] += clause_weight[c]; unsat(c); }//end else if }//end else } score[flipvar] = -org_flipvar_score; /*update CCD */ int index; conf_change[flipvar] = 0; //remove the vars no longer goodvar in goodvar stack for(index=goodvar_stack_fill_pointer-1; index>=0; index--) { v = goodvar_stack[index]; if(score[v]<=0) { goodvar_stack[index] = pop(goodvar_stack); already_in_goodvar_stack[v] = 0; } } //update all flipvar's neighbor's conf_change to be 1, add goodvar int* p; for(p=var_neighbor[flipvar]; (v=*p)!=0; p++) { conf_change[v] = 1; if(score[v]>0 && already_in_goodvar_stack[v] ==0) { push(v,goodvar_stack); already_in_goodvar_stack[v] = 1; } } } #endif