void WalksatAlgorithm::update_and_print_statistics_end_try(void)
{
    int i;
    int j;

    totalflip += numflip;
    x += numflip;
    r ++;

    if (sample_size > 0){
	avgfalse = sumfalse/sample_size;
	second_moment_avgfalse = sumfalse_squared / sample_size;
	variance_avgfalse = second_moment_avgfalse - (avgfalse * avgfalse);
	if (sample_size > 1) { variance_avgfalse = (variance_avgfalse * sample_size)/(sample_size - 1); }
	std_dev_avgfalse = sqrt(variance_avgfalse);

	ratio_avgfalse = avgfalse / std_dev_avgfalse;

	sum_avgfalse += avgfalse;
	sum_std_dev_avgfalse += std_dev_avgfalse;
	number_sampled_runs += 1;

	if (numfalse <= target){
	    suc_number_sampled_runs += 1;
	    suc_sum_avgfalse += avgfalse;
	    suc_sum_std_dev_avgfalse += std_dev_avgfalse;
	}
	else {
	    nonsuc_number_sampled_runs += 1;
	    nonsuc_sum_avgfalse += avgfalse;
	    nonsuc_sum_std_dev_avgfalse += std_dev_avgfalse;
	}
    }
    else{
	avgfalse = 0;
	variance_avgfalse = 0;
	std_dev_avgfalse = 0;
	ratio_avgfalse = 0;
    }

    if(numfalse <= target){

	status_flag = 0;

	save_solution();
	numsuccesstry++;

	totalsuccessflip += numflip;
	integer_sum_x += x;
	sum_x = (double) integer_sum_x;
	sum_x_squared += ((double)x)*((double)x);
	mean_x = sum_x / numsuccesstry;
	if (numsuccesstry > 1){
	    second_moment_x = sum_x_squared / numsuccesstry;
	    variance_x = second_moment_x - (mean_x * mean_x);
	    /* Adjustment for small small sample size */
	    variance_x = (variance_x * numsuccesstry)/(numsuccesstry - 1);
	    std_dev_x = sqrt(variance_x);
	    std_error_mean_x = std_dev_x / sqrt((double)numsuccesstry);
	}
	sum_r += r;
	mean_r = ((double)sum_r)/numsuccesstry;
	sum_r_squared += ((double)r)*((double)r);

	x = 0;
	r = 0;
    }

    if(verbosity) {  
      printf(" %9li %9i %9.2f %9.2f %9.2f %9" BIGINTSTR " %9i",
	     lowbad,numfalse,avgfalse, std_dev_avgfalse,ratio_avgfalse,numflip, (numsuccesstry*100)/numtry);
      if (numsuccesstry > 0){
	printf(" %9" BIGINTSTR , totalsuccessflip/numsuccesstry);
	printf(" %11.2f", mean_x);
	if (numsuccesstry > 1){
	  printf(" %11.2f", std_dev_x);
	}
      }
      printf("\n");
      
      if (printhist){
	printf("histogram: ");
	for (j=HISTMAX-1; tailhist[j] == 0; j--);
	for (i=0; i<=j; i++){
	  printf(" %li(%i)", tailhist[i], i);
	  if ((i+1) % 10 == 0) printf("\n           ");
	}
	if (j==HISTMAX-1) printf(" +++");
	printf("\n");
      }
      
      if (numfalse>0 && printfalse)
	print_false_clauses(lowbad);
      if (printlow && (!printonlysol || numfalse >= target))
	print_low_assign(lowbad);
      
      if(numfalse == 0 && countunsat() != 0){
	fprintf(stderr, "Program error, verification of solution fails!\n");
	exit(-1);
      }
      
      fflush(stdout);
    }
}
Beispiel #2
0
int main(int argc,char *argv[])
{
    int i;			/* loop counter */
    int j;			/* another loop counter */
    int k;			/* yet another loop counter */
    char initfile[100] = { 0 };
    int numrun = 10;
    int cutoff = 100000;
    int base_cutoff = 100000;
    int printonlysol = FALSE;
    int printsolcnf = FALSE;
    int printfalse = FALSE;
    int printlow = FALSE;
    int initoptions = FALSE;
    int superlinear = FALSE;
    int printtrace = FALSE;
    long int totalflip = 0;	/* total number of flips in all tries so far */
    long int totalsuccessflip = 0; /* total number of flips in all tries which succeeded so far */
    int numtry = 0;		/* total attempts at solutions */
    int numsuccesstry = 0;	/* total found solutions */
    int numsol = 1;	        /* stop after this many tries succeeds */
    int tochange;
    int seed;			/* seed for random */
    struct timeval tv;
    struct timezone tzp;
    double expertime;
    long flips_this_solution;
    long int lowbad;		/* lowest number of bad clauses during try */
    long int lowcost;		/* lowest cost of bad clauses during try */
    int targetcost = 0;		/* the cost at which the program terminates*/
    long x;
    long integer_sum_x = 0;
    double sum_x = 0.0;
    double sum_x_squared = 0.0;
    double mean_x;
    double second_moment_x;
    double variance_x;
    double std_dev_x;
    double std_error_mean_x;
    double seconds_per_flip;
    int r;
    int sum_r = 0;
    double sum_r_squared = 0.0;
    double mean_r;
    double variance_r;
    double std_dev_r;
    double std_error_mean_r;
    int worst_cost, computed_cost;

    gettimeofday(&tv,&tzp);
    seed = (( tv.tv_sec & 0177 ) * 1000000) + tv.tv_usec;
    heuristic = BEST;
    numerator = NOVALUE;
    denominator = 100;

    for (i=1;i < argc;i++)
      {
 	  if (strcmp(argv[i],"-withcost") == 0)
	    costexpected = TRUE;
	  else if (strcmp(argv[i],"-seed") == 0)
	    scanone(argc,argv,++i,&seed);
	  else if (strcmp(argv[i],"-targetcost") == 0)
	    scanone(argc,argv,++i,&targetcost);
	  else if (strcmp(argv[i],"-cutoff") == 0)
	    scanone(argc,argv,++i,&cutoff);
	  else if (strcmp(argv[i],"-random") == 0)
	    heuristic = RANDOM;
	  else if (strcmp(argv[i],"-productsum") == 0)
	    heuristic = PRODUCTSUM;
	  else if (strcmp(argv[i],"-reciprocal") == 0)
	    heuristic = RECIPROCAL;
	  else if (strcmp(argv[i],"-additive") == 0)
	    heuristic = ADDITIVE;
	  else if (strcmp(argv[i],"-exponential") == 0)
	    heuristic = EXPONENTIAL;
	  else if (strcmp(argv[i],"-best") == 0)
	    heuristic = BEST;
	  else if (strcmp(argv[i],"-noise") == 0)
	    {
		scanone(argc,argv,++i,&numerator);
		scanone(argc,argv,++i,&denominator);
	    }
	  else if (strcmp(argv[i],"-init") == 0  && i < argc-1)
	    sscanf(argv[++i], " %s", initfile);
	  else if (strcmp(argv[i],"-partial") == 0)
	    initoptions = INIT_PARTIAL;
	  else if (strcmp(argv[i],"-super") == 0)
	    superlinear = TRUE;
	  else if (strcmp(argv[i],"-tries") == 0)
	    scanone(argc,argv,++i,&numrun);
	  else if (strcmp(argv[i],"-tabu") == 0)
	    {
		scanone(argc,argv,++i,&tabu_length);
		heuristic = TABU;
	    }
	  else if (strcmp(argv[i],"-low") == 0)
	    printlow = TRUE;
	  else if (strcmp(argv[i],"-sol") == 0)
	    {
		printonlysol = TRUE;
		printlow = TRUE;
	    }
	  else if (strcmp(argv[i],"-bad") == 0)
	    printfalse = TRUE;
	  else if (strcmp(argv[i],"-hard") == 0)
	    hard = TRUE;
	  else if (strcmp(argv[i],"-numsol") == 0)
	    scanone(argc,argv,++i,&numsol);
	  else if (strcmp(argv[i],"-trace") == 0)
	    scanone(argc,argv,++i,&printtrace);
	  else 
	    {
		fprintf(stderr, "Bad argument %s\n", argv[i]);
		fprintf(stderr, "General parameters:\n");
		fprintf(stderr, "  -seed N -cutoff N -tries N\n");
		fprintf(stderr, "  -numsol N = stop after finding N solutions\n");
		fprintf(stderr, "  -init FILE = set vars not included in FILE to false\n");
		fprintf(stderr, "  -partial FILE = set vars not included in FILE randomly\n");
		fprintf(stderr, "  -withcost = input is a set of weighted clauses\n");
		fprintf(stderr, "  -targetcost N = find assignments of cost <= N (MAXSAT)\n");
		fprintf(stderr, "  -hard = never break a highest-cost clause\n");
		fprintf(stderr, "Heuristics:\n");
		fprintf(stderr, "  -noise N M -best -super -tabu N\n");
		fprintf(stderr, "  -productsum -reciprocal -additive -exponential\n");
		fprintf(stderr, "Printing:\n");
		fprintf(stderr, "  -trace N = print statistics every N flips\n");
		fprintf(stderr, "  -sol = print assignments where cost < target\n");
		fprintf(stderr, "  -low = print lowest assignment each try\n");
		fprintf(stderr, "  -bad = print unsat clauses each try\n");
		fprintf(stderr, "  -solcnf = print sat assign in cnf format, and exit\n");
		exit(-1);
	    }
      }
    base_cutoff = cutoff;
    if (numerator==NOVALUE){
	if (heuristic==BEST)
	  numerator = 50;
	else
	  numerator = 0;
    }

    srandom(seed);
#ifdef Huge
    printf("maxwalksat version 20 (Huge)\n");
#else
    printf("maxwalksat version 20\n");
#endif
    printf("seed = %i\n",seed);
    printf("cutoff = %i\n",cutoff);
    printf("tries = %i\n",numrun);
    printf("numsol = %i\n",numsol);
    printf("targetcost = %i\n",targetcost);

    printf("heuristic = ");

    switch(heuristic)
      {
	case RANDOM:
	  printf("random");
	  break;
	case PRODUCTSUM:
	  printf("productsum");
	  break;
	case RECIPROCAL:
	  printf("reciprocal");
	  break;
	case ADDITIVE:
	  printf("additive");
	  break;
	case BEST:
	  printf("best");
	  break;
	case EXPONENTIAL:
	  printf("exponential");
	  break;
	case TABU:
	  printf("tabu %d", tabu_length);
	  break;
      }
    if (numerator>0){
	printf(", noise %d / %d", numerator, denominator);
    }
    if (superlinear)
      printf(", super");
    if (printtrace)
      printf(", trace %d", printtrace);
    if (initfile[0]){
	printf(", init %s", initfile);
	if (initoptions == INIT_PARTIAL)
	  printf(", partial");
    }
    printf("\n");
    
    initprob();

    if (costexpected) printf("clauses contain explicit costs\n");
    else printf("clauses all assigned default cost of 1\n");

    printf("numatom = %i, numclause = %i, numliterals = %i\n",numatom,numclause,numliterals);
    printf("wff read in\n");
    printf("                                           average             average       mean              standard\n");
    printf("    lowest     worst    number                when                over      flips                 error\n");
    printf("      cost    clause    #unsat    #flips     model   success       all      until        std         of\n");
    printf("  this try  this try  this try  this try     found      rate     tries     assign        dev       mean\n");

    signal(SIGINT, (void *) handle_interrupt);
    abort_flag = FALSE;
    numnullflip = 0;
    (void) elapsed_seconds();
    x = 0; r = 0;
    lowcost = BIG;
    for(k = 0;k < numrun;k++)
      {
	  init(initfile, initoptions);
	  lowbad = numfalse; 
	  lowcost = costofnumfalse;
	  save_low_assign();
	  numflip = 0;

	  if (superlinear) cutoff = base_cutoff * super(r+1);

	  while((numflip < cutoff) && (costofnumfalse > targetcost))
	    {
		if (printtrace && (numflip % printtrace == 0)){
		    printf("%10i          %10i%10li\n", costofnumfalse,numfalse,numflip);
		    fflush(stdout);
		}
		numflip++;
                if ((eqhighest) && (highestcost!=1))
                {/* fprintf(stderr, "number of highest %i\n", numhighest);*/ 	
			fix(selecthigh(1+random()%numhighest));
                }
		else fix(false[random()%numfalse]);
	        if (costofnumfalse < lowcost)
	        {
		    lowcost = costofnumfalse;
		    lowbad = numfalse;
		    save_low_assign();
		}
	    }
	  numtry++;
	  totalflip += numflip;
	  x += numflip;
	  r ++;
	  if(costofnumfalse<=targetcost)
	    {
		numsuccesstry++;
		totalsuccessflip += numflip;
		integer_sum_x += x;
		sum_x = (double) integer_sum_x;
		sum_x_squared += ((double)x)*((double)x);
		mean_x = sum_x / numsuccesstry;
		if (numsuccesstry > 1){
		    second_moment_x = sum_x_squared / numsuccesstry;
		    variance_x = second_moment_x - (mean_x * mean_x);
		    /* Adjustment for small small sample size */
		    variance_x = (variance_x * numsuccesstry)/(numsuccesstry - 1);
		    std_dev_x = sqrt(variance_x);
		    std_error_mean_x = std_dev_x / sqrt((double)numsuccesstry);
		}
		sum_r += r;
		mean_r = ((double)sum_r)/numsuccesstry;
		sum_r_squared += ((double)r)*((double)r);
		x = 0;
		r = 0;
	    }

	  countlowunsatcost(&computed_cost, &worst_cost);
	  if(lowcost != computed_cost)
	    {
		fprintf(stderr, "Program error, verification of assignment cost fails!\n");
		exit(-1);
	    }

	  if(numsuccesstry == 0)
	    printf("%10i%10i%10i%10li         *         0         *          *          *          *\n",
		   lowcost,worst_cost,lowbad,numflip);
	  else if (numsuccesstry == 1)
	    printf("%10i%10i%10i%10li%10li%10i%10li %10.1f          *          *\n",
		   lowcost,worst_cost,lowbad,numflip,totalsuccessflip/numsuccesstry,
		   (numsuccesstry*100)/numtry,totalflip/numsuccesstry,
		   mean_x);
	  else
	    printf("%10i%10i%10i%10li%10li%10i%10li %10.1f %10.1f %10.1f\n",
		   lowcost,worst_cost,lowbad,numflip,totalsuccessflip/numsuccesstry,
		   (numsuccesstry*100)/numtry,totalflip/numsuccesstry,
		   mean_x, std_dev_x, std_error_mean_x);
	  if (numfalse>0 && printfalse)
	    print_false_clauses_cost(lowbad);
	  if (printlow && (!printonlysol || costofnumfalse<=targetcost))
	    print_low_assign(lowcost);

	  if (numsuccesstry >= numsol) break;
	  if (abort_flag) break;
	  fflush(stdout);
      }
    expertime = elapsed_seconds();
    seconds_per_flip = expertime / totalflip;
    printf("\ntotal elapsed seconds = %f\n", expertime);
    printf("average flips per second = %d\n", (long)(totalflip/expertime));
    if (heuristic == TABU)
      printf("proportion null flips = %f\n", ((double)numnullflip)/totalflip);
    printf("number of solutions found = %d\n", numsuccesstry);
    if (numsuccesstry > 0)
      {
	  printf("mean flips until assign = %f\n", mean_x);
	  if (numsuccesstry>1){
	      printf("  variance = %f\n", variance_x);
	      printf("  standard deviation = %f\n", std_dev_x);
	      printf("  standard error of mean = %f\n", std_error_mean_x);
	  }
	  printf("mean seconds until assign = %f\n", mean_x * seconds_per_flip);
	  if (numsuccesstry>1){
	      printf("  variance = %f\n", variance_x * seconds_per_flip * seconds_per_flip);
	      printf("  standard deviation = %f\n", std_dev_x * seconds_per_flip);
	      printf("  standard error of mean = %f\n", std_error_mean_x * seconds_per_flip);
	  }
	  printf("mean restarts until assign = %f\n", mean_r);
	  if (numsuccesstry>1){
	      variance_r = (sum_r_squared / numsuccesstry) - (mean_r * mean_r);
	      variance_r = (variance_r * numsuccesstry)/(numsuccesstry - 1);	   
	      std_dev_r = sqrt(variance_r);
	      std_error_mean_r = std_dev_r / sqrt((double)numsuccesstry);
	      printf("  variance = %f\n", variance_r);
	      printf("  standard deviation = %f\n", std_dev_r);
	      printf("  standard error of mean = %f\n", std_error_mean_r);
	  }
      }

    if (numsuccesstry > 0)
      {
	  printf("ASSIGNMENT ACHIEVING TARGET %i FOUND\n", targetcost);
	  if(printsolcnf == TRUE)
	    for(i = 1;i < numatom+1;i++)
	      printf("v %i\n", atom[i] == 1 ? i : -i);
      }
    else
      printf("ASSIGNMENT NOT FOUND\n");
    return 0;
}