samplesat.cpp

00001 /*
00002  * All of the documentation and software included in the
00003  * Alchemy Software is copyrighted by Stanley Kok, Parag
00004  * Singla, Matthew Richardson, Pedro Domingos, Marc
00005  * Sumner and Hoifung Poon.
00006  * 
00007  * Copyright [2004-07] Stanley Kok, Parag Singla, Matthew
00008  * Richardson, Pedro Domingos, Marc Sumner and Hoifung
00009  * Poon. All rights reserved.
00010  * 
00011  * Contact: Pedro Domingos, University of Washington
00012  * (pedrod@cs.washington.edu).
00013  * 
00014  * Redistribution and use in source and binary forms, with
00015  * or without modification, are permitted provided that
00016  * the following conditions are met:
00017  * 
00018  * 1. Redistributions of source code must retain the above
00019  * copyright notice, this list of conditions and the
00020  * following disclaimer.
00021  * 
00022  * 2. Redistributions in binary form must reproduce the
00023  * above copyright notice, this list of conditions and the
00024  * following disclaimer in the documentation and/or other
00025  * materials provided with the distribution.
00026  * 
00027  * 3. All advertising materials mentioning features or use
00028  * of this software must display the following
00029  * acknowledgment: "This product includes software
00030  * developed by Stanley Kok, Parag Singla, Matthew
00031  * Richardson, Pedro Domingos, Marc Sumner and Hoifung
00032  * Poon in the Department of Computer Science and
00033  * Engineering at the University of Washington".
00034  * 
00035  * 4. Your publications acknowledge the use or
00036  * contribution made by the Software to your research
00037  * using the following citation(s): 
00038  * Stanley Kok, Parag Singla, Matthew Richardson and
00039  * Pedro Domingos (2005). "The Alchemy System for
00040  * Statistical Relational AI", Technical Report,
00041  * Department of Computer Science and Engineering,
00042  * University of Washington, Seattle, WA.
00043  * http://www.cs.washington.edu/ai/alchemy.
00044  * 
00045  * 5. Neither the name of the University of Washington nor
00046  * the names of its contributors may be used to endorse or
00047  * promote products derived from this software without
00048  * specific prior written permission.
00049  * 
00050  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF WASHINGTON
00051  * AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00052  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00053  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00054  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY
00055  * OF WASHINGTON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00056  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00057  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00058  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00059  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00060  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00061  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00062  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00063  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00064  * 
00065  */
00066 
00067 /************************************
00068  * Near-Uniform Sampler
00069  * Adapted for MC-SAT
00070  * Original:
00071         WalkSAT v45 by Kautz
00072         SampleSat by Wei et.al.
00073  ************************************/
00074 #include "samplesat.h"
00075 #include "timer.h"
00076 
00077 char* heuristic_names[] = { "random", "best", "tabu", "sa"};
00078 
00079 // ---------------------------------- //
00080 // - Impl
00081 // ---------------------------------- //
00082 SampleSat::SampleSat(const SampleSatParams & params, int numGndPreds, int maxClause,
00083                                          int maxLen, int maxLitOccurence, int* fixedAtoms, int** clauses,
00084                      const Array<Array<int> >* const & blocks,
00085                      const Array<bool >* const & blockEvidence)
00086 {
00087   cout<<"Init Samplesat ..."<<endl;
00088 
00089         // -- samplesat param
00090   saRatio = params.saRatio;
00091   temperature = params.temperature;
00092   latesa = params.latesa;
00093   numsol = params.numsol;
00094   numerator = params.ws_noise;
00095   numrun = params.ws_restart;
00096   cutoff = base_cutoff = params.ws_cutoff;
00097 
00098         // -- WS data
00099   numatom = MAXATOM = numGndPreds;               
00100   MAXCLAUSE = maxClause;
00101   MAXLENGTH = maxLen;
00102         //MAXLENGTH = 500;
00103 
00104   numoccurence = new int[2*MAXATOM+1];
00105   atom = new int[2*MAXATOM+1];
00106   lowatom = new int[2*MAXATOM+1];
00107   solution = new int[2*MAXATOM+1];
00108   changed = new int[2*MAXATOM+1];
00109   breakcount = new int[2*MAXATOM+1];
00110   makecount = new int[2*MAXATOM+1];
00111 
00112         // for unit propagation
00113         //fixedatom = new int[MAXATOM+1];
00114   fixedatom = fixedAtoms;
00115   isSat = new bool[MAXCLAUSE];
00116 
00117   blocks_ = new Array<Array<int> >(*blocks);
00118   blockEvidence_ = new Array<bool>(*blockEvidence);
00119   
00120     // Init to not in block
00121   inBlock = false;
00122   flipInBlock = NOVALUE;
00123   clause = clauses;
00124 
00125   size = new int[MAXCLAUSE];
00126   wfalse = new int[MAXCLAUSE];
00127   lowfalse = new int[MAXCLAUSE];
00128   wherefalse = new int[MAXCLAUSE];
00129   numtruelit = new int[MAXCLAUSE];
00130 
00131         // -- for new flip
00132   watch1 = new int[MAXCLAUSE];
00133   watch2 = new int[MAXCLAUSE];
00134 
00135   occurence = new int*[2*MAXATOM+1];
00136   for (int i = 0; i <= 2*MAXATOM; i++)
00137   {
00138         occurence[i] = new int[maxLitOccurence];
00139   }
00140 
00141   int idx = 0;
00142   pickcode[idx++] = &SampleSat::pickrandom;
00143   pickcode[idx++] = &SampleSat::pickbest;
00144   pickcode[idx++] = &SampleSat::picktabu;
00145   pickcode[idx++] = &SampleSat::picksa;
00146 
00147         // from initVars()
00148   denominator = 100;
00149   heuristic = SA;               /* heuristic to be used */
00150   tabu_length = 5;              /* length of tabu list */
00151   wp_numerator = NOVALUE;       /* walk probability numerator/denominator */
00152   wp_denominator = 100;         
00153   superlinear = true; 
00154     /* SA - set to true by heuristics that require the make values to be calculated */
00155   makeflag = true;
00156 
00157         /* Histogram of tail */
00158   tail = 3;
00159 
00160         /* Printing options */
00161   printonlysol = false;
00162   printsolcnf = false;
00163   printfalse = false;
00164   printlow = false;
00165   printhist = false;
00166   printtrace = 0;
00167   //printtrace = 1000;
00168   trace_assign = false;
00169 
00170   outfile[0] = 0;
00171 
00172         /* Initialization options */
00173   initfile[0] = 0;
00174   initoptions = false;
00175 }
00176 
00177 SampleSat::~SampleSat()
00178 {
00179   for (int i = 0; i <= 2*MAXATOM; i++)
00180   {
00181         delete [] occurence[i];
00182   }
00183   delete [] occurence;
00184   delete [] numoccurence;
00185   delete [] atom;
00186   delete [] lowatom;
00187   delete [] solution;
00188   delete [] changed;
00189   delete [] breakcount;
00190   delete [] makecount;
00191         
00192   delete [] size;
00193   delete [] wfalse;
00194   delete [] lowfalse;
00195   delete [] wherefalse;
00196   delete [] numtruelit;
00197 
00198   delete [] watch1;
00199   delete [] watch2;
00200   
00201   for (int i = 0; i < blocks_->size(); i++)
00202     (*blocks_)[i].clearAndCompress();
00203   delete blocks_;
00204     
00205   delete blockEvidence_;
00206 }
00207 
00208 // Samplesat algorithm
00209 bool SampleSat::sample(bool*& assignments, int numClauses,
00210                        const Array<Array<int> >* const & blocks,
00211                        const Array<bool>* const & blockEvidence)
00212 {
00213     // init random: this is independent of the randomizer used in infer
00214   gettimeofday(&tv,&tzp);
00215   seed = (unsigned int)((( tv.tv_sec & 0177 ) * 1000000) + tv.tv_usec);
00216   srandom(seed);
00217 
00218   for (int i = 0; i < blocks_->size(); i++)
00219     (*blocks_)[i].clearAndCompress();
00220   delete blocks_;
00221   delete blockEvidence_;
00222 
00223   blocks_ = new Array<Array<int> >(*blocks);
00224   blockEvidence_ = new Array<bool>(*blockEvidence);
00225     
00226         //cout<<"In SampleSat.sample ..."<<endl;
00227   numclause = numClauses;
00228 
00229         // -- if no curr sat, randomly flip
00230   if (numclause == 0)
00231   {
00232       // For each block: select one to set to true
00233     for (int i = 0; i < blocks_->size(); i++)
00234     {
00235       Array<int> block = (*blocks_)[i];
00236       
00237         // True fixed atom in the block: do nothing
00238       if (fixedAtomInBlock(i))
00239         continue;
00240 
00241         // If evidence atom exists, then all others are false
00242       if ((*blockEvidence_)[i])
00243       {
00244           // If 2nd argument is -1, then all are set to false
00245         setOthersInBlockToFalse(assignments, -1, i);
00246         continue;
00247       }
00248       
00249       int chosen = random() % block.size();
00250       assignments[block[chosen]] = true;
00251       setOthersInBlockToFalse(assignments, chosen, i);
00252     }
00253       
00254       // Random tv for all not in blocks
00255         for (int i = 1; i <= MAXATOM; i++)
00256         {
00257           if (fixedatom[i] >= 0) assignments[i-1] = (fixedatom[i] == 1);
00258       else if (getBlock(i-1) >= 0) continue;
00259           else assignments[i-1] = (random() < RAND_MAX/2);
00260         }
00261         return true;
00262   }
00263 
00264   initVars();           // initialize variables 
00265     
00266   Timer timer;
00267   double begSec = timer.time();
00268   
00269   if (!initprob())
00270   {
00271         return false;
00272   }
00273   //cout << "time taken for UP = "; Timer::printTime(cout, timer.time()-begSec);
00274   //cout << endl;
00275 
00276 //cout << "Numatom after UP: " << numatom << endl;
00277 //cout << "Numclause after UP: " << numclause << endl;
00278     // -- if no curr sat, randomly flip
00279   if (numclause == 0)
00280   {
00281       // For each block: select one to set to true
00282     for (int i = 0; i < blocks_->size(); i++)
00283     {
00284       Array<int> block = (*blocks_)[i];
00285         // Fixed atoms have been removed from the blocks
00286         // If evidence atom exists, then all others are false
00287       if ((*blockEvidence_)[i])
00288       {
00289         for (int j = 0; j < block.size(); j++)
00290         {
00291           int newIdx = block[j];
00292           int oldIdx = newToOldMapping_[newIdx];
00293           assignments[oldIdx - 1] = false;
00294         }
00295         continue;
00296       }
00297       
00298       int chosen = random() % block.size();
00299       int newIdx = block[chosen];
00300       int oldIdx = newToOldMapping_[newIdx];
00301       assignments[oldIdx - 1] = true;
00302       for (int j = 0; j < block.size(); j++)
00303       {
00304         if (j == chosen) continue;
00305         int newOtherIdx = block[j];
00306         int oldOtherIdx = newToOldMapping_[newOtherIdx];
00307         assignments[oldOtherIdx - 1] = false;
00308       }
00309     }
00310       
00311       // Random tv for all not in blocks
00312     for (int i = 1; i <= MAXATOM; i++)
00313     {
00314       if (fixedatom[i] >= 0) assignments[i-1] = (fixedatom[i] == 1);
00315       else if (getBlock(-(fixedatom[i] + 1)) >= 0) continue;
00316       else assignments[i-1] = (random() < RAND_MAX/2);
00317     }
00318 
00319     return true;
00320   }
00321 
00322   initRandom(); // random restart each time
00323 
00324   begSec = timer.time(); 
00325   
00326   while (numsuccesstry < numsol && numtry < numrun*numsol)
00327   {
00328         numtry++;
00329           //update_statistics_start_try();
00330         numflip = 0;    
00331         if (superlinear) cutoff = base_cutoff * super(numtry);  
00332 
00333         while(numflip < cutoff && numsuccesstry < numsol)
00334         {
00335           print_statistics_start_flip();
00336           numflip++;
00337           flipatom((this->*(pickcode[heuristic]))());
00338         // If in a block, then another atom was also chosen to flip
00339       if (inBlock)
00340       {
00341         flipatom(flipInBlock);
00342       }
00343         // set in block back to false
00344       inBlock = false;
00345       flipInBlock = NOVALUE;
00346       
00347                 //update_statistics_end_flip();
00348           if (numfalse==0) update_and_print_statistics_end_try();
00349         }
00350                 //update_and_print_statistics_end_try();
00351 
00352           // If unsat random restart
00353     if (numsuccesstry <= 0) initRandom();
00354           // if (numfalse > target) initRandom();
00355 
00356   }
00357 
00358   //cout << "time taken for flipping = "; Timer::printTime(cout, timer.time()-begSec);
00359   //cout << endl;
00360   
00361   if (numsuccesstry > 0)
00362   {
00363         for (int i = 1; i <= MAXATOM; i++)
00364         {
00365           if (fixedatom[i] >= 0) assignments[i-1] = (fixedatom[i] == 1);
00366           else assignments[i-1] = (solution[-fixedatom[i]] == 1);
00367         }
00368         return true;
00369   }
00370   else return false;
00371 }
00372 
00373 // Init w. Unit propagation
00374 bool SampleSat::initprob()
00375 {
00376   //cout << "=== initProb w. unit prop: query clauses=" << numclause << endl;
00377   int i;
00378   int lit;
00379 
00380   if(numclause > MAXCLAUSE)
00381   {
00382         fprintf(stderr,"ERROR - too many clauses\n"); 
00383         exit(-1);                              
00384   }
00385 
00386   bool done = false;
00387   int numfixedatom = 0, numsat = 0;
00388   for (i = 0; i < numclause; i++)
00389   {
00390         isSat[i] = false;
00391   }
00392 
00393   while (!done)
00394   {
00395         done = true;
00396     for (i = 0; i < numclause; i++)
00397     {
00398       if (!isSat[i])
00399       {
00400                 int nonUnitNum = 0;
00401                 int nonUnitIdx = -1;
00402                 int j = 0;
00403                 while (clause[i][j] != 0)
00404                 {
00405                   int lit = clause[i][j];
00406                   int var = (lit > 0)? lit : -lit;
00407                   if (fixedatom[var] == -1)
00408                   { // Not fixed
00409                         nonUnitNum++;
00410                         nonUnitIdx = j;
00411                   }
00412                   else
00413           if ((fixedatom[var] == 0 && lit < 0) ||
00414               (fixedatom[var] == 1 && lit > 0))
00415                   { // Fixed and satisfied
00416                         isSat[i] = true;
00417                         numsat++;
00418                         break;
00419                   }
00420                   j++;
00421                 }
00422                 
00423           // Exactly one non-fixed atom in clause and not satisfied
00424         if (!isSat[i] && nonUnitNum==1)
00425                 {
00426                   int lit = clause[i][nonUnitIdx];
00427                   int var = (lit > 0)? lit : -lit;
00428                   fixedatom[var] = (lit > 0)? 1 : 0;
00429                   isSat[i] = true;
00430                   done = false;
00431                   numfixedatom++;
00432           numsat++;
00433                 }
00434           }
00435     }
00436   }
00437   //cout << "\tnumunit=" << numunit <<endl;
00438   //cout << "\tafter unit propagation: numfixedatom="<<numfixedatom<<" : numsat="<<numsat<<endl;
00439 
00440         // delegate to subproblem w backbone removed
00441   numliterals = 0;
00442   for(i = 0; i < 2*MAXATOM + 1; i++) numoccurence[i] = 0;
00443 
00444   int nc = numclause;
00445   numatom = 0, numclause = 0;
00446   newToOldMapping_.clearAndCompress();
00447   for (i = 1; i <= MAXATOM; i++) 
00448   {
00449     // mapping i => -k_i
00450     if (fixedatom[i] < 0)
00451     {
00452       fixedatom[i] = -(++numatom);
00453       newToOldMapping_.append(i);
00454     }
00455   }
00456   
00457     // Take new mapping into account in the blocks
00458   for (i = 0; i < blocks_->size(); i++)
00459   {
00460     int fixedTrueAtoms = 0;
00461     Array<int>& block = (*blocks_)[i];
00462     for (int j = 0; j < block.size(); j++)
00463     {
00464       int num = fixedatom[block[j] + 1];
00465         // Atom is fixed to true
00466       if (num == 1)
00467       {
00468         if (fixedTrueAtoms > 0)
00469         {
00470           cout << "Inconsistent fixed assignment! Two atoms in one block "
00471                << "are fixed to true through unit propagation." << endl;
00472           exit(-1);
00473         }
00474         if ((*blockEvidence_)[i])
00475         {
00476           cout << "Inconsistent fixed assignment! An atom in a block "
00477                << "is fixed to true which contradicts evidence." << endl;
00478           exit(-1);
00479         }
00480         fixedTrueAtoms++;
00481         block.removeItem(j--);
00482       }
00483         // Atom is fixed to false
00484       else if (num == 0)
00485       {
00486         block.removeItem(j--);
00487       }
00488         // Atom is not fixed
00489       else
00490       {
00491         assert (num < 0);
00492         block[j] = -(num + 1);
00493       }
00494     }
00495 
00496       // If an atom is fixed to true in the block,
00497       // then treat as evidence and set others to false
00498     if (fixedTrueAtoms > 0 || (*blockEvidence_)[i])
00499     {
00500       (*blockEvidence_)[i] = true;
00501       for (int j = 0; j < block.size(); j++)
00502       {
00503         atom[block[j] + 1] = false;
00504       }
00505     }    
00506       // If block has been emptied, then remove it
00507     else if (block.size() == 0)
00508     {
00509       blocks_->removeItem(i);
00510       blockEvidence_->removeItem(i);
00511       i--;
00512     }
00513       // Otherwise block with one true and others false
00514     else
00515     {
00516       int chosen = random() % block.size();
00517       atom[block[chosen] + 1] = true;
00518       for (int j = 0; j < block.size(); j++)
00519       {
00520         if (j != chosen)
00521         {
00522           atom[block[j] + 1] = false;
00523         }
00524       }
00525     }
00526   }
00527 
00528   for (i = 0; i < nc; i++)
00529   {
00530     if (!isSat[i])
00531     {
00532           int idx = 0;
00533           int k = 0;
00534           while (clause[i][k] != 0)
00535           {
00536                 lit = clause[i][k++];
00537                 int var = (lit > 0) ? lit: -lit;
00538                         
00539                 assert(fixedatom[var] != (lit > 0));
00540           // if fixed but unsat, must be false, ignore
00541                 if (fixedatom[var] >= 0) continue;
00542           // fixedatom[var] is negative
00543                 int newlit = (lit < 0) ? fixedatom[var] : -fixedatom[var];      // mapped lit
00544                 assert(numclause <= i && idx < k);
00545                 clause[numclause][idx++] = newlit;
00546                 numliterals++;
00547                 occurence[newlit + MAXATOM][numoccurence[newlit + MAXATOM]++] = numclause;
00548           }
00549                 //assert(idx>0);
00550           if (idx == 0)
00551           {
00552                 cout << "Inconsistent fixed assignment!" << endl;
00553                 return false;
00554           }
00555           size[numclause] = idx;
00556           numclause++;
00557         }
00558   }
00559   return true;
00560 }
00561 
00562 void SampleSat::initRandom()
00563 {
00564   int i;
00565   int j;
00566   int thetruelit = -1;
00567   int truelit1;
00568   int truelit2;
00569 
00570   for(i = 0; i < numclause; i++) numtruelit[i] = 0;
00571   numfalse = 0;
00572 
00573   for(i = 1; i < numatom + 1; i++)
00574   {
00575     changed[i] = -BIG;
00576         breakcount[i] = 0;
00577         makecount[i] = 0;
00578   }
00579 
00580         // UP: Unit propagation
00581         //for(i = 1;i < numatom+1;i++) atom[i] = (fixedatom[i]!=-1) ? fixedatom[i] : (random()%2);
00582 
00583         // BB: the backbone is removed
00584     // For each block: select one to set to true
00585   for (int i = 0; i < blocks_->size(); i++)
00586   {
00587     Array<int> block = (*blocks_)[i];
00588       // If evidence atom exists, then all others are false
00589     if ((*blockEvidence_)[i])
00590     {
00591         // If 1st argument is -1, then all are set to false
00592       setOthersInBlockToFalse(-1, i);
00593       continue;
00594     }
00595     
00596     int chosen = random() % block.size();
00597     atom[block[chosen] + 1] = true;
00598     setOthersInBlockToFalse(chosen, i);
00599   }
00600       
00601     // Random tv for all not in blocks
00602   for (int i = 1; i <= numatom; i++)
00603   {
00604     if (getBlock(i - 1) >= 0) continue;
00605     else atom[i] = (random() < RAND_MAX/2) ? 1 : 0;
00606   }
00607 
00608         // Initialize breakcount and makecount in the following:
00609   for(i = 0; i < numclause; i++)
00610   {
00611     truelit1 = 0;
00612     truelit2 = 0;
00613         for(j = 0; j < size[i]; j++)
00614         {
00615           if((clause[i][j] > 0) == atom[abs(clause[i][j])])
00616           { // ij is true lit
00617                 numtruelit[i]++;
00618                 thetruelit = clause[i][j];
00619 
00620         if (!truelit1) truelit1 = clause[i][j];
00621         else if (truelit1 && !truelit2) truelit2 = clause[i][j];
00622           }
00623         }
00624         
00625     if(numtruelit[i] == 0)
00626         {
00627           wherefalse[i] = numfalse;
00628           wfalse[numfalse] = i;
00629           numfalse++;
00630           for(j = 0; j < size[i]; j++) makecount[abs(clause[i][j])]++;
00631         }
00632         else
00633     if (numtruelit[i] == 1)
00634         {
00635           breakcount[abs(thetruelit)]++;
00636       watch1[i] = abs(thetruelit);
00637         }
00638         else
00639         { /*if (numtruelit[i] == 2)*/
00640           watch1[i] = abs(truelit1);
00641           watch2[i] = abs(truelit2);
00642         }
00643   }
00644 
00645   if (hamming_flag)
00646   {
00647         hamming_distance = calc_hamming_dist(atom, hamming_target, numatom);
00648         fprintf(hamming_fp, "0 %i\n", hamming_distance);
00649   }
00650 }
00651 
00652 void SampleSat::initVars()
00653 {
00654   status_flag = 0; /* value returned from main procedure */
00655 
00656   target = 0;
00657   numtry = 0; /* total attempts at solutions */
00658   numsuccesstry = 0; /* total found solutions */
00659 
00660         // Hamming calcualations
00661   hamming_target_file[0] = 0;
00662   hamming_data_file[0] = 0;
00663   hamming_flag = false;
00664 }
00665 
00666 void SampleSat::print_parameters(int argc, char * argv[])
00667 {
00668   printf("cutoff = %li\n",cutoff);
00669   printf("tries = %i\n",numrun);
00670 
00671   printf("heuristic = ");
00672   switch(heuristic)
00673   {
00674         case TABU:
00675           printf("tabu %d", tabu_length);
00676           break;
00677         default:
00678           printf("%s", heuristic_names[heuristic]);
00679           break;
00680   }
00681   if (numerator > 0)
00682   {
00683         printf(", noise %d / %d", numerator, denominator);
00684   }
00685   if (wp_numerator > 0)
00686   {
00687         printf(", wp %d / %d", wp_numerator, wp_denominator);
00688   }
00689   printf("\n");
00690 }
00691 
00692 int SampleSat::picksa(void)
00693 {
00694   int change;
00695   int toflip;
00696 
00697   if (numfalse == 0 || (random() % 100 < saRatio && !latesa))
00698   {
00699         toflip = random()%numatom + 1;
00700 
00701     int blockIdx = getBlock(toflip - 1);
00702     if (blockIdx == -1)
00703       change = makecount[toflip] - breakcount[toflip];
00704     else // Atom is in a block
00705     {  
00706         // If evidence atom exists or in block of size 1, then can not flip
00707       if ((*blockEvidence_)[blockIdx] || (*blocks_)[blockIdx].size() == 1)
00708         return NOVALUE;
00709       change = calculateChange(toflip);
00710     }
00711     
00712         if (change >= 0)
00713           return toflip;
00714         else if (random() <= exp(change/(temperature/100.0)) * RAND_MAX)
00715           return toflip;
00716         else
00717     {
00718         // set back flipInBlock
00719       inBlock = false;
00720       flipInBlock = NOVALUE;
00721       return NOVALUE;
00722     }
00723   }
00724   else
00725   {
00726         //return picktabu();
00727     return pickbest();
00728   }
00729 }
00730 
00731 void SampleSat::update_and_print_statistics_end_try(void)
00732 {
00733   if(numfalse <= target)
00734   {
00735         status_flag = 0;
00736         save_solution();
00737         numsuccesstry++;
00738   }
00739 }
00740 

Generated on Tue Jan 16 05:30:03 2007 for Alchemy by  doxygen 1.5.1