00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #ifndef SAMPLESAT_H_OCT_23_2005
00067 #define SAMPLESAT_H_OCT_23_2005
00068
00069
00070
00071
00072
00073
00074
00075
00076 #define VERSION "samplesat-WSv45"
00077 #define UNIX 1
00078
00079
00080
00081
00082 #include "samplesatparams.h"
00083 #include "array.h"
00084 #include "hashint.h"
00085 #include <assert.h>
00086 #include <iostream>
00087 using namespace std;
00088
00089 #include <stdio.h>
00090 #include <string.h>
00091 #include <stdlib.h>
00092 #include <math.h>
00093 #include <sys/types.h>
00094 #include <limits.h>
00095 #include <signal.h>
00096
00097
00098 #include <sys/times.h>
00099 #include <sys/time.h>
00100
00101
00102
00103
00104 #ifdef DYNAMIC
00105 #define STOREBLOCK 2000000
00106 #else
00107 #define STOREBLOCK 2000000
00108 #endif
00109
00110 #define BIGINT long int
00111 #ifndef CLK_TCK
00112 #define CLK_TCK 60
00113 #endif
00114 #define NOVALUE -1
00115 #define INIT_PARTIAL 1
00116
00117 #define HISTMAX 1
00118 #define BIG 100000000
00119
00120 enum heuristics {RANDOM, BEST, TABU, SA};
00121
00122
00123
00124
00125 class SampleSat
00126 {
00127 public:
00128 SampleSat(const SampleSatParams & params, int numGndPreds, int maxClause,
00129 int maxLen, int maxLitOccurence, int* fixedAtoms, int** clauses,
00130 const Array<Array<int> >* const & blocks,
00131 const Array<bool>* const & blockEvidence);
00132 ~SampleSat();
00133 bool sample(bool*& assignments, int numClauses,
00134 const Array<Array<int> >* const & blocks,
00135 const Array<bool>* const & blockEvidence);
00136
00137 private:
00138
00139
00140
00141 int saRatio;
00142 int temperature;
00143 bool latesa;
00144
00145
00146
00147
00148 int (SampleSat::*pickcode[15])(void);
00149
00150 int numatom, MAXATOM;
00151 int numclause, MAXCLAUSE;
00152 int numliterals;
00153 int MAXLENGTH;
00154
00155 int ** clause;
00156
00157 int * size;
00158 int * wfalse;
00159 int * lowfalse;
00160 int * wherefalse;
00161 int * numtruelit;
00162
00163 int** occurence;
00164 int* numoccurence;
00165 int* atom;
00166 int* lowatom;
00167 int* solution;
00168 int* changed;
00169 int* breakcount;
00170 int* makecount;
00171 int numfalse;
00172
00173
00174 int* fixedatom;
00175 bool* isSat;
00176
00177
00178 Array<Array<int> >* blocks_;
00179 Array<bool >* blockEvidence_;
00180
00181
00182 bool inBlock;
00183 int flipInBlock;
00184
00185
00186 Array<int> newToOldMapping_;
00187
00188 int* watch1;
00189 int* watch2;
00190
00191
00192 int status_flag;
00193 int abort_flag;
00194
00195 int heuristic;
00196 int numerator;
00197 int denominator;
00198 int tabu_length;
00199
00200 int wp_numerator;
00201 int wp_denominator;
00202
00203 BIGINT numflip;
00204 BIGINT numnullflip;
00205
00206 BIGINT cutoff;
00207 BIGINT base_cutoff;
00208 int target;
00209 int numtry;
00210
00211 int numrun;
00212 int numsol;
00213
00214 bool superlinear;
00215
00216
00217 bool makeflag;
00218
00219
00220 long int tailhist[HISTMAX];
00221 long histtotal;
00222 int tail;
00223 int tail_start_flip;
00224
00225
00226 bool printonlysol;
00227 bool printsolcnf;
00228 bool printfalse;
00229 bool printlow;
00230 bool printhist;
00231 int printtrace;
00232 bool trace_assign;
00233
00234 char outfile[1024];
00235
00236
00237 char initfile[100];
00238 int initoptions;
00239
00240
00241 int seed;
00242
00243 #ifdef UNIX
00244 struct timeval tv;
00245 struct timezone tzp;
00246 #endif
00247 #ifdef NT
00248 DWORD win_time;
00249 #endif
00250
00251
00252 double expertime;
00253 BIGINT flips_this_solution;
00254 long int lowbad;
00255 BIGINT totalflip;
00256 BIGINT totalsuccessflip;
00257 int numsuccesstry;
00258
00259 BIGINT x;
00260 BIGINT integer_sum_x;
00261 double sum_x;
00262 double sum_x_squared;
00263 double mean_x;
00264 double second_moment_x;
00265 double variance_x;
00266 double std_dev_x;
00267 double std_error_mean_x;
00268 double seconds_per_flip;
00269 int r;
00270 int sum_r;
00271 double sum_r_squared;
00272 double mean_r;
00273 double variance_r;
00274 double std_dev_r;
00275 double std_error_mean_r;
00276
00277 double avgfalse;
00278 double sumfalse;
00279 double sumfalse_squared;
00280 double second_moment_avgfalse, variance_avgfalse, std_dev_avgfalse, ratio_avgfalse;
00281
00282 double f;
00283 double sample_size;
00284
00285 double sum_avgfalse;
00286 double sum_std_dev_avgfalse;
00287 double mean_avgfalse;
00288 double mean_std_dev_avgfalse;
00289 int number_sampled_runs;
00290 double ratio_mean_avgfalse;
00291
00292 double suc_sum_avgfalse;
00293 double suc_sum_std_dev_avgfalse;
00294 double suc_mean_avgfalse;
00295 double suc_mean_std_dev_avgfalse;
00296 int suc_number_sampled_runs;
00297 double suc_ratio_mean_avgfalse;
00298
00299 double nonsuc_sum_avgfalse;
00300 double nonsuc_sum_std_dev_avgfalse;
00301 double nonsuc_mean_avgfalse;
00302 double nonsuc_mean_std_dev_avgfalse;
00303 int nonsuc_number_sampled_runs;
00304 double nonsuc_ratio_mean_avgfalse;
00305
00306
00307 char hamming_target_file[512];
00308 char hamming_data_file[512];
00309 int hamming_sample_freq;
00310 int hamming_flag;
00311 int hamming_distance;
00312 int* hamming_target;
00313 FILE * hamming_fp;
00314
00315
00316 int samplefreq;
00317
00318
00319
00320
00321 void initRandom();
00322 void initVars();
00323 void print_parameters(int argc, char * argv[]);
00324
00325 int Var(int c, int p) {return abs(clause[c][p]);}
00326
00327 void parse_parameters(int argc,char *argv[])
00328 {
00329 int i;
00330 int temp;
00331
00332
00333 heuristic = SA;
00334
00335
00336 for (i=1;i < argc;i++)
00337 {
00338 if (strcmp(argv[i],"-seed") == 0)
00339 scanone(argc,argv,++i,&seed);
00340 else if (strcmp(argv[i],"-out") == 0 && i<argc-1)
00341 strcpy(outfile, argv[++i]);
00342 else if (strcmp(argv[i],"-hist") == 0)
00343 printhist = true;
00344 else if (strcmp(argv[i],"-status") == 0)
00345 status_flag = 1;
00346 else if (strcmp(argv[i],"-cutoff") == 0)
00347 scanonell(argc,argv,++i,&cutoff);
00348 else if (strcmp(argv[i],"-late_sa")==0)
00349 latesa = true;
00350 else if (strcmp(argv[i],"-random") == 0)
00351 heuristic = RANDOM;
00352 else if (strcmp(argv[i],"-best") == 0)
00353 heuristic = BEST;
00354 else if (strcmp(argv[i],"-sa") == 0){
00355 heuristic = SA;
00356 makeflag = true;
00357 scanone(argc, argv, ++i, &saRatio);
00358 scanone(argc, argv, ++i, &temperature);
00359 }
00360 else if (strcmp(argv[i],"-noise") == 0){
00361 scanone(argc,argv,++i,&numerator);
00362 if (i < argc-1 && sscanf(argv[i+1],"%i",&temp)==1){
00363 denominator = temp;
00364 i++;
00365 }
00366 }
00367 else if (strcmp(argv[i],"-wp") == 0){
00368 scanone(argc,argv,++i,&wp_numerator);
00369 if (i < argc-1 && sscanf(argv[i+1],"%i",&temp)==1){
00370 wp_denominator = temp;
00371 i++;
00372 }
00373 }
00374 else if (strcmp(argv[i],"-init") == 0 && i < argc-1)
00375 sscanf(argv[++i], " %s", initfile);
00376 else if (strcmp(argv[i],"-hamming") == 0 && i < argc-3){
00377 sscanf(argv[++i], " %s", hamming_target_file);
00378 sscanf(argv[++i], " %s", hamming_data_file);
00379 sscanf(argv[++i], " %i", &hamming_sample_freq);
00380 hamming_flag = true;
00381 numrun = 1;
00382 }
00383 else if (strcmp(argv[i],"-partial") == 0)
00384 initoptions = INIT_PARTIAL;
00385 else if (strcmp(argv[i],"-super") == 0)
00386 superlinear = true;
00387 else if (strcmp(argv[i],"-tries") == 0 || strcmp(argv[i],"-restart") == 0)
00388 scanone(argc,argv,++i,&numrun);
00389 else if (strcmp(argv[i],"-target") == 0)
00390 scanone(argc,argv,++i,&target);
00391 else if (strcmp(argv[i],"-tail") == 0)
00392 scanone(argc,argv,++i,&tail);
00393 else if (strcmp(argv[i],"-sample") == 0)
00394 scanone(argc,argv,++i,&samplefreq);
00395 else if (strcmp(argv[i],"-tabu") == 0)
00396 {
00397 scanone(argc,argv,++i,&tabu_length);
00398 heuristic = TABU;
00399 }
00400 else if (strcmp(argv[i],"-low") == 0)
00401 printlow = true;
00402 else if (strcmp(argv[i],"-sol") == 0)
00403 {
00404 printonlysol = true;
00405 printlow = true;
00406 }
00407 else if (strcmp(argv[i],"-solcnf") == 0)
00408 {
00409 printsolcnf = true;
00410 if (numsol == NOVALUE) numsol = 1;
00411 }
00412 else if (strcmp(argv[i],"-bad") == 0)
00413 printfalse = true;
00414 else if (strcmp(argv[i],"-numsol") == 0)
00415 scanone(argc,argv,++i,&numsol);
00416 else if (strcmp(argv[i],"-trace") == 0)
00417 scanone(argc,argv,++i,&printtrace);
00418 else if (strcmp(argv[i],"-assign") == 0){
00419 scanone(argc,argv,++i,&printtrace);
00420 trace_assign = true;
00421 }
00422 else
00423 {
00424 fprintf(stderr, "General parameters:\n");
00425 fprintf(stderr, " -seed N -cutoff N -restart N\n");
00426 fprintf(stderr, " -numsol N = stop after finding N solutions\n");
00427 fprintf(stderr, " -super = use the Luby series for the cutoff values\n");
00428 fprintf(stderr, " -init FILE = set vars not included in FILE to false\n");
00429 fprintf(stderr, " -partial FILE = set vars not included in FILE randomly\n");
00430 fprintf(stderr, " -status = return fail status if solution not found\n");
00431 fprintf(stderr, " -target N = succeed if N or fewer clauses unsatisfied\n");
00432 fprintf(stderr, "Heuristics:\n");
00433 fprintf(stderr, " -random -best -tabu N \n");
00434 fprintf(stderr, " -sa SA_RATIO TEMPERATURE walksat with SA_RATIO percent SA\n moves added at temp TEMPERAURE/100. (default: -sa 50 10)\n");
00435 fprintf(stderr, " -late_sa use mixed simulated annealing moves only at solution cluster\n");
00436 fprintf(stderr, " -noise N or -noise N M (default M = 100)\n");
00437 fprintf(stderr, "Printing:\n");
00438 fprintf(stderr, " -out FILE = print solution as a list of literals to FILE\n");
00439 fprintf(stderr, " -trace N = print statistics every N flips\n");
00440 fprintf(stderr, " -assign N = print assignments at flip N, 2N, ...\n");
00441 fprintf(stderr, " -sol = print satisfying assignments to stdout\n");
00442 fprintf(stderr, " -solcnf = print sat assign to stdout in DIMACS format, and exit\n");
00443 fprintf(stderr, " -low = print lowest assignment each try\n");
00444 fprintf(stderr, " -bad = print unsat clauses each try\n");
00445 fprintf(stderr, " -hist = print histogram of tail\n");
00446 fprintf(stderr, " -tail N = assume tail begins at nvars*N\n");
00447 fprintf(stderr, " -sample N = sample noise level every N flips\n");
00448 fprintf(stderr, " -hamming TARGET_FILE DATA_FILE SAMPLE_FREQUENCY\n");
00449 exit(-1);
00450 }
00451 }
00452 base_cutoff = cutoff;
00453 if (numsol==NOVALUE || numsol>numrun) numsol = numrun;
00454 if (numerator==NOVALUE){
00455 switch(heuristic) {
00456 case BEST:
00457 default:
00458 numerator = 0;
00459 break;
00460 }
00461 }
00462 if (wp_numerator==NOVALUE){
00463 switch(heuristic) {
00464 default:
00465 wp_numerator = 0;
00466 break;
00467 }
00468 }
00469 }
00470
00471
00472
00473 void print_statistics_header(void)
00474 {
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 }
00486
00487 void initialize_statistics(void)
00488 {
00489 x = 0; r = 0;
00490 if (hamming_flag) {
00491 read_hamming_file(hamming_target_file);
00492 open_hamming_data(hamming_data_file);
00493 }
00494 tail_start_flip = tail * numatom;
00495
00496 numnullflip = 0;
00497 }
00498
00499 void update_statistics_start_try(void)
00500 {
00501 int i;
00502
00503 lowbad = numfalse;
00504
00505 sample_size = 0;
00506 sumfalse = 0.0;
00507 sumfalse_squared = 0.0;
00508
00509 for (i=0; i<HISTMAX; i++)
00510 tailhist[i] = 0;
00511 if (tail_start_flip == 0){
00512 tailhist[numfalse < HISTMAX ? numfalse : HISTMAX - 1] ++;
00513 }
00514
00515 if (printfalse) save_false_clauses(lowbad);
00516 if (printlow) save_low_assign();
00517 }
00518
00519 void update_and_print_statistics_end_try(void);
00520
00521 void print_statistics_start_flip(void)
00522 {
00523 if (printtrace && (numflip % printtrace == 0)){
00524 printf(" %9li %9i %9li\n", lowbad,numfalse,numflip);
00525 if (trace_assign)
00526 print_current_assign();
00527 fflush(stdout);
00528 }
00529 }
00530
00531 void update_statistics_end_flip(void)
00532 {
00533 if (numfalse < lowbad){
00534 lowbad = numfalse;
00535 if (printfalse) save_false_clauses(lowbad);
00536 if (printlow) save_low_assign();
00537 }
00538 if (numflip >= tail_start_flip){
00539 tailhist[(numfalse < HISTMAX) ? numfalse : (HISTMAX - 1)] ++;
00540 if ((numflip % samplefreq) == 0){
00541 sumfalse += numfalse;
00542 sumfalse_squared += numfalse * numfalse;
00543 sample_size ++;
00544 }
00545 }
00546 }
00547
00548 void print_statistics_final(void)
00549 {
00550 if (numsuccesstry > 0)
00551 {
00552 printf("ASSIGNMENT FOUND\n");
00553 if (printsolcnf) print_sol_cnf();
00554 if (outfile[0]) print_sol_file(outfile);
00555 }
00556 else
00557 printf("ASSIGNMENT NOT FOUND\n");
00558 }
00559
00560
00561 static long super(int i)
00562 {
00563 long power;
00564 int k;
00565
00566 if (i<=0){
00567 fprintf(stderr, "bad argument super(%d)\n", i);
00568 exit(1);
00569 }
00570
00571 k = 1;
00572 power = 2;
00573 while (power < (i+1)){
00574 k += 1;
00575 power *= 2;
00576 }
00577 if (power == (i+1)) return (power/2);
00578 return (super(i - (power/2) + 1));
00579 }
00580
00581 void handle_interrupt(int sig)
00582 {
00583 if (abort_flag) exit(-1);
00584 abort_flag = true;
00585 }
00586
00587 void scanone(int argc, char *argv[], int i, int *varptr)
00588 {
00589 if (i>=argc || sscanf(argv[i],"%i",varptr)!=1){
00590 fprintf(stderr, "Bad argument %s\n", i<argc ? argv[i] : argv[argc-1]);
00591 exit(-1);
00592 }
00593 }
00594
00595 void scanoneu(int argc, char *argv[], int i, unsigned int *varptr)
00596 {
00597 if (i>=argc || sscanf(argv[i],"%u",varptr)!=1){
00598 fprintf(stderr, "Bad argument %s\n", i<argc ? argv[i] : argv[argc-1]);
00599 exit(-1);
00600 }
00601 }
00602
00603 void scanonell(int argc, char *argv[], int i, BIGINT *varptr)
00604 {
00605 if (i>=argc || sscanf(argv[i],"%li",varptr)!=1){
00606 fprintf(stderr, "Bad argument %s\n", i<argc ? argv[i] : argv[argc-1]);
00607 exit(-1);
00608 }
00609 }
00610
00611
00612 int calc_hamming_dist(int atom[], int hamming_target[], int numatom)
00613 {
00614 int i;
00615 int dist = 0;
00616
00617 for (i=1; i<=numatom; i++){
00618 if (atom[i] != hamming_target[i]) dist++;
00619 }
00620 return dist;
00621 }
00622
00623 void open_hamming_data(char initfile[])
00624 {
00625 if ((hamming_fp = fopen(initfile, "w")) == NULL){
00626 fprintf(stderr, "Cannot open %s for output\n", initfile);
00627 exit(1);
00628 }
00629 }
00630
00631
00632 void read_hamming_file(char initfile[])
00633 {
00634 int i;
00635 FILE * infile;
00636 int lit;
00637
00638 printf("loading hamming target file %s ...", initfile);
00639
00640 if ((infile = fopen(initfile, "r")) == NULL){
00641 fprintf(stderr, "Cannot open %s\n", initfile);
00642 exit(1);
00643 }
00644 i=0;
00645 for(i = 1;i < numatom+1;i++)
00646 hamming_target[i] = 0;
00647
00648 while (fscanf(infile, " %d", &lit)==1){
00649 if (abs(lit)>numatom){
00650 fprintf(stderr, "Bad hamming file %s\n", initfile);
00651 exit(1);
00652 }
00653 if (lit>0) hamming_target[lit]=1;
00654 }
00655 printf("done\n");
00656 }
00657
00658
00659 void
00660 print_false_clauses(long int lowbad)
00661 {
00662 int i, j;
00663 int cl;
00664
00665 printf("Unsatisfied clauses:\n");
00666 for (i=0; i<lowbad; i++){
00667 cl = lowfalse[i];
00668 for (j=0; j<size[cl]; j++){
00669 printf("%d ", clause[cl][j]);
00670 }
00671 printf("0\n");
00672 }
00673 printf("End unsatisfied clauses\n");
00674 }
00675
00676 void
00677 save_false_clauses(long int lowbad)
00678 {
00679 int i;
00680
00681 for (i=0; i<lowbad; i++)
00682 lowfalse[i] = wfalse[i];
00683 }
00684
00685
00686 bool initprob();
00687
00688
00689 void flipatom(int toflip)
00690 {
00691 int i, j;
00692 int toenforce;
00693 register int cli;
00694 register int lit;
00695 int numocc;
00696 register int sz;
00697 register int * litptr;
00698 int * occptr;
00699 register int v;
00700
00701
00702 if (toflip == NOVALUE)
00703 {
00704 numnullflip++;
00705 return;
00706 }
00707
00708 changed[toflip] = numflip;
00709 if(atom[toflip] > 0)
00710 {
00711 toenforce = -toflip;
00712 }
00713 else
00714 {
00715 toenforce = toflip;
00716 }
00717 atom[toflip] = 1 - atom[toflip];
00718
00719 if (hamming_flag)
00720 {
00721 if (atom[toflip] == hamming_target[toflip])
00722 hamming_distance--;
00723 else
00724 hamming_distance++;
00725
00726 if ((numflip % hamming_sample_freq) == 0)
00727 fprintf(hamming_fp, "%li %i\n", numflip, hamming_distance);
00728 }
00729
00730 numocc = numoccurence[MAXATOM - toenforce];
00731 occptr = occurence[MAXATOM - toenforce];
00732 for(i = 0; i < numocc ; i++)
00733 {
00734
00735 cli = *(occptr++);
00736
00737 if (--numtruelit[cli] == 0)
00738 {
00739 wfalse[numfalse] = cli;
00740 wherefalse[cli] = numfalse;
00741 numfalse++;
00742
00743 breakcount[toflip]--;
00744
00745 if (makeflag)
00746 {
00747
00748 sz = size[cli];
00749 litptr = clause[cli];
00750 for (j = 0; j < sz; j++)
00751 {
00752
00753 lit = *(litptr++);
00754 makecount[abs(lit)]++;
00755 }
00756 }
00757 }
00758 else if (numtruelit[cli] == 1)
00759 {
00760 if (watch1[cli] == toflip)
00761 {
00762 assert(watch1[cli] != watch2[cli]);
00763 watch1[cli] = watch2[cli];
00764 }
00765 breakcount[watch1[cli]]++;
00766 }
00767 else
00768 {
00769 if (watch1[cli] == toflip)
00770 {
00771
00772 sz = size[cli];
00773 litptr = clause[cli];
00774 for (j = 0; j < sz; j++)
00775 {
00776 lit = *(litptr++);
00777 v = abs(lit);
00778 if ((lit>0) == atom[v] && v != watch1[cli] && v != watch2[cli])
00779 {
00780 watch1[cli] = v;
00781 break;
00782 }
00783 }
00784 }
00785 else
00786 if (watch2[cli] == toflip)
00787 {
00788
00789 sz = size[cli];
00790 litptr = clause[cli];
00791 for (j = 0; j < sz; j++)
00792 {
00793 lit = *(litptr++);
00794 v =abs(lit);
00795 if ((lit>0) == atom[v] && v != watch1[cli] && v != watch2[cli])
00796 {
00797 watch2[cli] = v;
00798 break;
00799 }
00800 }
00801 }
00802 }
00803 }
00804
00805 numocc = numoccurence[MAXATOM+toenforce];
00806 occptr = occurence[MAXATOM+toenforce];
00807 for(i = 0; i < numocc; i++)
00808 {
00809
00810 cli = *(occptr++);
00811
00812 if (++numtruelit[cli] == 1)
00813 {
00814 numfalse--;
00815 wfalse[wherefalse[cli]] = wfalse[numfalse];
00816 wherefalse[wfalse[numfalse]] = wherefalse[cli];
00817
00818 breakcount[toflip]++;
00819
00820 if (makeflag)
00821 {
00822
00823 sz = size[cli];
00824 litptr = clause[cli];
00825 for (j = 0; j < sz; j++)
00826 {
00827
00828 lit = *(litptr++);
00829 makecount[abs(lit)]--;
00830 }
00831 }
00832 watch1[cli] = toflip;
00833 }
00834 else
00835 if (numtruelit[cli] == 2)
00836 {
00837 watch2[cli] = toflip;
00838 breakcount[watch1[cli]]--;
00839 }
00840 }
00841 }
00842
00843 int pickrandom(void)
00844 {
00845 int tofix;
00846
00847 tofix = wfalse[random()%numfalse];
00848 return Var(tofix, random()%size[tofix]);
00849 }
00850
00851 int pickbest(void)
00852 {
00853 int numbreak;
00854 int tofix;
00855 int clausesize;
00856 int i;
00857 int best[MAXLENGTH];
00858 register int numbest;
00859 register int bestvalue;
00860 register int var;
00861
00862 Array<int> canNotFlip;
00863
00864
00865 Array<int> candidateBlockedVars;
00866 Array<int> othersToFlip;
00867
00868 tofix = wfalse[random()%numfalse];
00869 clausesize = size[tofix];
00870 numbest = 0;
00871 bestvalue = BIG;
00872
00873 for (i = 0; i < clausesize; i++)
00874 {
00875 var = abs(clause[tofix][i]);
00876 int otherToFlip = NOVALUE;
00877 int blockIdx = getBlock(var - 1);
00878 if (blockIdx == -1)
00879 numbreak = breakcount[var];
00880 else
00881 {
00882
00883 if ((*blockEvidence_)[blockIdx] || (*blocks_)[blockIdx].size() == 1)
00884 {
00885 numbreak = INT_MAX;
00886
00887 canNotFlip.append(i);
00888 }
00889 else
00890 {
00891 numbreak = calculateNumbreak(var, otherToFlip);
00892 candidateBlockedVars.append(var);
00893 othersToFlip.append(otherToFlip);
00894 }
00895 }
00896
00897 if (numbreak <= bestvalue)
00898 {
00899 if (numbreak < bestvalue) numbest = 0;
00900 bestvalue = numbreak;
00901 best[numbest++] = var;
00902 }
00903 }
00904
00905
00906
00907 int toflip = best[random()%numbest];
00908
00909
00910
00911 if (bestvalue > 0 && (random()%denominator < numerator))
00912 toflip = abs(clause[tofix][random()%clausesize]);
00913
00914 else if (numbest == 1)
00915 toflip = best[0];
00916
00917
00918 if (canNotFlip.contains(toflip)) toflip = NOVALUE;
00919 else
00920 {
00921 int idx = candidateBlockedVars.find(toflip);
00922 if (idx >= 0)
00923 {
00924 inBlock = true;
00925 flipInBlock = othersToFlip[idx];
00926 }
00927 }
00928 return toflip;
00929 }
00930
00931 int picktabu(void)
00932 {
00933 int numbreak[MAXLENGTH];
00934 int tofix;
00935 int clausesize;
00936 int i;
00937 int best[MAXLENGTH];
00938 int numbest;
00939 int bestvalue;
00940 int noisypick;
00941
00942 tofix = wfalse[random()%numfalse];
00943 clausesize = size[tofix];
00944 for(i = 0; i < clausesize; i++)
00945 numbreak[i] = breakcount[abs(clause[tofix][i])];
00946
00947 numbest = 0;
00948 bestvalue = BIG;
00949
00950 noisypick = (numerator > 0 && random()%denominator < numerator);
00951 for (i = 0; i < clausesize; i++)
00952 {
00953 if (numbreak[i] == 0)
00954 {
00955 if (bestvalue > 0)
00956 {
00957 bestvalue = 0;
00958 numbest = 0;
00959 }
00960 best[numbest++] = i;
00961 }
00962 else if (tabu_length < numflip - changed[abs(clause[tofix][i])])
00963 {
00964 if (noisypick && bestvalue > 0)
00965 {
00966 best[numbest++] = i;
00967 }
00968 else
00969 {
00970 if (numbreak[i] < bestvalue)
00971 {
00972 bestvalue = numbreak[i];
00973 numbest = 0;
00974 }
00975 if (numbreak[i] == bestvalue)
00976 {
00977 best[numbest++] = i;
00978 }
00979 }
00980 }
00981 }
00982 if (numbest == 0) return NOVALUE;
00983 if (numbest == 1) return Var(tofix, best[0]);
00984 return (Var(tofix, best[random()%numbest]));
00985 }
00986
00987 int picksa(void);
00988
00989 int countunsat(void)
00990 {
00991 int i, j, unsat, lit, sign;
00992 bool bad;
00993
00994 unsat = 0;
00995 for (i = 0; i < numclause; i++)
00996 {
00997 bad = true;
00998 for (j = 0; j < size[i]; j++)
00999 {
01000 lit = clause[i][j];
01001 sign = lit > 0 ? 1 : 0;
01002 if ( atom[abs(lit)] == sign )
01003 {
01004 bad = false;
01005 break;
01006 }
01007 }
01008
01009 if (bad) unsat++;
01010 }
01011 return unsat;
01012 }
01013
01014
01015 double elapsed_seconds(void)
01016 {
01017 double answer;
01018
01019 #ifdef ANSI
01020 static long prev_time = 0;
01021 time( &long_time );
01022
01023 answer = long_time - prev_time;
01024 prev_time = long_time;
01025 #endif
01026 #ifdef NT
01027 static DWORD prev_time = 0;
01028 win_time = timeGetTime();
01029
01030 answer = (double)(win_time - prev_time) / (double)1000;
01031 prev_time = win_time;
01032 #endif
01033 #ifdef UNIX
01034 static struct tms prog_tms;
01035 static long prev_times = 0;
01036 (void) times(&prog_tms);
01037 answer = ((double)(((long)prog_tms.tms_utime)-prev_times))/((double) CLK_TCK);
01038 prev_times = (long) prog_tms.tms_utime;
01039 #endif
01040 return answer;
01041 }
01042
01043
01044 void print_sol_cnf(void)
01045 {
01046 int i;
01047 for(i = 1;i < numatom+1;i++)
01048 printf("v %i\n", solution[i] == 1 ? i : -i);
01049 }
01050
01051
01052 void print_sol_file(char * filename)
01053 {
01054 FILE * fp;
01055 int i;
01056
01057 if ((fp = fopen(filename, "w"))==NULL){
01058 fprintf(stderr, "Cannot open output file\n");
01059 exit(-1);
01060 }
01061 for(i = 1;i < numatom+1;i++){
01062 fprintf(fp, " %i", solution[i] == 1 ? i : -i);
01063 if (i % 10 == 0) fprintf(fp, "\n");
01064 }
01065 if ((i-1) % 10 != 0) fprintf(fp, "\n");
01066 fclose(fp);
01067 }
01068
01069
01070 void print_low_assign(long int lowbad)
01071 {
01072 int i;
01073
01074 printf("Begin assign with lowest # bad = %li\n", lowbad);
01075 for (i = 1; i <= numatom; i++)
01076 {
01077 printf(" %d", lowatom[i]==0 ? -i : i);
01078 if (i % 10 == 0) printf("\n");
01079 }
01080
01081 if ((i-1) % 10 != 0) printf("\n");
01082 printf("End assign\n");
01083 }
01084
01085 void print_current_assign(void)
01086 {
01087 int i;
01088
01089 printf("Begin assign at flip = %li\n", numflip);
01090 for (i = 1; i <= numatom; i++)
01091 {
01092 printf(" %d", atom[i]==0 ? -i : i);
01093 if (i % 10 == 0) printf("\n");
01094 }
01095
01096 if ((i-1) % 10 != 0) printf("\n");
01097 printf("End assign\n");
01098 }
01099
01100 void save_low_assign(void)
01101 {
01102 int i;
01103
01104 for (i = 1; i <= numatom; i++)
01105 lowatom[i] = atom[i];
01106 }
01107
01108 void save_solution(void)
01109 {
01110 int i;
01111
01112 for (i = 1; i <= numatom; i++)
01113 solution[i] = atom[i];
01114 }
01115
01116
01117 bool fixedAtomInBlock(const int blockIdx)
01118 {
01119 Array<int> block = (*blocks_)[blockIdx];
01120 for (int i = 0; i < block.size(); i++)
01121 if (fixedatom[block[i] + 1] > 0) return true;
01122 return false;
01123 }
01124
01125
01126
01127 void setOthersInBlockToFalse(bool*& assignments,
01128 const int& atomIdx,
01129 const int& blockIdx)
01130 {
01131 Array<int> block = (*blocks_)[blockIdx];
01132 for (int i = 0; i < block.size(); i++)
01133 {
01134 if (i != atomIdx)
01135 assignments[block[i]] = false;
01136 }
01137 }
01138
01139
01140
01141 void setOthersInBlockToFalse(const int& atomIdx,
01142 const int& blockIdx)
01143 {
01144 Array<int> block = (*blocks_)[blockIdx];
01145 for (int i = 0; i < block.size(); i++)
01146 {
01147 if (i != atomIdx)
01148 atom[block[i] + 1] = 0;
01149 }
01150 }
01151
01152
01153
01154 int getBlock(const int& atomIdx)
01155 {
01156 for (int i = 0; i < blocks_->size(); i++)
01157 {
01158 int blockIdx = (*blocks_)[i].find(atomIdx);
01159 if (blockIdx >= 0)
01160 return i;
01161 }
01162 return -1;
01163 }
01164
01165
01166
01167 int calculateChange(const int& atomIdx)
01168 {
01169 int blockIdx = getBlock(atomIdx - 1);
01170 assert(blockIdx >= 0);
01171
01172
01173 Array<int> block = (*blocks_)[blockIdx];
01174 int chosen = -1;
01175
01176
01177 if (atom[atomIdx] == 0)
01178 {
01179 for (int i = 0; i < block.size(); i++)
01180 {
01181 if (atom[block[i] + 1] == 1)
01182 {
01183 chosen = i;
01184 break;
01185 }
01186 }
01187 }
01188
01189 else
01190 {
01191 bool ok = false;
01192 while(!ok)
01193 {
01194 chosen = random() % block.size();
01195 if (block[chosen] + 1 != atomIdx)
01196 ok = true;
01197 }
01198 }
01199
01200 assert(chosen >= 0);
01201 inBlock = true;
01202 flipInBlock = block[chosen] + 1;
01203 return makecount[atomIdx] + makecount[flipInBlock] -
01204 breakcount[atomIdx] - breakcount[flipInBlock];
01205 }
01206
01207
01208
01209 int calculateNumbreak(const int& atomIdx, int& otherToFlip)
01210 {
01211 int blockIdx = getBlock(atomIdx - 1);
01212 assert(blockIdx >= 0);
01213
01214
01215 Array<int> block = (*blocks_)[blockIdx];
01216 int chosen = -1;
01217
01218
01219 if (atom[atomIdx] == 0)
01220 {
01221 for (int i = 0; i < block.size(); i++)
01222 {
01223 if (atom[block[i] + 1] == 1)
01224 {
01225 chosen = i;
01226 break;
01227 }
01228 }
01229 }
01230
01231
01232 else
01233 {
01234 bool ok = false;
01235 while(!ok)
01236 {
01237 chosen = random() % block.size();
01238 if (block[chosen] + 1 != atomIdx)
01239 ok = true;
01240 }
01241 }
01242
01243 assert(chosen >= 0);
01244 otherToFlip = block[chosen] + 1;
01245 return breakcount[atomIdx] + breakcount[otherToFlip];
01246 }
01247 };
01248
01249 #endif
01250