📄 walksat.c
字号:
fprintf(stderr,"ERROR - too many atoms\n"); exit(-1); }#ifdef Huge clause = (int **) malloc(sizeof(int *)*(numclause+1)); size = (int *) malloc(sizeof(int)*(numclause+1)); false = (int *) malloc(sizeof(int)*(numclause+1)); lowfalse = (int *) malloc(sizeof(int)*(numclause+1)); wherefalse = (int *) malloc(sizeof(int)*(numclause+1)); numtruelit = (int *) malloc(sizeof(int)*(numclause+1));#else if(numclause > MAXCLAUSE) { fprintf(stderr,"ERROR - too many clauses\n"); exit(-1); } #endif freestore = 0; numliterals = 0; for(i = 0;i < 2*MAXATOM+1;i++) numoccurence[i] = 0; for(i = 0;i < numclause;i++) { size[i] = -1; if (freestore < MAXLENGTH) { storeptr = (int *) malloc( sizeof(int) * STOREBLOCK ); freestore = STOREBLOCK; fprintf(stderr,"allocating memory...\n"); } clause[i] = storeptr; do { size[i]++; if(size[i] > MAXLENGTH) { printf("ERROR - clause too long\n"); exit(-1); } if (scanf("%i ",&lit) != 1) { fprintf(stderr, "Bad input file\n"); exit(-1); } if(lit != 0) { *(storeptr++) = lit; /* clause[i][size[i]] = j; */ freestore--; numliterals++; numoccurence[lit+MAXATOM]++; } } while(lit != 0); } if(size[0] == 0) { fprintf(stderr,"ERROR - incorrect problem format or extraneous characters\n"); exit(-1); } for(i = 0;i < 2*MAXATOM+1;i++) { if (freestore < numoccurence[i]) { storeptr = (int *) malloc( sizeof(int) * STOREBLOCK ); freestore = STOREBLOCK; fprintf(stderr,"allocating memory...\n"); } occurence[i] = storeptr; freestore -= numoccurence[i]; storeptr += numoccurence[i]; numoccurence[i] = 0; } for(i = 0;i < numclause;i++) { for(j = 0;j < size[i];j++) { occurence[clause[i][j]+MAXATOM] [numoccurence[clause[i][j]+MAXATOM]] = i; numoccurence[clause[i][j]+MAXATOM]++; } }}void flipatom(int toflip){ int i, j; /* loop counter */ int toenforce; /* literal to enforce */ register int cli; register int lit; int numocc; register int sz; register int * litptr; int * occptr; /* printf("flipping %i\n", toflip); */ if (toflip == NOVALUE){ numnullflip++; return; } changed[toflip] = numflip; if(atom[toflip] > 0) toenforce = -toflip; else toenforce = toflip; atom[toflip] = 1-atom[toflip]; if (hamming_flag){ if (atom[toflip] == hamming_target[toflip]) hamming_distance--; else hamming_distance++; if ((numflip % hamming_sample_freq) == 0) fprintf(hamming_fp, "%i %i\n", numflip, hamming_distance); } numocc = numoccurence[MAXATOM-toenforce]; occptr = occurence[MAXATOM-toenforce]; for(i = 0; i < numocc ;i++) { /* cli = occurence[MAXATOM-toenforce][i]; */ cli = *(occptr++); if (--numtruelit[cli] == 0){ false[numfalse] = cli; wherefalse[cli] = numfalse; numfalse++; /* Decrement toflip's breakcount */ breakcount[toflip]--; if (makeflag){ /* Increment the makecount of all vars in the clause */ sz = size[cli]; litptr = clause[cli]; for (j=0; j<sz; j++){ /* lit = clause[cli][j]; */ lit = *(litptr++); makecount[ABS(lit)]++; } } } else if (numtruelit[cli] == 1){ /* Find the lit in this clause that makes it true, and inc its breakcount */ sz = size[cli]; litptr = clause[cli]; for (j=0; j<sz; j++){ /* lit = clause[cli][j]; */ lit = *(litptr++); if((lit > 0) == atom[ABS(lit)]){ breakcount[ABS(lit)]++; break; } } } } numocc = numoccurence[MAXATOM+toenforce]; occptr = occurence[MAXATOM+toenforce]; for(i = 0; i < numocc; i++) { /* cli = occurence[MAXATOM+toenforce][i]; */ cli = *(occptr++); if (++numtruelit[cli] == 1){ numfalse--; false[wherefalse[cli]] = false[numfalse]; wherefalse[false[numfalse]] = wherefalse[cli]; /* Increment toflip's breakcount */ breakcount[toflip]++; if (makeflag){ /* Decrement the makecount of all vars in the clause */ sz = size[cli]; litptr = clause[cli]; for (j=0; j<sz; j++){ /* lit = clause[cli][j]; */ lit = *(litptr++); makecount[ABS(lit)]--; } } } else if (numtruelit[cli] == 2){ /* Find the lit in this clause other than toflip that makes it true, and decrement its breakcount */ sz = size[cli]; litptr = clause[cli]; for (j=0; j<sz; j++){ /* lit = clause[cli][j]; */ lit = *(litptr++); if( ((lit > 0) == atom[ABS(lit)]) && (toflip != ABS(lit)) ){ breakcount[ABS(lit)]--; break; } } } }}int pickrandom(void){ int tofix; tofix = false[random()%numfalse]; return Var(tofix, random()%size[tofix]);}int pickbest(void){ int numbreak; int tofix; int clausesize; int i; int best[MAXLENGTH]; /* best possibility so far */ register int numbest; /* how many are tied for best */ register int bestvalue; /* best value so far */ register int var; tofix = false[random()%numfalse]; clausesize = size[tofix]; numbest = 0; bestvalue = BIG; for (i=0; i< clausesize; i++){ var = ABS(clause[tofix][i]); numbreak = breakcount[var]; if (numbreak<=bestvalue){ if (numbreak<bestvalue) numbest=0; bestvalue = numbreak; best[numbest++] = var; } } if (bestvalue>0 && (random()%denominator < numerator)) return ABS(clause[tofix][random()%clausesize]); if (numbest == 1) return best[0]; return best[random()%numbest];}int picknovelty(void){ int var, diff, birthdate; int youngest, youngest_birthdate, best, second_best, best_diff, second_best_diff; int tofix, clausesize, i; tofix = false[random()%numfalse]; clausesize = size[tofix]; if (clausesize == 1) return ABS(clause[tofix][0]); youngest_birthdate = -1; best_diff = -BIG; second_best_diff = -BIG; for(i = 0; i < clausesize; i++){ var = ABS(clause[tofix][i]); diff = makecount[var] - breakcount[var]; birthdate = changed[var]; if (birthdate > youngest_birthdate){ youngest_birthdate = birthdate; youngest = var; } if (diff > best_diff || (diff == best_diff && changed[var] < changed[best])) { /* found new best, demote best to 2nd best */ second_best = best; second_best_diff = best_diff; best = var; best_diff = diff; } else if (diff > second_best_diff || (diff == second_best_diff && changed[var] < changed[second_best])){ /* found new second best */ second_best = var; second_best_diff = diff; } } if (best != youngest) return best; if ((random()%denominator < numerator)) return second_best; return best;}int pickrnovelty(void){ int var, diff, birthdate; int diffdiff; int youngest, youngest_birthdate, best, second_best, best_diff, second_best_diff; int tofix, clausesize, i; tofix = false[random()%numfalse]; clausesize = size[tofix]; if (clausesize == 1) return ABS(clause[tofix][0]); if ((numflip % 100) == 0) return ABS(clause[tofix][random()%clausesize]); youngest_birthdate = -1; best_diff = -BIG; second_best_diff = -BIG; for(i = 0; i < clausesize; i++){ var = ABS(clause[tofix][i]); diff = makecount[var] - breakcount[var]; birthdate = changed[var]; if (birthdate > youngest_birthdate){ youngest_birthdate = birthdate; youngest = var; } if (diff > best_diff || (diff == best_diff && changed[var] < changed[best])) { /* found new best, demote best to 2nd best */ second_best = best; second_best_diff = best_diff; best = var; best_diff = diff; } else if (diff > second_best_diff || (diff == second_best_diff && changed[var] < changed[second_best])){ /* found new second best */ second_best = var; second_best_diff = diff; } } if (best != youngest) return best; diffdiff = best_diff - second_best_diff; if (numerator < 50 && diffdiff > 1) return best; if (numerator < 50 && diffdiff == 1){ if ((random()%denominator) < 2*numerator) return second_best; return best; } if (diffdiff == 1) return second_best; if ((random()%denominator) < 2*(numerator-50)) return second_best; return best;}int picktabu(void){ int numbreak[MAXLENGTH]; int tofix; int clausesize; int i; /* a loop counter */ int best[MAXLENGTH]; /* best possibility so far */ int numbest; /* how many are tied for best */ int bestvalue; /* best value so far */ int tabu_level; int val; int noisypick; tofix = false[random()%numfalse]; clausesize = size[tofix]; for(i = 0;i < clausesize;i++) numbreak[i] = breakcount[ABS(clause[tofix][i])]; numbest = 0; bestvalue = BIG; noisypick = (numerator > 0 && random()%denominator < numerator); for (i=0; i < clausesize; i++) { if (numbreak[i] == 0) { if (bestvalue > 0) { bestvalue = 0; numbest = 0; } best[numbest++] = i; } else if (tabu_length < numflip - changed[ABS(clause[tofix][i])]) { if (noisypick && bestvalue > 0) { best[numbest++] = i; } else { if (numbreak[i] < bestvalue) { bestvalue = numbreak[i]; numbest = 0; } if (numbreak[i] == bestvalue) { best[numbest++] = i; } } } } if (numbest == 0) return NOVALUE; if (numbest == 1) return Var(tofix, best[0]); return (Var(tofix, best[random()%numbest]));}int countunsat(void) { int i, j, unsat, bad, lit, sign; unsat = 0; for (i=0;i < numclause;i++) { bad = TRUE; for (j=0; j < size[i]; j++) { lit = clause[i][j]; sign = lit > 0 ? 1 : 0; if ( atom[ABS(lit)] == sign ) { bad = FALSE; break; } } if (bad) unsat++; } return unsat; }#ifdef NTdouble elapsed_seconds(void) { return 0.0; }#elsedouble elapsed_seconds(void){ double answer; static struct tms prog_tms; static long prev_times = 0; (void) times(&prog_tms); answer = ((double)(((long)prog_tms.tms_utime)-prev_times))/((double) CLK_TCK); prev_times = (long) prog_tms.tms_utime; return answer;}#endifvoid print_sol_cnf(void){ int i; for(i = 1;i < numatom+1;i++) printf("v %i\n", solution[i] == 1 ? i : -i);}voidprint_low_assign(long int lowbad){ int i; printf("Begin assign with lowest # bad = %d\n", lowbad); for (i=1; i<=numatom; i++){ printf(" %d", lowatom[i]==0 ? -i : i); if (i % 10 == 0) printf("\n"); } if ((i-1) % 10 != 0) printf("\n"); printf("End assign\n");}voidprint_current_assign(void){ int i; printf("Begin assign at flip = %d\n", numflip); for (i=1; i<=numatom; i++){ printf(" %d", atom[i]==0 ? -i : i); if (i % 10 == 0) printf("\n"); } if ((i-1) % 10 != 0) printf("\n"); printf("End assign\n");}voidsave_low_assign(void){ int i; for (i=1; i<=numatom; i++) lowatom[i] = atom[i];}voidsave_solution(void){ int i; for (i=1; i<=numatom; i++) solution[i] = atom[i];}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -