00001
00002
00003
00004
00005
00006
00007
00008
00009 #define MAXATOM 100000
00010
00011 #ifdef Huge
00012 #define STOREBLOCK 2000000
00013 #else
00014 #define STOREBLOCK 1000000
00015 #define MAXCLAUSE 500000
00016 #endif
00017
00018 #define TRUE 1
00019 #define FALSE 0
00020
00021 #define BIG 100000000
00022
00023 #define MAXLENGTH 1000
00024
00025 #define RANDOM 0
00026 #define PRODUCTSUM 1
00027 #define RECIPROCAL 2
00028 #define ADDITIVE 3
00029 #define BEST 4
00030 #define EXPONENTIAL 5
00031 #define TABU 6
00032
00033 #define NOVALUE -1
00034
00035 #define INIT_PARTIAL 1
00036
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039 #include <math.h>
00040 #include <sys/time.h>
00041 #include <sys/resource.h>
00042 #include <signal.h>
00043
00044
00045 static int scratch;
00046 #define abs(x) ((scratch=(x))>0?scratch: -scratch)
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 int numatom;
00059 int numclause;
00060 int numliterals;
00061
00062 #ifdef Huge
00063 int ** clause;
00064
00065 int * cost;
00066 int * size;
00067 int * false;
00068 int * wherefalse;
00069 int * numtruelit;
00070 #else
00071 int * clause[MAXCLAUSE];
00072
00073 int cost[MAXCLAUSE];
00074 int size[MAXCLAUSE];
00075 int false[MAXCLAUSE];
00076 int lowfalse[MAXCLAUSE];
00077 int wherefalse[MAXCLAUSE];
00078 int numtruelit[MAXCLAUSE];
00079 #endif
00080
00081 int *occurence[2*MAXATOM+1];
00082
00083
00084 int numoccurence[2*MAXATOM+1];
00085
00086
00087 int atom[MAXATOM+1];
00088 int lowatom[MAXATOM+1];
00089
00090 int changed[MAXATOM+1];
00091
00092 int breakcost[MAXATOM+1];
00093
00094 int numfalse;
00095 int costofnumfalse;
00096
00097
00098 int costexpected = FALSE;
00099 int abort_flag;
00100
00101 int heuristic;
00102 int numerator;
00103 int denominator;
00104 int tabu_length;
00105
00106 long int numflip;
00107 long int numnullflip;
00108
00109
00110 int highestcost=1;
00111 int eqhighest=0;
00112 int numhighest=0;
00113
00114 int hard=0;
00115
00116 int selecthigh(int);
00117
00118 double elapsed_seconds(void);
00119 int countunsat(void);
00120 void countlowunsatcost( int *, int *);
00121 void scanone(int argc, char *argv[], int i, int *varptr);
00122 void init(char initfile[], int initoptions);
00123 void initprob(void);
00124 void fix(int tofix);
00125 void flipatom(int toflip);
00126 int pickzero(int *numbreak,int clausesize);
00127
00128 int pickweight(int *weight,int clausesize);
00129
00130 void print_false_clauses_cost(long int lowbad);
00131 void print_low_assign(long int lowbad);
00132 void save_low_assign(void);
00133
00134 int pickrandom(int *numbreak,int clausesize, int tofix);
00135 int pickproductsum(int *numbreak,int clausesize, int tofix);
00136 int pickreciprocal(int *numbreak,int clausesize, int tofix);
00137 int pickadditive(int *numbreak,int clausesize, int tofix);
00138 int pickbest(int *numbreak,int clausesize, int tofix);
00139 int pickexponential(int *numbreak,int clausesize, int tofix);
00140 int pickfair(int *numbreak,int clausesize, int tofix);
00141 int picktabu(int *numbreak,int clausesize, int tofix);
00142
00143 void handle_interrupt(int sig);
00144
00145 long super(int i);
00146
00147 int main(int argc,char *argv[])
00148 {
00149 int i;
00150 int j;
00151 int k;
00152 char initfile[100] = { 0 };
00153 int numrun = 10;
00154 int cutoff = 100000;
00155 int base_cutoff = 100000;
00156 int printonlysol = FALSE;
00157 int printsolcnf = FALSE;
00158 int printfalse = FALSE;
00159 int printlow = FALSE;
00160 int initoptions = FALSE;
00161 int superlinear = FALSE;
00162 int printtrace = FALSE;
00163 long int totalflip = 0;
00164 long int totalsuccessflip = 0;
00165 int numtry = 0;
00166 int numsuccesstry = 0;
00167 int numsol = 1;
00168 int tochange;
00169 int seed;
00170 struct timeval tv;
00171 struct timezone tzp;
00172 double expertime;
00173 long flips_this_solution;
00174 long int lowbad;
00175 long int lowcost;
00176 int targetcost = 0;
00177 long x;
00178 long integer_sum_x = 0;
00179 double sum_x = 0.0;
00180 double sum_x_squared = 0.0;
00181 double mean_x;
00182 double second_moment_x;
00183 double variance_x;
00184 double std_dev_x;
00185 double std_error_mean_x;
00186 double seconds_per_flip;
00187 int r;
00188 int sum_r = 0;
00189 double sum_r_squared = 0.0;
00190 double mean_r;
00191 double variance_r;
00192 double std_dev_r;
00193 double std_error_mean_r;
00194 int worst_cost, computed_cost;
00195
00196 gettimeofday(&tv,&tzp);
00197 seed = (( tv.tv_sec & 0177 ) * 1000000) + tv.tv_usec;
00198 heuristic = BEST;
00199 numerator = NOVALUE;
00200 denominator = 100;
00201
00202 for (i=1;i < argc;i++)
00203 {
00204 if (strcmp(argv[i],"-withcost") == 0)
00205 costexpected = TRUE;
00206 else if (strcmp(argv[i],"-seed") == 0)
00207 scanone(argc,argv,++i,&seed);
00208 else if (strcmp(argv[i],"-targetcost") == 0)
00209 scanone(argc,argv,++i,&targetcost);
00210 else if (strcmp(argv[i],"-cutoff") == 0)
00211 scanone(argc,argv,++i,&cutoff);
00212 else if (strcmp(argv[i],"-random") == 0)
00213 heuristic = RANDOM;
00214 else if (strcmp(argv[i],"-productsum") == 0)
00215 heuristic = PRODUCTSUM;
00216 else if (strcmp(argv[i],"-reciprocal") == 0)
00217 heuristic = RECIPROCAL;
00218 else if (strcmp(argv[i],"-additive") == 0)
00219 heuristic = ADDITIVE;
00220 else if (strcmp(argv[i],"-exponential") == 0)
00221 heuristic = EXPONENTIAL;
00222 else if (strcmp(argv[i],"-best") == 0)
00223 heuristic = BEST;
00224 else if (strcmp(argv[i],"-noise") == 0)
00225 {
00226 scanone(argc,argv,++i,&numerator);
00227 scanone(argc,argv,++i,&denominator);
00228 }
00229 else if (strcmp(argv[i],"-init") == 0 && i < argc-1)
00230 sscanf(argv[++i], " %s", initfile);
00231 else if (strcmp(argv[i],"-partial") == 0)
00232 initoptions = INIT_PARTIAL;
00233 else if (strcmp(argv[i],"-super") == 0)
00234 superlinear = TRUE;
00235 else if (strcmp(argv[i],"-tries") == 0)
00236 scanone(argc,argv,++i,&numrun);
00237 else if (strcmp(argv[i],"-tabu") == 0)
00238 {
00239 scanone(argc,argv,++i,&tabu_length);
00240 heuristic = TABU;
00241 }
00242 else if (strcmp(argv[i],"-low") == 0)
00243 printlow = TRUE;
00244 else if (strcmp(argv[i],"-sol") == 0)
00245 {
00246 printonlysol = TRUE;
00247 printlow = TRUE;
00248 }
00249 else if (strcmp(argv[i],"-bad") == 0)
00250 printfalse = TRUE;
00251 else if (strcmp(argv[i],"-hard") == 0)
00252 hard = TRUE;
00253 else if (strcmp(argv[i],"-numsol") == 0)
00254 scanone(argc,argv,++i,&numsol);
00255 else if (strcmp(argv[i],"-trace") == 0)
00256 scanone(argc,argv,++i,&printtrace);
00257 else
00258 {
00259 fprintf(stderr, "Bad argument %s\n", argv[i]);
00260 fprintf(stderr, "General parameters:\n");
00261 fprintf(stderr, " -seed N -cutoff N -tries N\n");
00262 fprintf(stderr, " -numsol N = stop after finding N solutions\n");
00263 fprintf(stderr, " -init FILE = set vars not included in FILE to false\n");
00264 fprintf(stderr, " -partial FILE = set vars not included in FILE randomly\n");
00265 fprintf(stderr, " -withcost = input is a set of weighted clauses\n");
00266 fprintf(stderr, " -targetcost N = find assignments of cost <= N (MAXSAT)\n");
00267 fprintf(stderr, " -hard = never break a highest-cost clause\n");
00268 fprintf(stderr, "Heuristics:\n");
00269 fprintf(stderr, " -noise N M -best -super -tabu N\n");
00270 fprintf(stderr, " -productsum -reciprocal -additive -exponential\n");
00271 fprintf(stderr, "Printing:\n");
00272 fprintf(stderr, " -trace N = print statistics every N flips\n");
00273 fprintf(stderr, " -sol = print assignments where cost < target\n");
00274 fprintf(stderr, " -low = print lowest assignment each try\n");
00275 fprintf(stderr, " -bad = print unsat clauses each try\n");
00276 fprintf(stderr, " -solcnf = print sat assign in cnf format, and exit\n");
00277 exit(-1);
00278 }
00279 }
00280 base_cutoff = cutoff;
00281 if (numerator==NOVALUE){
00282 if (heuristic==BEST)
00283 numerator = 50;
00284 else
00285 numerator = 0;
00286 }
00287
00288 srandom(seed);
00289 #ifdef Huge
00290 printf("maxwalksat version 20 (Huge)\n");
00291 #else
00292 printf("maxwalksat version 20\n");
00293 #endif
00294 printf("seed = %i\n",seed);
00295 printf("cutoff = %i\n",cutoff);
00296 printf("tries = %i\n",numrun);
00297 printf("numsol = %i\n",numsol);
00298 printf("targetcost = %i\n",targetcost);
00299
00300 printf("heuristic = ");
00301
00302 switch(heuristic)
00303 {
00304 case RANDOM:
00305 printf("random");
00306 break;
00307 case PRODUCTSUM:
00308 printf("productsum");
00309 break;
00310 case RECIPROCAL:
00311 printf("reciprocal");
00312 break;
00313 case ADDITIVE:
00314 printf("additive");
00315 break;
00316 case BEST:
00317 printf("best");
00318 break;
00319 case EXPONENTIAL:
00320 printf("exponential");
00321 break;
00322 case TABU:
00323 printf("tabu %d", tabu_length);
00324 break;
00325 }
00326 if (numerator>0){
00327 printf(", noise %d / %d", numerator, denominator);
00328 }
00329 if (superlinear)
00330 printf(", super");
00331 if (printtrace)
00332 printf(", trace %d", printtrace);
00333 if (initfile[0]){
00334 printf(", init %s", initfile);
00335 if (initoptions == INIT_PARTIAL)
00336 printf(", partial");
00337 }
00338 printf("\n");
00339
00340 initprob();
00341
00342 if (costexpected) printf("clauses contain explicit costs\n");
00343 else printf("clauses all assigned default cost of 1\n");
00344
00345 printf("numatom = %i, numclause = %i, numliterals = %i\n",numatom,numclause,numliterals);
00346 printf("wff read in\n");
00347 printf(" average average mean standard\n");
00348 printf(" lowest worst number when over flips error\n");
00349 printf(" cost clause #unsat #flips model success all until std of\n");
00350 printf(" this try this try this try this try found rate tries assign dev mean\n");
00351
00352 signal(SIGINT, (void *) handle_interrupt);
00353 abort_flag = FALSE;
00354 numnullflip = 0;
00355 (void) elapsed_seconds();
00356 x = 0; r = 0;
00357 lowcost = BIG;
00358 for(k = 0;k < numrun;k++)
00359 {
00360 init(initfile, initoptions);
00361 lowbad = numfalse;
00362 lowcost = costofnumfalse;
00363 save_low_assign();
00364 numflip = 0;
00365
00366 if (superlinear) cutoff = base_cutoff * super(r+1);
00367
00368 while((numflip < cutoff) && (costofnumfalse > targetcost))
00369 {
00370 if (printtrace && (numflip % printtrace == 0)){
00371 printf("%10i %10i%10li\n", costofnumfalse,numfalse,numflip);
00372 fflush(stdout);
00373 }
00374 numflip++;
00375 if ((eqhighest) && (highestcost!=1))
00376 {
00377 fix(selecthigh(1+random()%numhighest));
00378 }
00379 else fix(false[random()%numfalse]);
00380 if (costofnumfalse < lowcost)
00381 {
00382 lowcost = costofnumfalse;
00383 lowbad = numfalse;
00384 save_low_assign();
00385 }
00386 }
00387 numtry++;
00388 totalflip += numflip;
00389 x += numflip;
00390 r ++;
00391 if(costofnumfalse<=targetcost)
00392 {
00393 numsuccesstry++;
00394 totalsuccessflip += numflip;
00395 integer_sum_x += x;
00396 sum_x = (double) integer_sum_x;
00397 sum_x_squared += ((double)x)*((double)x);
00398 mean_x = sum_x / numsuccesstry;
00399 if (numsuccesstry > 1){
00400 second_moment_x = sum_x_squared / numsuccesstry;
00401 variance_x = second_moment_x - (mean_x * mean_x);
00402
00403 variance_x = (variance_x * numsuccesstry)/(numsuccesstry - 1);
00404 std_dev_x = sqrt(variance_x);
00405 std_error_mean_x = std_dev_x / sqrt((double)numsuccesstry);
00406 }
00407 sum_r += r;
00408 mean_r = ((double)sum_r)/numsuccesstry;
00409 sum_r_squared += ((double)r)*((double)r);
00410 x = 0;
00411 r = 0;
00412 }
00413
00414 countlowunsatcost(&computed_cost, &worst_cost);
00415 if(lowcost != computed_cost)
00416 {
00417 fprintf(stderr, "Program error, verification of assignment cost fails!\n");
00418 exit(-1);
00419 }
00420
00421 if(numsuccesstry == 0)
00422 printf("%10i%10i%10i%10li * 0 * * * *\n",
00423 lowcost,worst_cost,lowbad,numflip);
00424 else if (numsuccesstry == 1)
00425 printf("%10i%10i%10i%10li%10li%10i%10li %10.1f * *\n",
00426 lowcost,worst_cost,lowbad,numflip,totalsuccessflip/numsuccesstry,
00427 (numsuccesstry*100)/numtry,totalflip/numsuccesstry,
00428 mean_x);
00429 else
00430 printf("%10i%10i%10i%10li%10li%10i%10li %10.1f %10.1f %10.1f\n",
00431 lowcost,worst_cost,lowbad,numflip,totalsuccessflip/numsuccesstry,
00432 (numsuccesstry*100)/numtry,totalflip/numsuccesstry,
00433 mean_x, std_dev_x, std_error_mean_x);
00434 if (numfalse>0 && printfalse)
00435 print_false_clauses_cost(lowbad);
00436 if (printlow && (!printonlysol || costofnumfalse<=targetcost))
00437 print_low_assign(lowcost);
00438
00439 if (numsuccesstry >= numsol) break;
00440 if (abort_flag) break;
00441 fflush(stdout);
00442 }
00443 expertime = elapsed_seconds();
00444 seconds_per_flip = expertime / totalflip;
00445 printf("\ntotal elapsed seconds = %f\n", expertime);
00446 printf("average flips per second = %d\n", (long)(totalflip/expertime));
00447 if (heuristic == TABU)
00448 printf("proportion null flips = %f\n", ((double)numnullflip)/totalflip);
00449 printf("number of solutions found = %d\n", numsuccesstry);
00450 if (numsuccesstry > 0)
00451 {
00452 printf("mean flips until assign = %f\n", mean_x);
00453 if (numsuccesstry>1){
00454 printf(" variance = %f\n", variance_x);
00455 printf(" standard deviation = %f\n", std_dev_x);
00456 printf(" standard error of mean = %f\n", std_error_mean_x);
00457 }
00458 printf("mean seconds until assign = %f\n", mean_x * seconds_per_flip);
00459 if (numsuccesstry>1){
00460 printf(" variance = %f\n", variance_x * seconds_per_flip * seconds_per_flip);
00461 printf(" standard deviation = %f\n", std_dev_x * seconds_per_flip);
00462 printf(" standard error of mean = %f\n", std_error_mean_x * seconds_per_flip);
00463 }
00464 printf("mean restarts until assign = %f\n", mean_r);
00465 if (numsuccesstry>1){
00466 variance_r = (sum_r_squared / numsuccesstry) - (mean_r * mean_r);
00467 variance_r = (variance_r * numsuccesstry)/(numsuccesstry - 1);
00468 std_dev_r = sqrt(variance_r);
00469 std_error_mean_r = std_dev_r / sqrt((double)numsuccesstry);
00470 printf(" variance = %f\n", variance_r);
00471 printf(" standard deviation = %f\n", std_dev_r);
00472 printf(" standard error of mean = %f\n", std_error_mean_r);
00473 }
00474 }
00475
00476 if (numsuccesstry > 0)
00477 {
00478 printf("ASSIGNMENT ACHIEVING TARGET %i FOUND\n", targetcost);
00479 if(printsolcnf == TRUE)
00480 for(i = 1;i < numatom+1;i++)
00481 printf("v %i\n", atom[i] == 1 ? i : -i);
00482 }
00483 else
00484 printf("ASSIGNMENT NOT FOUND\n");
00485 return 0;
00486 }
00487
00488 long super(int i)
00489 {
00490 long power;
00491 int k;
00492
00493 if (i<=0){
00494 fprintf(stderr, "bad argument super(%d)\n", i);
00495 exit(1);
00496 }
00497
00498 k = 1;
00499 power = 2;
00500 while (power < (i+1)){
00501 k += 1;
00502 power *= 2;
00503 }
00504 if (power == (i+1)) return (power/2);
00505 return (super(i - (power/2) + 1));
00506 }
00507
00508 void handle_interrupt(int sig)
00509 {
00510 if (abort_flag) exit(-1);
00511 abort_flag = TRUE;
00512 }
00513
00514 void scanone(int argc, char *argv[], int i, int *varptr)
00515 {
00516 if (i>=argc || sscanf(argv[i],"%i",varptr)!=1){
00517 fprintf(stderr, "Bad argument %s\n", i<argc ? argv[i] : argv[argc-1]);
00518 exit(-1);
00519 }
00520 }
00521
00522 void init(char initfile[], int initoptions)
00523 {
00524 int i;
00525 int j;
00526 int thetruelit;
00527 FILE * infile;
00528 int lit;
00529
00530 for(i = 0;i < numclause;i++)
00531 numtruelit[i] = 0;
00532 numfalse = 0;
00533 costofnumfalse = 0;
00534 eqhighest = 0;
00535 numhighest = 0;
00536
00537 for(i = 1;i < numatom+1;i++)
00538 {
00539 changed[i] = -BIG;
00540 breakcost[i] = 0;
00541 }
00542
00543 if (initfile[0] && initoptions!=INIT_PARTIAL){
00544 for(i = 1;i < numatom+1;i++)
00545 atom[i] = 0;
00546 }
00547 else {
00548 for(i = 1;i < numatom+1;i++)
00549 atom[i] = random()%2;
00550 }
00551
00552 if (initfile[0]){
00553 if ((infile = fopen(initfile, "r")) == NULL){
00554 fprintf(stderr, "Cannot open %s\n", initfile);
00555 exit(1);
00556 }
00557 i=0;
00558 while (fscanf(infile, " %d", &lit)==1){
00559 i++;
00560 if (abs(lit)>numatom){
00561 fprintf(stderr, "Bad init file %s\n", initfile);
00562 exit(1);
00563 }
00564 if (lit<0) atom[-lit]=0;
00565 else atom[lit]=1;
00566 }
00567 if (i==0){
00568 fprintf(stderr, "Bad init file %s\n", initfile);
00569 exit(1);
00570 }
00571 close(infile);
00572
00573 }
00574
00575
00576 for(i = 0;i < numclause;i++)
00577 {
00578 for(j = 0;j < size[i];j++)
00579 {
00580 if((clause[i][j] > 0) == atom[abs(clause[i][j])])
00581 {
00582 numtruelit[i]++;
00583 thetruelit = clause[i][j];
00584 }
00585 }
00586 if(numtruelit[i] == 0)
00587 {
00588 wherefalse[i] = numfalse;
00589 false[numfalse] = i;
00590 numfalse++;
00591 costofnumfalse += cost[i];
00592 if (highestcost == cost[i])
00593 {eqhighest = 1; numhighest++;}
00594 }
00595 else if (numtruelit[i] == 1)
00596 {
00597 breakcost[abs(thetruelit)] += cost[i];
00598 }
00599 }
00600 }
00601
00602 void
00603 print_false_clauses_cost(long int lowbad)
00604 {
00605 int i, j;
00606 int bad;
00607 int lit, sign;
00608
00609 printf("Unsatisfied clauses:\n");
00610 for (i=0; i<numclause; i++){
00611 bad = TRUE;
00612 for (j=0; j < size[i]; j++) {
00613 lit = clause[i][j];
00614 sign = lit > 0 ? 1 : 0;
00615 if ( lowatom[abs(lit)] == sign ){
00616 bad = FALSE;
00617 break;
00618 }
00619 }
00620 if (bad){
00621 printf("Cost %i ", cost[i]);
00622 for (j=0; j<size[i]; j++){
00623 printf("%d ", clause[i][j]);
00624 }
00625 printf("0\n");
00626 }
00627 }
00628 printf("End unsatisfied clauses\n");
00629 }
00630
00631
00632 void initprob(void)
00633 {
00634 int i;
00635 int j;
00636 int lastc;
00637 int nextc;
00638 int *storeptr;
00639 int freestore;
00640 int lit;
00641 char buf[512];
00642
00643 while ((lastc = getchar()) == 'c')
00644 {
00645 while ((nextc = getchar()) != EOF && nextc != '\n');
00646 }
00647 ungetc(lastc,stdin);
00648 fgets(buf, 512, stdin);
00649 if (sscanf(buf, "p wcnf %i %i",&numatom,&numclause) == 2){
00650 costexpected = 1; }
00651 else if (sscanf(buf, "p cnf %i %i",&numatom,&numclause) != 2){
00652 fprintf(stderr,"Bad input file\n");
00653 exit(-1);}
00654 if(numatom > MAXATOM)
00655 {
00656 fprintf(stderr,"ERROR - too many atoms\n");
00657 exit(-1);
00658 }
00659
00660 #ifdef Huge
00661 clause = (int **) malloc(sizeof(int *)*(numclause+1));
00662 cost = (int *) malloc(sizeof(int)*(numclause+1));
00663 size = (int *) malloc(sizeof(int)*(numclause+1));
00664 false = (int *) malloc(sizeof(int)*(numclause+1));
00665 lowfalse = (int *) malloc(sizeof(int)*(numclause+1));
00666 wherefalse = (int *) malloc(sizeof(int)*(numclause+1));
00667 numtruelit = (int *) malloc(sizeof(int)*(numclause+1));
00668 #else
00669 if(numclause > MAXCLAUSE)
00670 {
00671 fprintf(stderr,"ERROR - too many clauses\n");
00672 exit(-1);
00673 }
00674 #endif
00675 freestore = 0;
00676 numliterals = 0;
00677 for(i = 0;i < 2*MAXATOM+1;i++)
00678 numoccurence[i] = 0;
00679 for(i = 0;i < numclause;i++)
00680 {
00681 if (costexpected)
00682 {
00683 if (scanf("%i ",&cost[i]) != 1)
00684 {
00685 fprintf(stderr, "Bad input file\n");
00686 exit(-1);
00687 }
00688 else if (cost[i]>highestcost) highestcost = cost[i];
00689 }
00690 else cost[i] = 1;
00691
00692 size[i] = -1;
00693 if (freestore < MAXLENGTH)
00694 {
00695 storeptr = (int *) malloc( sizeof(int) * STOREBLOCK );
00696 freestore = STOREBLOCK;
00697 fprintf(stderr,"allocating memory...\n");
00698 }
00699 clause[i] = storeptr;
00700 do
00701 {
00702 size[i]++;
00703 if(size[i] > MAXLENGTH)
00704 {
00705 printf("ERROR - clause too long\n");
00706 exit(-1);
00707 }
00708 if (scanf("%i ",&lit) != 1)
00709 {
00710 fprintf(stderr, "Bad input file\n");
00711 exit(-1);
00712 }
00713 if(lit != 0)
00714 {
00715 *(storeptr++) = lit;
00716 freestore--;
00717 numliterals++;
00718 numoccurence[lit+MAXATOM]++;
00719 }
00720 }
00721 while(lit != 0);
00722 }
00723 if(size[0] == 0)
00724 {
00725 fprintf(stderr,"ERROR - incorrect problem format or extraneous characters\n");
00726 exit(-1);
00727 }
00728
00729 for(i = 0;i < 2*MAXATOM+1;i++)
00730 {
00731 if (freestore < numoccurence[i])
00732 {
00733 storeptr = (int *) malloc( sizeof(int) * STOREBLOCK );
00734 freestore = STOREBLOCK;
00735 fprintf(stderr,"allocating memory...\n");
00736 }
00737 occurence[i] = storeptr;
00738 freestore -= numoccurence[i];
00739 storeptr += numoccurence[i];
00740 numoccurence[i] = 0;
00741 }
00742
00743 for(i = 0;i < numclause;i++)
00744 {
00745 for(j = 0;j < size[i];j++)
00746 {
00747 occurence[clause[i][j]+MAXATOM]
00748 [numoccurence[clause[i][j]+MAXATOM]] = i;
00749 numoccurence[clause[i][j]+MAXATOM]++;
00750 }
00751 }
00752 }
00753
00754
00755 void
00756 fix(int tofix)
00757 {
00758 int numbreak[MAXLENGTH];
00759
00760 int i;
00761 int j;
00762 int choice;
00763 static int (*pickcode[])(int *numbreak,int clausesize, int tofix) =
00764 {pickrandom,pickproductsum,pickreciprocal,pickadditive,
00765 pickbest,pickexponential,picktabu};
00766
00767 for(i = 0;i < size[tofix];i++)
00768 numbreak[i] = breakcost[abs(clause[tofix][i])];
00769
00770 choice = (pickcode[heuristic])(numbreak,size[tofix],tofix);
00771 if (choice == NOVALUE)
00772 numnullflip++;
00773 else
00774 flipatom(abs(clause[tofix][choice]));
00775 }
00776
00777
00778 void flipatom(int toflip)
00779 {
00780 int i, j;
00781 int toenforce;
00782 register int cli;
00783 register int lit;
00784 int numocc;
00785 register int sz;
00786 register int * litptr;
00787 int * occptr;
00788
00789 changed[toflip] = numflip;
00790 if(atom[toflip] > 0)
00791 toenforce = -toflip;
00792 else
00793 toenforce = toflip;
00794 atom[toflip] = 1-atom[toflip];
00795
00796 numocc = numoccurence[MAXATOM-toenforce];
00797 occptr = occurence[MAXATOM-toenforce];
00798 for(i = 0; i < numocc ;i++)
00799 {
00800
00801 cli = *(occptr++);
00802
00803 if (--numtruelit[cli] == 0){
00804 false[numfalse] = cli;
00805 wherefalse[cli] = numfalse;
00806 numfalse++;
00807 costofnumfalse += cost[cli];
00808
00809 breakcost[toflip] -= cost[cli];
00810 if (cost[cli] == highestcost)
00811 { eqhighest = 1; numhighest++; }
00812 }
00813 else if (numtruelit[cli] == 1){
00814
00815 sz = size[cli];
00816 litptr = clause[cli];
00817 for (j=0; j<sz; j++){
00818
00819 lit = *(litptr++);
00820 if((lit > 0) == atom[abs(lit)]){
00821 breakcost[abs(lit)] += cost[cli];
00822 break;
00823 }
00824 }
00825 }
00826 }
00827
00828 numocc = numoccurence[MAXATOM+toenforce];
00829 occptr = occurence[MAXATOM+toenforce];
00830 for(i = 0; i < numocc; i++)
00831 {
00832
00833 cli = *(occptr++);
00834
00835 if (++numtruelit[cli] == 1){
00836 numfalse--;
00837 costofnumfalse -= cost[cli];
00838 false[wherefalse[cli]] =
00839 false[numfalse];
00840 wherefalse[false[numfalse]] =
00841 wherefalse[cli];
00842
00843 breakcost[toflip] += cost[cli];
00844 if (cost[cli] == highestcost)
00845 { numhighest--; if (numhighest==0) eqhighest = 0; }
00846 }
00847 else if (numtruelit[cli] == 2){
00848
00849
00850 sz = size[cli];
00851 litptr = clause[cli];
00852 for (j=0; j<sz; j++){
00853
00854 lit = *(litptr++);
00855 if( ((lit > 0) == atom[abs(lit)]) &&
00856 (toflip != abs(lit)) ){
00857 breakcost[abs(lit)] -= cost[cli];
00858 break;
00859 }
00860 }
00861 }
00862 }
00863 }
00864
00865 int pickrandom(int *numbreak,int clausesize, int tofix)
00866
00867 {
00868 return(random()%clausesize);
00869 }
00870
00871 int pickproductsum(int *numbreak,int clausesize, int tofix)
00872
00873
00874 {
00875 int i;
00876 int weight[MAXLENGTH];
00877 int tochange;
00878 int totalproduct = 1;
00879 int totalsum = 0;
00880
00881 if(clausesize == 1)
00882 return(0);
00883 if((tochange = pickzero(numbreak,clausesize)) != NOVALUE)
00884 return(tochange);
00885 for(i = 0;i < clausesize;i++)
00886 {
00887 totalproduct *= numbreak[i];
00888 totalsum += numbreak[i];
00889 }
00890 for(i = 0;i < clausesize;i++)
00891 {
00892 weight[i] = (totalproduct/numbreak[i])*
00893 (totalsum-numbreak[i]);
00894 }
00895 return(pickweight(weight,clausesize));
00896 }
00897
00898 int pickreciprocal(int *numbreak,int clausesize, int tofix)
00899
00900 {
00901 int i;
00902 int weight[MAXLENGTH];
00903 int tochange;
00904 int totalproduct = 1;
00905
00906 if(clausesize == 1)
00907 return(0);
00908 if((tochange = pickzero(numbreak,clausesize)) != NOVALUE)
00909 return(tochange);
00910 for(i = 0;i < clausesize;i++)
00911 totalproduct *= numbreak[i];
00912 for(i = 0;i < clausesize;i++)
00913 weight[i] = (totalproduct/numbreak[i]);
00914 return(pickweight(weight,clausesize));
00915 }
00916
00917 int pickadditive(int *numbreak,int clausesize, int tofix)
00918
00919 {
00920 int i;
00921 int weight[MAXLENGTH];
00922 int tochange;
00923 int totalsum = 0;
00924
00925 if(clausesize == 1)
00926 return(0);
00927 if((tochange = pickzero(numbreak,clausesize)) != NOVALUE)
00928 return(tochange);
00929 for(i = 0;i < clausesize;i++)
00930 totalsum += numbreak[i];
00931 for(i = 0;i < clausesize;i++)
00932 weight[i] = (totalsum-numbreak[i]);
00933 return(pickweight(weight,clausesize));
00934 }
00935
00936 int pickbest(int *numbreak,int clausesize, int tofix)
00937 {
00938 int i;
00939 int best[MAXLENGTH];
00940 int numbest;
00941 int bestvalue;
00942
00943 numbest = 0;
00944 bestvalue = BIG;
00945
00946 for (i=0; i< clausesize; i++){
00947 if (numbreak[i]<=bestvalue){
00948 if (numbreak[i]<bestvalue) numbest=0;
00949 bestvalue = numbreak[i];
00950 best[numbest++] = i;
00951 }
00952 }
00953
00954 if (bestvalue>0 && (random()%denominator < numerator)){
00955
00956 if (!hard || cost[tofix]>=highestcost) return(random()%clausesize);
00957
00958
00959
00960 numbest = 0;
00961 for (i=0; i< clausesize; i++){
00962 if (numbreak[i]<highestcost){
00963 best[numbest++] = i;
00964 }
00965 }
00966
00967 if (numbest==0) { return(random()%clausesize); }
00968 }
00969 if (numbest == 1) return best[0];
00970
00971
00972 if (numbest==0) { return(random()%clausesize); }
00973
00974 return(best[random()%numbest]);
00975
00976
00977
00978 }
00979
00980
00981 int
00982 picktabu(int *numbreak,int clausesize, int tofix)
00983 {
00984 int i;
00985 int best[MAXLENGTH];
00986 int numbest;
00987 int bestvalue;
00988 int tabu_level;
00989 int val;
00990
00991 numbest = 0;
00992 bestvalue = BIG;
00993
00994 if (numerator>0 && (random()%denominator < numerator)){
00995 for (i=0; i< clausesize; i++){
00996 if ((tabu_length < numflip - changed[abs(clause[tofix][i])]) ||
00997 numbreak[i]==0){
00998 if (numbreak[i]==0) numbest=0;
00999 best[numbest++] = i;
01000 }
01001 }
01002 }
01003 else {
01004 for (i=0; i< clausesize; i++){
01005 if (numbreak[i]<=bestvalue &&
01006 ((tabu_length < numflip - changed[abs(clause[tofix][i])]) ||
01007 numbreak[i]==0)){
01008 if (numbreak[i]<bestvalue) numbest=0;
01009 bestvalue = numbreak[i];
01010 best[numbest++] = i;
01011 }
01012 }
01013 }
01014
01015 if (numbest == 0) return NOVALUE;
01016 if (numbest == 1) return best[0];
01017 return (best[random()%numbest]);
01018 }
01019
01020 int pickexponential(int *numbreak,int clausesize, int tofix)
01021 {
01022 int i;
01023 int best[MAXLENGTH];
01024 int numbest;
01025 int bestvalue;
01026 int weight[MAXLENGTH];
01027 int tochange;
01028 int totalproduct = 1;
01029 int totalsum = 0;
01030
01031 if(clausesize == 1)
01032 return(0);
01033 if((tochange = pickzero(numbreak,clausesize)) != NOVALUE)
01034 return(tochange);
01035 for(i = 0;i < clausesize;i++)
01036 weight[i] = 2*2*2*2*2*2*2*2*2*2*2*2*2*2;
01037 for(i = 0;i < clausesize;i++)
01038 {
01039 weight[i] >>= numbreak[i];
01040 }
01041
01042 return(pickweight(weight,clausesize));
01043 }
01044
01045 int pickzero(int *numbreak,int clausesize)
01046 {
01047 int i;
01048 int numzero = 0;
01049 int select;
01050
01051 for(i = 0;i < clausesize;i++)
01052 {
01053 if(numbreak[i] == 0)
01054 numzero++;
01055 }
01056 if(numzero == 0)
01057 return(NOVALUE);
01058 select = random()%numzero;
01059 for(i = 0;select >= 0;i++)
01060 {
01061 if(numbreak[i] == 0)
01062 select--;
01063 }
01064
01065 return(i-1);
01066 }
01067
01068 int pickweight(int *weight,int clausesize)
01069 {
01070 int i;
01071 int total = 0;
01072 int select;
01073 int subtotal = 0;
01074
01075 for(i = 0;i < clausesize;i++)
01076 total += weight[i];
01077 if(total == 0)
01078 return(random()%clausesize);
01079 select = random()%total;
01080 for(i = 0;subtotal <= select;i++)
01081 subtotal += weight[i];
01082 return(i-1);
01083 }
01084
01085 int countunsat(void)
01086 {
01087 int i, j, unsat, bad, lit, sign;
01088
01089 unsat = 0;
01090 for (i=0;i < numclause;i++)
01091 {
01092 bad = TRUE;
01093 for (j=0; j < size[i]; j++)
01094 {
01095 lit = clause[i][j];
01096 sign = lit > 0 ? 1 : 0;
01097 if ( atom[abs(lit)] == sign )
01098 {
01099 bad = FALSE;
01100 break;
01101 }
01102 }
01103 if (bad)
01104 unsat++;
01105 }
01106 return unsat;
01107 }
01108
01109 void countlowunsatcost(int * unsatcostptr, int * worstcostptr)
01110 {
01111 int i, j, bad, lit, sign, unsatcost, worstcost;
01112
01113 unsatcost = 0;
01114 worstcost = 0;
01115 for (i=0;i < numclause;i++)
01116 {
01117 bad = TRUE;
01118 for (j=0; j < size[i]; j++)
01119 {
01120 lit = clause[i][j];
01121 sign = lit > 0 ? 1 : 0;
01122 if ( lowatom[abs(lit)] == sign )
01123 {
01124 bad = FALSE;
01125 break;
01126 }
01127 }
01128 if (bad){
01129 unsatcost += cost[i] ;
01130 if (cost[i] > worstcost) worstcost = cost[i];
01131 }
01132 }
01133 * unsatcostptr = unsatcost;
01134 * worstcostptr = worstcost;
01135 return;
01136 }
01137
01138
01139 double
01140 elapsed_seconds(void)
01141 {
01142 double answer;
01143
01144 static struct rusage prog_rusage;
01145 static long prev_rusage_seconds = 0;
01146 static long prev_rusage_micro_seconds = 0;
01147
01148 getrusage(0, &prog_rusage);
01149 answer = (double)(prog_rusage.ru_utime.tv_sec - prev_rusage_seconds)
01150 + ((double)(prog_rusage.ru_utime.tv_usec - prev_rusage_micro_seconds)) /
01151 1000000.0 ;
01152 prev_rusage_seconds = prog_rusage.ru_utime.tv_sec ;
01153 prev_rusage_micro_seconds = prog_rusage.ru_utime.tv_usec ;
01154 return answer;
01155 }
01156
01157
01158 void
01159 print_low_assign(long int lowbad)
01160 {
01161 int i, j;
01162
01163 printf("Begin assign with lowest # bad = %d (atoms assigned true)\n", lowbad);
01164 j=1;
01165 for (i=1; i<=numatom; i++){
01166 if (lowatom[i]>0){
01167 printf(" %d", i);
01168 if (j++ % 10 == 0) printf("\n");
01169 }
01170 }
01171 if ((j-1) % 10 != 0) printf("\n");
01172 printf("End assign\n");
01173 }
01174
01175 void
01176 save_low_assign(void)
01177 {
01178 int i;
01179
01180 for (i=1; i<=numatom; i++)
01181 lowatom[i] = atom[i];
01182 }
01183
01184 int selecthigh(int high)
01185 {
01186 int counter=0;
01187 int i=0;
01188 while ((i<numfalse) && (counter<high))
01189 {
01190 if (cost[false[i]] == highestcost)
01191 counter++;
01192 i++;
01193 }
01194
01195 return(false[i-1]);
01196 }
01197
01198