walksat2013版本的函数
重点函数之一
1 //cpick means computing break values and pick, this function is adopted for random 4-SAT 2 int cpick_bbreak_gmake() 3 { 4 int i,k,c,v,ci; 5 int bestvar_array[100]; 6 int bestvar_count; 7 int best_bbreak; 8 int best_gmake; 9 int bbreakv,gmakev; 10 11 int *truep, *falsep; 12 13 c = unsat_stack[rand()%unsat_stack_fill_pointer]; 14 15 //the first var 16 v = clause_lit[c][0].var_num; 17 truep = (cur_soln[v])? var_poslit[v]:var_neglit[v]; 18 19 bbreakv=0; 20 for(; (ci=*truep)!=-1; ++truep) 21 { 22 if (sat_count[ci]==1) ++bbreakv; 23 } 24 25 best_bbreak = bbreakv; 26 bestvar_array[0] = v; 27 bestvar_count = 1; 28 29 //the remaining vars 30 for(k=1; k<clause_lit_count[c]; ++k) 31 { 32 v = clause_lit[c][k].var_num; 33 34 truep = (cur_soln[v])? var_poslit[v]:var_neglit[v]; 35 36 bbreakv=0; 37 for(; (ci=*truep)!=-1; ++truep) 38 { 39 if (sat_count[ci]==1) 40 { 41 if (bbreakv == best_bbreak) break; 42 ++bbreakv; 43 } 44 } 45 46 if(ci!=-1) continue; 47 48 if (bbreakv < best_bbreak) 49 { 50 best_bbreak = bbreakv; 51 bestvar_array[0] = v; 52 bestvar_count = 1; 53 } 54 else// if (bbreakv == best_bbreak) 55 { 56 bestvar_array[bestvar_count]=v; 57 ++bestvar_count; 58 } 59 } 60 61 if(best_bbreak!=0 && (rand()%MY_RAND_MAX_INT)*BASIC_SCALE < wp) return clause_lit[c][rand()%clause_lit_count[c]].var_num; 62 63 if(bestvar_count>1) 64 { 65 int org_bestvar_count = bestvar_count; 66 67 v = bestvar_array[0]; 68 69 falsep = cur_soln[v]?var_neglit[v]:var_poslit[v]; 70 71 gmakev=0; 72 for(; (ci=*falsep)!=-1; ++falsep) 73 { 74 if (sat_count[ci]==1) gmakev+=b; 75 else if (sat_count[ci]==0) gmakev+=a; 76 } 77 best_gmake = gmakev; 78 //bestvar_array[0] = v; 79 bestvar_count = 1; 80 81 for(i=1; i<org_bestvar_count; ++i) 82 { 83 v = bestvar_array[i]; 84 falsep = cur_soln[v]?var_neglit[v]:var_poslit[v]; 85 86 gmakev=0; 87 for(; (ci=*falsep)!=-1; ++falsep) 88 { 89 if (sat_count[ci]>1) continue; 90 if (sat_count[ci]==1) gmakev+=b; 91 else //if (sat_count[ci]==0) 92 gmakev+=a; 93 } 94 95 if (gmakev > best_gmake) 96 { 97 best_gmake = gmakev; 98 bestvar_array[0] = v; 99 bestvar_count = 1; 100 } 101 else if (gmakev == best_gmake) 102 { 103 bestvar_array[bestvar_count]=v; 104 ++bestvar_count; 105 } 106 } 107 } 108 109 return bestvar_array[rand()%bestvar_count]; 110 111 /*if(best_bbreak == 0) return bestvar_array[rand()%bestvar_count]; 112 113 if(rand()%MY_RAND_MAX_INT < scaledwp) return clause_lit[c][rand()%clause_lit_count[c]].var_num; 114 else return bestvar_array[rand()%bestvar_count];*/ 115 116 }
我自己敲一遍顺便做些注释。如下:
int cpick_bbreak_gmake()
{
int i,k,c,v,ci; // c通常代表子句编号; v通常代表变元; ci通常代表子句中的元素(文字)
int bestvar_array[100];
int bestvar_count;
int best_bbreak;
int best_gmake;
int bbreakv, gmakev;
int *truep, *falsep; //这两个指针的移动可以用来指示子句序列——这些子句包含特定变元(分为两类,分别是以正、负文字形式出现在子句中的)。
//-----------------------------------------
c = unsat_stack[rand()%unsat_stack_fill_pointer]; //从栈中任选一个子句;unsat_satck_fill_pointer是栈内元素的个数,该值也作为栈顶的指示变量
//先针对c子句的0号文字(文字变元v),得到best_bbreak的初值,并将文字变元v记录到数组bestvar_array之中。
v = clause_lit[c][0].var_num; //选择子句clause_lit[c]的0号位置上的文字,取它的变元。
truep = ( cur_soln[v] ) ? var_poslit[v] : var_neglit[v]; //变元v赋值为1/0,分别取v以正/负文字出现的子句序列头指针(数组名)赋给truep(这样他总数获得v以为真的形式出现的头指针)。
bbreakv = 0;
for (;(ci = *truep) != -1; ++truep)
{
if (sat_cout[ci] == 1) bbreakv++; //bbreakv 记录c子句0号文字变元所对应的为真出现的全体子句中,有一个真文字的子句个数。
//即得到v所关联的sat子句个数(v在子句中为唯一真文字)。翻转该文字能将该子句从sat变为unsat。
}
best_bbreak = bbreakv;
bestvar_array[0] = v;
bestvar_cout = 1;
// 在针对c子句的其它文字(每一个文字变元v)
for (k =1; k < clause_lit_count[c] ; ++k)
{
v = clause_lit[c][k].var_num;
truep = (cur_soln[v] == 1) ? var_poslit[v] : var_neglit[v];
bbreakv = 0;
for(;(ci = *truep) != -1; ++truep)
{
if( sat_count[ci] = 1)
{
if (bbreakv == best_bbreak) break; //对于第k个文字, bbreakv的值不超过0号文字的bbreakv值
++bbreakv;
}
}
if(ci != -1) continue; //从上述break跳出后,说明有可能大于现有的best_bbreak值,可以忽略掉;下面只考虑小于或等于的情形。
if (bbreakv < best_bbreak ) //考虑小于的情形
{
best_bbreak = bbreakv;
bestvar_array[0] = v; //该数组首元素一定寸bbreak值最小的文字变元
bestvar_count = 1;
}
else{ //if (bbreakv== best_bbreak) 考虑等于的情形
bestvar_array[bestvar_count] = v;
++bestvar_count;
}
}
//此时bestvar_array已经有值,值得个数为bestvar_count。
if ( best_bbreak!=0 && (rand()%MY_RAND_MAX_INT)*BASIC_SCALE < wp)
return clause_lit[c][rand()%clause_lit_count[c]].var_num;
}