Armin Biere Institute for Formal Models and Verification Johannes Kepler University Linz
| Abstract—This paper serves as solver description for the SAT solvers Lingeling and its two parallel variants Treengeling and Plingeling, as well as for our new local search solver YalSAT entering the Competition 2014. For Lingeling and its variants we only list important differences to earlier version of these solvers as used in the SAT Competition 2013. For further information we refer to the solver description [1] of the SAT Competition 2013 or source code. | |
|
YALSAT Recent SAT competitions witnessed a new generation of several efficient local search solvers including Sparrow [2] and ProbSAT [3], which surprisingly were able to solve some non-random instances. Fascinated by this success and the simplicity of the ProbSAT solver [3] we started to implement Yet Another Local Search SAT Solver (YalSAT). At its core it implements several variants of ProbSAT’s algorithm and recent extensions [4]. These variants are selected randomly at restarts, scheduled by a reluctant doubling scheme (Luby).
Beside initializing the assignment at each restart with a randomly picked assignment among previously saved best assignments within one restart round, it is also possible to assign all variables to false, to true or to a random value. 译文:除了在每次重新启动时使用在一个重新启动轮内先前保存的最佳赋值中随机挑选的赋值来初始化赋值外,还可以将所有变量分配为false、true或随机值。
At each restart the submitted version further varies the base cbk for the exponential score distribution between either using the original base values of ProbSAT, where k is determined by the maximum length of the clause in the instance, or using the default of cbk = 2. 译文:在每次重新启动时,提交的版本会进一步改变指数分数分布的基准cbk,使用原始的ProbSAT基准值(其中k由实例中子句的最大长度决定),或者使用cbk = 2的默认值。
Then clause weights are either chosen to be the same for all clauses or are chosen as linear function depending on the clause length (with either larger clauses having larger weight or alternatively smaller clauses). The maximum weight is also picked randomly. 译文:然后将子句权重选择为对所有子句相同,或者根据子句长度选择为线性函数(较大的子句权重较大,或者较小的子句权重较小)。最大权值也是随机选取的。 With this set-up we were able to solve a surprisingly large number of satisfiable crafted instances from last year’s competition.译文:通过这种设置,我们能够解决去年比赛中大量令人满意的制作实例。 For uniform random instances YalSAT is supposed to work almost identical to last year’s version of ProbSAT。译文:对于统一随机实例,YalSAT应该与去年版本的ProbSAT运行起来几乎完全相同 |
|
代码sparrow.c v 2014 解读
|
/** |
|
一、基本函数原型和调用关系
二、基本数据成员
1 #define MAXCLAUSELENGTH 20000 //maximum number of literals per clause 2 #define STOREBLOCK 200000 3 4 # undef LLONG_MAX 5 #define LLONG_MAX 9223372036854775807 6 #define BIGINT long long int 7 #define MAXSCORE 300 8 #define getScore(VAR) (score[VAR]) 9 #define setScore(VAR,VAL) (score[VAR]=VAL) 10 #define adjScore(VAR,VAL) (score[VAR]+=VAL) 11 12 #define incScore(VAR,CLS) (score[VAR]+=clauseWeight[CLS]) 13 #define decScore(VAR,CLS) (score[VAR]-=clauseWeight[CLS]) 14 #define BASECW 1 //base clause weight, when score used 1 15 #define GETOCCPOS(L) (2*abs(L)-(L<0)) //文字-1对应标号1;文字+1对应2 16 17 /*--------*/ 18 19 int (*pickClause)() = NULL; //函数指针 20 21 /*----Instance data (independent from assignment)----*/ 22 /** The numbers of variables. */ 23 int numVars; 24 /** The number of clauses. */ 25 int numClauses; 26 /** The number of literals. */ 27 int numLiterals; 28 /** The value of the variables. The numbering starts at 1 and the possible values are 0 or 1. */ 29 char *atom; //变元的赋值 30 /** The clauses of the formula represented as: clause[clause_number][literal_number]. 31 * The clause and literal numbering start both at 0.*/ 32 int **clause; 33 /**min and max clause length*/ 34 int maxClauseSize; 35 int minClauseSize; 36 /** The number of occurrence of each literal.*/ 37 int *numOccurrence; 38 /** The clauses where each literal occurs. For literal i : occurrence[i+MAXATOMS][j] gives the clause = 39 * the j'th occurrence of literal i. */ 40 int **occurrence; 41 int maxNumOccurences = 0; //maximum number of occurences for a literal
|
|
三、函数解析
1.parsefile
1 void parseFile() { 2 register int i, j; 3 int lit, r, clauseSize; 4 int tatom; 5 char c; 6 int totalOcc=0; 7 long filePos; 8 int numNeighbours, cla, var; 9 int *clptr; 10 fp = NULL; 11 fp = fopen(fileName, "r"); 12 if (fp == NULL) { 13 fprintf(stderr, "c Error: Not able to open the file: %s", fileName); 14 exit(-1); 15 } 16 17 // Start scanning the header and set numVars and numClauses 18 for (;;) { 19 c = fgetc(fp); 20 if (c == 'c') //comment line - skip content 21 do { 22 c = fgetc(fp); //read the complete comment line until a eol is detected. 23 } while ((c != '\n') && (c != EOF)); 24 else if (c == 'p') { //p-line detected 25 if ((fscanf(fp, "%*s %d %d", &numVars, &numClauses))) //%*s should match with "cnf" 26 break; 27 break; 28 } else { 29 fprintf(stderr, "c No parameter line found! Computing number of atoms and number of clauses from file!\n"); 30 r = fseek(fp, -1L, SEEK_CUR); //try to unget c 31 if (r == -1) { 32 fprintf(stderr, "c Error: Not able to seek in file: %s", fileName); 33 exit(-1); 34 } 35 filePos = ftell(fp); 36 if (r == -1) { 37 fprintf(stderr, "c Error: Not able to obtain position in file: %s", fileName); 38 exit(-1); 39 } 40 41 numVars = 0; 42 numClauses = 0; 43 for (; fscanf(fp, "%i", &lit) == 1;) { 44 if (lit == 0) 45 numClauses++; 46 else { 47 tatom = abs(lit); 48 if (tatom > numVars) 49 numVars = tatom; 50 } 51 } 52 fprintf(stderr, "c scanned numVars: %d numClauses: %d\n", numVars, numClauses); 53 54 r = fseek(fp, filePos, SEEK_SET); //try to rewind the file to the beginning of the formula 55 if (r == -1) { 56 fprintf(stderr, "c Error: Not able to seek in file: %s", fileName); 57 exit(-1); 58 } 59 60 break; 61 } 62 } 63 // Finished scanning header. 64 //allocating memory to use! 65 allocateMemory(); 66 maxClauseSize = 0; 67 minClauseSize = MAXCLAUSELENGTH; 68 int *numOccurrenceT = (int*) malloc(sizeof(int) * (numLiterals + 1)); 69 70 int freeStore = 0; 71 int *tempClause = 0; 72 73 for (i = 0; i < numLiterals + 1; i++) { 74 numOccurrence[i] = 0; 75 numOccurrenceT[i] = 0; 76 } 77 78 for (i = 1; i <= numClauses; i++) { 79 if (freeStore < MAXCLAUSELENGTH) { 80 tempClause = (int*) malloc(sizeof(int) * STOREBLOCK); 81 freeStore = STOREBLOCK; 82 } 83 clause[i] = tempClause; 84 clauseSize = 0; 85 do { 86 r = fscanf(fp, "%i", &lit); 87 if (lit != 0) { 88 clauseSize++; 89 *tempClause++ = lit; 90 numOccurrenceT[GETOCCPOS(lit)]++; 91 if (numOccurrenceT[GETOCCPOS(lit)] > maxNumOccurences) 92 maxNumOccurences = numOccurrenceT[GETOCCPOS(lit)]; 93 totalOcc++; 94 } else { 95 *tempClause++ = 0; //0 sentinel as literal! 96 } 97 freeStore--; 98 } while (lit != 0); 99 if (clauseSize > maxClauseSize) 100 maxClauseSize = clauseSize; 101 if (clauseSize < minClauseSize) 102 minClauseSize = clauseSize; 103 } 104 105 106 occurrence[0] = (int*) malloc(sizeof(int) * (totalOcc + numLiterals+2)); 107 int occpos=0; 108 for (i = 0; i < numLiterals + 1; i++) { 109 occurrence[i] = (occurrence[0]+occpos); 110 occpos+=numOccurrenceT[i] + 1; 111 } 112 113 for (i = 1; i <= numClauses; i++) { 114 j = 0; 115 while ((lit = clause[i][j])) { 116 occurrence[GETOCCPOS(lit)][numOccurrence[GETOCCPOS(lit)]++] = i; 117 j++; 118 } 119 } 120 //end occurrence array with a sentinel 121 for (lit=1;lit<=numVars;lit++){ 122 occurrence[GETOCCPOS(lit)][numOccurrence[GETOCCPOS(lit)]] = 0; 123 occurrence[GETOCCPOS(-lit)][numOccurrence[GETOCCPOS(-lit)]] = 0; 124 } 125 126 //Now the maximum size of a clause is determined! 127 probs = (double*) malloc(sizeof(double) * (maxClauseSize + 1)); 128 129 //Constructing the neighbor array from the occurrence-arrays . 130 freeStore = 0; 131 int *tempNeighbour = 0; 132 int isNeighbour[numVars + 1]; //isNeighbour[j]=i means that j is a neighbor-var of i. 133 int *occptr; 134 for(i = 1; i <= numVars; i++) 135 isNeighbour[i] = 0; 136 for (i = 1; i <= numVars; i++) { 137 numNeighbours = 0; 138 //first take a look at all positive occurrences of i 139 //for (j = 0; j < numOccurrence[GETOCCPOS(i)]; j++) { 140 occptr = &occurrence[GETOCCPOS(i)][0]; 141 while ((cla = *occptr)){ 142 //cla = occurrence[GETOCCPOS(i)][j]; 143 clptr = &clause[cla][0]; 144 while ((var = abs(*clptr))) { 145 if ((isNeighbour[var] != i) && (var != i)) { //if it is not all ready marked as a neighbor of i mark it. 146 isNeighbour[var] = i; 147 numNeighbours++; 148 } 149 clptr++; 150 } 151 occptr++; 152 } 153 //then take a look at all negative occurrence of i 154 //for (j = 0; j < numOccurrence[GETOCCPOS(-i)]; j++) { 155 occptr = &occurrence[GETOCCPOS(-i)][0]; 156 while ((cla = *occptr)){ 157 //cla = occurrence[GETOCCPOS(-i)][j]; 158 clptr = &clause[cla][0]; 159 while ((var = abs(*clptr))) { 160 if ((isNeighbour[var] != i) && (var != i)) { //if it is not all ready marked as a neighbor of i mark it. 161 isNeighbour[var] = i; 162 numNeighbours++; 163 } 164 clptr++; 165 } 166 occptr++; 167 } 168 if (freeStore < numNeighbours + 1) { 169 tempNeighbour = (int*) malloc(sizeof(int) * STOREBLOCK); 170 freeStore = STOREBLOCK; 171 } 172 neighbourVar[i] = tempNeighbour; 173 freeStore -= numNeighbours + 1; 174 if (numNeighbours >= 1) { 175 for (j = 1; j <= numVars; j++) { 176 if (isNeighbour[j] == i) { 177 *(tempNeighbour++) = j; 178 numNeighbours--; 179 if (numNeighbours == 0) { 180 *(tempNeighbour++) = 0; 181 break; 182 } 183 } 184 } 185 } else 186 *(tempNeighbour++) = 0; 187 } 188 free(numOccurrenceT); 189 fclose(fp); 190 191 }
|
|
2.init()
1 void init() { 2 static int initialized=0; 3 register int i; 4 int critLit = 0, lit; 5 int *clptr; 6 ticks_per_second = sysconf(_SC_CLK_TCK); 7 statNumGWalks = 0; //how often a gradient walk was done 8 statNumSmooth = 0; //how often a smoothing has been done. 9 statNumWeight = 0; //how often a smoothing has been done. 10 statXOROps = 0; 11 statClSearch=0; 12 numFalse = 0; 13 numWeight = 0; 14 15 for (i = 1; i <= numVars; i++) { 16 if ((!keep_assig)||(!initialized)){//new assigment should be generated 17 atom[i] = rand() % 2; 18 } 19 score[i] = 0; 20 varLastChange[i] = -1; //-1 means never changed 21 } 22 initialized = !initialized; 23 //pass trough all clauses and apply the assignment previously generated 24 for (i = 1; i <= numClauses; i++) { 25 clptr = & clause[i][0]; 26 numTrueLit[i] = 0; 27 whereWeight[i] = -1; 28 whereFalseOrCritVar[i] = 0; 29 while ((lit = *clptr)) { 30 if (atom[abs(lit)] == (lit > 0)) { 31 numTrueLit[i]++; 32 critLit = lit; 33 #ifdef XOR 34 whereFalseOrCritVar[i] ^= abs(lit); 35 #endif 36 } 37 clptr++; 38 } 39 if (numTrueLit[i] == 1) { 40 //if the clause has only one literal that causes it to be sat, 41 //then this var. will break the sat of the clause if flipped. 42 #ifndef XOR 43 whereFalseOrCritVar[i] = abs(critLit); 44 #endif 45 score[abs(critLit)]--; 46 } else if (numTrueLit[i] == 0) { 47 //add this clause to the list of unsat caluses. 48 falseClause[numFalse] = i; 49 whereFalseOrCritVar[i] = numFalse; 50 numFalse++; 51 52 //if the clause is unsat fliping any variable from it will make it sat 53 //-> increase the score of all variables within this clause 54 clptr = & clause[i][0]; 55 while ((lit = *clptr)) { 56 score[abs(lit)]++; 57 clptr++; 58 } 59 } 60 clauseWeight[i] = BASECW; 61 } 62 numDecVar = 0; 63 //add all variables that are decreasing to the list of decreasing variables. 64 for (i = 1; i <= numVars; i++) 65 if (getScore(i) > 0) { 66 decVar[numDecVar] = i; 67 numDecVar++; 68 isCandVar[i] = 1; 69 } else { 70 isCandVar[i] = 0; 71 } 72 }
|
|
3. smooth2()
1 void smooth2() { //for all weighted !!!satisfied!!! clauses decrease the score by 1 2 register int i, c, var; 3 for (i = 0; i < numWeight; i++) { 4 c = weightedClause[i]; 5 if (numTrueLit[c] > 0) { 6 if (--clauseWeight[c] == BASECW) { //remove from the list of weighted clauses 7 numWeight--; 8 weightedClause[i] = weightedClause[numWeight]; 9 whereWeight[weightedClause[i]] = i; 10 whereWeight[c] = -1; 11 i--; 12 } 13 if (numTrueLit[c] == 1) { 14 var = whereFalseOrCritVar[c]; 15 //clause lost one weight and whereFalse had this weight as negative, so we have to add one to the weigth of var 16 adjScore(var, 1); 17 if ((getScore(var) > 0) && (!isCandVar[var]) && (varLastChange[var] < flip - 1)) { 18 isCandVar[var] = 1; 19 decVar[numDecVar] = var; 20 numDecVar++; 21 } 22 } 23 } 24 } 25 statNumSmooth++; 26 }
|
|
4. updateWeights()
1 void updateWeights() { //for all unsat clauses increase the weight by 1. 2 statNumWeight++; 3 int i, j; 4 int c, var; 5 for (i = 0; i < numFalse; i++) { 6 c = falseClause[i]; 7 clauseWeight[c]++; 8 if ((whereWeight[c] == -1) && (clauseWeight[c] > BASECW)) { //add to the list of weigthedClause 9 weightedClause[numWeight] = c; 10 whereWeight[c] = numWeight; 11 numWeight++; 12 } 13 j = 0; 14 while ((var = abs(clause[c][j]))) { 15 score[var]++; 16 if ((!isCandVar[var]) && (getScore(var) > 0) && (varLastChange[var] < flip - 1)) { 17 isCandVar[var] = 1; 18 decVar[numDecVar] = var; 19 numDecVar++; 20 } 21 j++; 22 } 23 } 24 }
|
|
5.pickVar()
1 void pickVar() { 2 register int i, j; 3 int var; 4 int bestScore = -numClauses; 5 double probAge = 1.0, baseAge; 6 int varChanged = -1; 7 int scoreVar; 8 int *clptr; 9 int rClause; //randomly choosen clause. 10 //g2Wsat part - the greedy part - if there is a variable that decreases the number of variables then choose the best one. 11 12 if (numDecVar > 0) { 13 //find the variable with the best score, and the following variable with same score. 14 for (i = 0; i < numDecVar; i++) { 15 var = decVar[i]; 16 scoreVar = getScore(var); 17 if (scoreVar > 0) { 18 if (bestScore < scoreVar) { 19 bestScore = scoreVar; 20 bestVar = var; 21 varChanged = varLastChange[var]; 22 } else if (bestScore == scoreVar) //found one with the same score 23 if (varLastChange[var] < varChanged) { //check if it is younger 24 bestVar = var; //this var being younger is chosen. 25 varChanged = varLastChange[var]; 26 } 27 } else { 28 numDecVar--; 29 decVar[i] = decVar[numDecVar]; 30 //whereDecVar[decVar[numDecVar]]=i; 31 isCandVar[var] = 0; 32 i--; 33 } 34 } 35 } 36 37 if (bestScore != -numClauses) { 38 statNumGWalks++; 39 } else { 40 //new probability distribution replacing adaptNovelty+ 41 //a variable is YOUNG if it was flipped not long time ago 42 //a variable is OLD if it was flipped long ago in the past, or not at all 43 rClause = falseClause[pickClause()]; 44 double sumProb = 0; 45 i = 0; 46 clptr = &clause[rClause][0]; 47 while ((var = abs(*clptr))) { 48 scoreVar = getScore(var); 49 if (scoreVar < -300) //has to be limited because the score is weighted 50 probs[i] = scorePow[300]; 51 else { 52 if (scoreVar > 0) { 53 probs[i] = 1.0; 54 } else { 55 probs[i] = scorePow[abs(scoreVar)]; 56 } 57 } 58 baseAge = (double) (flip - varLastChange[var]) * inv_c3; 59 for (j = 0, probAge = 1.0; j < c2; j++) 60 probAge *= baseAge; 61 probAge += 1.0; 62 probs[i] *= probAge; 63 sumProb += probs[i]; 64 i++; 65 clptr++; 66 } 67 double randPosition = (double) (rand()) / (RAND_MAX+1.0) * sumProb; 68 for (i = i-1; i!=0; i--) { 69 sumProb -= probs[i]; 70 if (sumProb <= randPosition) 71 break; 72 } 73 74 75 bestVar = abs(clause[rClause][i]); 76 77 if (sp < 1000) { 78 if (rand() % 1000 < sp) 79 smooth2(); 80 else 81 updateWeights(); 82 } 83 } 84 return; 85 }
|
|
6.flipAtom()
1 void flipAtom() { 2 int var; 3 int *ocptr; //occurrence pointer 4 int *clptr; //clause pointer 5 int tClause; //temporary clause variable 6 int xMakesSat; //tells which literal of x will make the clauses where it appears sat. 7 if (atom[bestVar] == 1) 8 xMakesSat = -bestVar; //if x=1 then all clauses containing -x will be made sat after fliping bestVar 9 else 10 xMakesSat = bestVar; //if x=0 then all clauses containing x will be made sat after fliping bestVar 11 12 atom[bestVar] = 1 - atom[bestVar]; 13 //all Neighbours of x with score>0 are considered candVars without taking into account if they are in decVar or not. 14 //trough this mechanism we can avoid that a variable that was fliped and increased the number of false variable is added to the 15 //decVar array - this variable is not promissing. 16 17 clptr=&neighbourVar[bestVar][0]; 18 while ((var = abs(*clptr))) { 19 isCandVar[var] = (getScore(var) > 0); 20 clptr++; 21 } 22 23 //1. all clauses that contain the literal xMakesSat will become SAT, if they where not already sat. 24 ocptr=&occurrence[GETOCCPOS(xMakesSat)][0]; 25 while ((tClause = *ocptr)) { 26 //tClause = occurrence[xMakesSat + numVars][i]; 27 //if the clause is unsat it will become SAT so it has to be removed from the list of unsat-clauses. 28 if (numTrueLit[tClause] == 0) { 29 //remove from unsat-list 30 falseClause[whereFalseOrCritVar[tClause]] = falseClause[--numFalse]; //overwrite this clause with the last clause in the list. 31 whereFalseOrCritVar[falseClause[numFalse]] = whereFalseOrCritVar[tClause]; 32 whereFalseOrCritVar[tClause] = 0; 33 #ifndef XOR 34 whereFalseOrCritVar[tClause] = bestVar; //this variable is now critically responsible for satisfying tClause 35 #endif 36 //adapt the scores of the variables 37 //the score of x has to be decreased by one because x is critical and will break this clause if fliped. 38 decScore(bestVar, tClause); 39 //the scores of all variables from tClause have to be decreased by one because tClause is not UNSAT any more 40 //j = 0; 41 statinc0++; 42 clptr= &clause[tClause][0]; 43 while ((var = abs(*clptr))) { 44 decScore(var, tClause); 45 //j++; 46 clptr++; 47 } 48 } else { 49 //if the clause is satisfied by only one literal then the score has to be increased by one for this var. 50 //because fliping this variable will no longer break the clause 51 if (numTrueLit[tClause] == 1) { 52 incScore(whereFalseOrCritVar[tClause], tClause); 53 statinc1++; 54 } 55 } 56 //if the number of numTrueLit[tClause]>=2 then nothing will change in the scores 57 numTrueLit[tClause]++; //the number of true Lit is increased. 58 statinc2++; 59 #ifdef XOR 60 whereFalseOrCritVar[tClause] ^= bestVar; 61 #endif 62 ocptr++; 63 } 64 65 //2. all clauses that contain the literal -xMakesSat=0 will not be longer satisfied by variable x. 66 //all this clauses contained x as a satisfying literal 67 //i = 0; 68 ocptr=&occurrence[GETOCCPOS(-xMakesSat)][0]; 69 while ((tClause = *ocptr)) { 70 #ifdef XOR 71 whereFalseOrCritVar[tClause] ^= bestVar; 72 #endif 73 if (numTrueLit[tClause] == 1) { //then xMakesSat=1 was the satisfying literal. 74 //this clause gets unsat. 75 falseClause[numFalse] = tClause; 76 whereFalseOrCritVar[tClause] = numFalse; 77 numFalse++; 78 //the score of x has to be increased by one because it is not breaking any more for this clause. 79 incScore(bestVar, tClause); 80 statdec1++; 81 //the scores of all variables have to be increased by one ; inclusive x because flipping them will make the clause again sat 82 83 clptr = &clause[tClause][0]; 84 while ((var = abs(*clptr))) { 85 incScore(var, tClause); 86 clptr++; 87 } 88 } else if (numTrueLit[tClause] == 2) { //find which literal is true and make it critical and decrease its score 89 statdec2++; 90 #ifdef XOR 91 decScore(whereFalseOrCritVar[tClause],tClause); 92 #else 93 clptr = &clause[tClause][0]; 94 while ((var = abs(*clptr))) { 95 statClSearch++; 96 if (((*clptr > 0) == atom[var])) { //x can not be the var anymore because it was flipped //&&(xMakesSat!=var) 97 whereFalseOrCritVar[tClause] = var; 98 decScore(var, tClause); 99 break; 100 } 101 clptr++; 102 } 103 #endif 104 } 105 numTrueLit[tClause]--; 106 statdec3++; 107 ocptr++; 108 } 109 110 //acoordant to G2WSAT only the scores of variables within neighbourVar[x] have changed. 111 clptr= &neighbourVar[bestVar][0]; 112 while ((var = *clptr)) { 113 if ((getScore(var) > 0) && (!isCandVar[var])) { //is not in the list of decreasing variables 114 //add to decVar 115 decVar[numDecVar] = var; 116 //whereDecVar[var]=numDecVar; 117 numDecVar++; 118 } 119 clptr++; 120 } 121 }
|
|
7.main()
1 int main(int argc, char *argv[]) { 2 tryTime = 0.; 3 parseParameters(argc, argv); 4 setCpuLimit(); 5 parseFile(); 6 printFormulaProperties(); 7 setupSparrowParameters(); //call only after parsing file!!! 8 //Initialize the look up table of Sparrow 9 initSparrow(); 10 setupSignalHandler(); 11 printSolverParameters(); 12 srand(seed); 13 14 allowedFlips = maxFlips; 15 16 for (tryn = 0; tryn < maxTries; tryn++) { 17 init(); 18 bestNumFalse = numClauses; 19 if (use_luby) { 20 maxFlips = luby() * luby_base; 21 sp = sparray[tryn%num_sp]; 22 //fprintf(stderr, "c sp= %4d next restart after %4lld * %6d = %7lld flips\n", sp, maxFlips / luby_base, luby_base, maxFlips); 23 } 24 for (flip = 1; flip <= maxFlips; flip++) { 25 if (numFalse == 0) 26 break; 27 pickVar(); 28 flipAtom(); 29 varLastChange[bestVar] = flip; 30 printStatsEndFlip(); //update bestNumFalse 31 totalFlips++; 32 if (totalFlips >= allowedFlips){ 33 maxTries = 0; 34 break; 35 } 36 37 } 38 tryTime = elapsed_seconds(); 39 totalTime += tryTime; 40 if (numFalse == 0) { 41 if (!checkAssignment()) { 42 fprintf(stderr, "c ERROR the assignment is not valid!"); 43 printf("c UNKNOWN"); 44 return 0; 45 } else { 46 printEndStatistics(); 47 printf("s SATISFIABLE\n"); 48 if (printSol == 1) 49 printSolution1line(); 50 return 10; 51 } 52 } else{; 53 //fprintf(stderr,"c UNKNOWN best(%4d) current(%4d) (%-15.5fsec)\n", bestNumFalse, numFalse, tryTime); 54 } 55 } 56 fprintf(stderr,"c UNKNOWN best(%4d) current(%4d) (%-15.5fsec)\n", bestNumFalse, numFalse, tryTime); 57 printEndStatistics(); 58 if (maxTries > 1) 59 fprintf(stderr, "c %-30s: %-8.3fsec\n", "Mean time per try", totalTime / (double) tryn); 60 return 0; 61 }
|
|
浙公网安备 33010602011771号