hmaxwalksat.h

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, Hoifung Poon, and Daniel Lowd.
00006  * 
00007  * Copyright [2004-08] Stanley Kok, Parag Singla, Matthew
00008  * Richardson, Pedro Domingos, Marc Sumner, Hoifung
00009  * Poon, and Daniel Lowd. 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, Hoifung
00032  * Poon, and Daniel Lowd 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 #ifndef HMAXWALKSAT_H
00067 #define HMAXWALKSAT_H
00068 
00069 #include <cfloat>
00070 #include <unistd.h>
00071 #include <sys/time.h>
00072 #include <sys/resource.h>
00073 #include <cstring>
00074 #include <sstream>
00075 #include <fstream>
00076 #include "array.h"
00077 #include "timer.h"
00078 #include "util.h"
00079 #include "sat.h"
00080 #include "logichelper.h"
00081 #include "maxwalksatparams.h"
00082 
00083 
00084 const bool hmwsdebug = false;
00085 const bool wjhmwsdebug = false;
00086 #define BIGSTEP 100
00087 
00097 class HMaxWalkSat : public SAT
00098 {
00099 public:
00103         HMaxWalkSat(HVariableState* state, int seed, const bool& trackClauseTrueCnts,
00104                 MaxWalksatParams* params)
00105                 : SAT(state, seed, trackClauseTrueCnts)
00106         {
00107                 int numAtoms = hstate_->getNumAtoms();
00108                 saSteps_ = 0;
00109                 saInterval_ = 100;
00110                 //falseDisNum_ = 0;
00111                 // User-set parameters
00112                 maxSteps_ = params->maxSteps;
00113                 maxTries_ = params->maxTries;
00114                 targetCost_ = params->targetCost;
00115                 hard_ = params->hard;
00116                 numSolutions_ = params->numSolutions;
00117                 heuristic_ = params->heuristic;                                                                    
00118 
00119                 tabuLength_ = params->tabuLength;
00120                 lazyLowState_ = params->lazyLowState;
00121                 // For SampleSat
00122                 saRatio_ = params->ssParams->saRatio;
00123                 saTemp_ = params->ssParams->saTemp;
00124                 saTempInit_ = saTemp_;
00125                 lateSa_ = params->ssParams->lateSa;
00126 
00127                 // Info from SAT class
00128                 if (heuristic_ == TABU || heuristic_ == SS || heuristic_ == HMWS) {
00129                         changed_.growToSize(numAtoms + 1);
00130                 }
00131                 numFlips_ = 0;
00132 
00133                 // Info from HMaxWalkSat
00134                 numerator_ = 50; // User-set?
00135                 denominator_ = 100; // User-set?
00136                 // We assume we are not in a block
00137                 inBlock_ = false;
00138                 flipInBlock_ = NOVALUE;
00139                 // Initialize array of function pointers
00140                 int idx = 0;
00141                 pickcode[idx++] = &HMaxWalkSat::pickRandom;
00142                 pickcode[idx++] = &HMaxWalkSat::pickBest;
00143                 pickcode[idx++] = &HMaxWalkSat::pickHMCS;
00144                 pickcode[idx++] = &HMaxWalkSat::pickSS;
00145                 pickcode[idx++] = &HMaxWalkSat::pickHMWS;
00146                 pickcode[idx++] = &HMaxWalkSat::pickSA;
00147                 maxSeconds_ = -1;
00148         }
00149 
00153         ~HMaxWalkSat() { }
00154 
00155 
00156         void SetMaxSeconds(double maxSeconds)
00157         {
00158                 maxSeconds_ = maxSeconds;
00159         }
00160 
00161         void SetNoisePra(int numerator, int denominator)
00162         {
00163                 numerator_ = numerator;
00164                 denominator_ = denominator;
00165         }
00166 
00167         void SetSAInterval(int saInterval)
00168         {
00169                 saInterval_ = saInterval;
00170         }
00175         void init()
00176         {
00177                 if (heuristic_ == TABU || heuristic_ == SS || heuristic_ == HMWS)
00178                 {
00179                         int numAtoms = hstate_->getNumAtoms();
00180                         if (changed_.size() != numAtoms + 1)
00181                         {
00182                                 if (int(changed_.size()) < numAtoms + 1) {
00183                                         changed_.growToSize(numAtoms + 1);
00184                                 } else {
00185                                         changed_.shrinkToSize(numAtoms + 1);
00186                                 }
00187                         }
00188                         for(int i = 1; i <= numAtoms; ++i)
00189                                 changed_[i] = -(tabuLength_ + 1);
00190                 }
00191 
00192                 // Random initialize the variables 
00193                 hstate_->initRandom();          
00194                 //reinitialize the SATemp here
00195                 saTemp_ = saTempInit_;
00196         }
00197 
00198         double getTargetCost()
00199         {
00200                 return targetCost_;
00201         }
00202 
00203         void setSATempDownRatio(double saTempDownRatio)
00204         {
00205                 saTempDownRatio_ = saTempDownRatio;
00206         }
00207 
00208 
00212         void infer()
00213         {
00214                 int numtry = 0;
00215                 int numsuccesstry = 0;
00216                 Timer timer;
00217                 double startTimeSec = timer.time();
00218                 
00219                 double currentTimeSec, secondsElapsed;
00220                 // Whether the expected time is consumed by the inference.
00221                 bool timeUp = false;
00222                 double lowCost;
00223                 if (!hstate_->bMaxOnly_)
00224                 {
00225                         lowCost = BigValue;
00226                 } else {
00227                         lowCost = -BigValue;
00228                 }
00229 
00230                 int totaltrynum = 0;
00231                 // If keeping track of true clause groundings, then init to zero
00232                 if (trackClauseTrueCnts_)
00233                 {
00234                         for (int clauseno = 0; clauseno < clauseTrueCnts_->size(); clauseno++)
00235                                 (*clauseTrueCnts_)[clauseno] = 0;
00236                         for (int clauseno = 0; clauseno < clauseTrueCntsCont_->size(); clauseno++)
00237                                 (*clauseTrueCntsCont_)[clauseno] = 0;
00238                 }
00239 
00240                 int numhardfalse = 0;
00241                 if (hstate_->bMaxOnly_)
00242                 {
00243                         for(int i = 0; i < hstate_->getNumFalseClauses(); i++)
00244                         {
00245                                 GroundClause* clause = (*(hstate_->gndClauses_))[hstate_->falseClause_[i]];
00246                                 if (clause->isHardClause())
00247                                 {
00248                                         numhardfalse++;
00249                                 }
00250                         }
00251                         cout << "before HMWS, false dis clause#: " << hstate_->getNumFalseClauses() << " false hard clause#: " << numhardfalse<< endl;
00252                 }
00253 
00254                 // Perform up to maxTries tries or numSolutions successful tries
00255                 while (numsuccesstry < numSolutions_ && numtry < maxTries_ && !timeUp) //default 1*10
00256                 {
00257                         numtry++;
00258                         numFlips_ = 0;
00259                         bool lowStateInThisTry = false;
00260 
00261                         // Make random assignment in subsequent tries
00262                         // (for first try, init() should have been called)
00263                         if (numtry > 1 && numsuccesstry == 0)
00264                         {
00265                                 init();
00266                                 startTimeSec = timer.time();
00267                         }
00268 
00269                         while (((numFlips_ < maxSteps_ && maxSeconds_ < 0) || (maxSeconds_ > 0)) 
00270                                    && numsuccesstry < numSolutions_)
00271                         {        
00272                                 currentTimeSec = timer.time();
00273                                 secondsElapsed = currentTimeSec - startTimeSec;
00274                                 if (maxSeconds_ > 0 && secondsElapsed > maxSeconds_) {
00275                                         cout << "Time is up for current HMaxWalkSAT try. "      << endl;
00276                                         timeUp = true;
00277                                         break;
00278                                 }
00279                                 numFlips_++;
00280                                 int atomIdx = (this->*(pickcode[heuristic_]))();
00281 
00282                                 if (wjhmwsdebug)
00283                                 {
00284                                         cout << "HMWS picked atom: " << atomIdx << "." << endl;
00285                                 }
00286                                 
00287                                 //we need to decide whether to record the continuous sample here.
00288                                 if (atomIdx < 0) // Continuous variables
00289                                 {
00290                                         atomIdx = -atomIdx;
00291                                         if (!hstate_->bMaxOnly_)  // HMCSAT
00292                                         {
00293                                                 if (pickedContValue_ == UNSOLVABLE) {
00294                                                         continue;
00295                                                 }
00296                                                 hstate_->UpdateHybridClauseInfoByContAtom(atomIdx, pickedContValue_);
00297                                         }  // For HMCS ends
00298                                         else  // HMWS
00299                                         {
00300                                                 if (pickedContValue_ == UNSOLVABLE) {
00301                                                         continue;
00302                                                 }
00303                                                 hstate_->UpdateHybridClauseWeightSumByContAtom(atomIdx, pickedContValue_);
00304                                         }  // For HMWS ends
00305                                 }  // Continuous variable ends
00306                                 else if (atomIdx >0 && atomIdx != NOVALUE)  // Discrete variables
00307                                 {
00308                                         if (!hstate_->bMaxOnly_)  // HMCS
00309                                         {
00310                                                 if (wjhmwsdebug)
00311                                                 {
00312                                                         cout << "flipping dis atom: " << atomIdx << " before flip:"; hstate_->printDisAtom(atomIdx, cout); cout << endl;
00313                                                 }
00314 
00315                                                 flipAtom(atomIdx);
00316                                                 if (wjhmwsdebug)
00317                                                 {
00318                                                         cout << "after flip in dis: ";hstate_->printDisAtom(atomIdx, cout); cout<< endl;
00319                                                 }
00320 
00321                                                 bool atomValue = hstate_->getValueOfAtom(atomIdx);
00322                                                 hstate_->UpdateHybridClauseInfoByDisAtom(atomIdx, atomValue);
00323                                                 if (wjhmwsdebug)
00324                                                 {
00325                                                         cout << "after flip in cont: ";hstate_->printDisAtom(atomIdx, cout); cout<< endl;
00326                                                 }
00327                                         }  // For HMCS ends
00328                                         else  // HMWS
00329                                         {       
00330                                                 flipAtom(atomIdx);
00331                                                 bool atomValue = hstate_->getValueOfAtom(atomIdx);
00332                                                 hstate_->UpdateHybridClauseWeightSumByDisAtom(atomIdx, atomValue);
00333                                         }  // For HMWS ends
00334                                 }  // Discrete variable ends
00335                                 /*else {
00336                                         continue;
00337                                 }*/
00338 
00339                                 double discost = 0, hybridcost = 0;
00340                                 long double costOfFalseConstraints = 0;
00341                                 if (!hstate_->bMaxOnly_)  // For HMCS
00342                                 {
00343                                         costOfFalseConstraints = hstate_->getCostOfTotalFalseConstraints();
00344                                 }
00345                                 else  // For HMWS
00346                                 {
00347                                         costOfFalseConstraints =  hstate_->getCostOfAllClauses(discost, hybridcost);
00348                                 }
00349 
00350                                 //long double lowCost = hstate_->getLowCost();
00351                                 // If the cost of false clauses is lower than the low cost of all
00352                                 // tries, then save this as the low state.
00353                                 if(!hstate_->bMaxOnly_)  // HMCS
00354                                 {
00355                                         if (costOfFalseConstraints <= lowCost) // <= saves the last satisfying assignment
00356                                         {
00357                                                 if (hmwsdebug)
00358                                                 {
00359                                                         cout << "Cost of false clauses: " << costOfFalseConstraints
00360                                                                 << " less than lowest cost: " << lowCost << endl;
00361                                                 }
00362                                                 lowCost = costOfFalseConstraints;
00363                                                 hstate_->saveLowStateAll();
00364                                         }
00365 
00366                                         // If successful try
00367                                         // Add SMALLVALUE to targetCost_ because of double precision error
00368                                         // This needs to be fixed
00369                                         if (costOfFalseConstraints <= targetCost_ + SMALLVALUE)
00370                                                 numsuccesstry++; 
00371                                 }
00372                                 else
00373                                 {
00374                                         if (costOfFalseConstraints >= lowCost) // <= saves the last satisfying assignment
00375                                         {
00376                                                 lowCost = costOfFalseConstraints;
00377                                                 hstate_->saveLowStateAll();
00378                                         }
00379                                 }                                       
00380                         }  // End inner while.
00381 
00382                         if (!hstate_->bMaxOnly_)  // HMCS
00383                         {
00384                                 totaltrynum += numFlips_;
00385                                 if (lowStateInThisTry)
00386                                         reconstructLowState();
00387                                 hstate_->saveLowStateToDB(); // only for discrete
00388                                 if (hmwsdebug)
00389                                 {
00390                                         cout<< "In the end of try " << numtry << ": " << endl;
00391                                         cout<< "Lowest num. of false constraints: " << hstate_->getLowBadAll() << endl;
00392                                         cout<< "Lowest cost of false constraints: " << hstate_->getLowCostAll() << endl;
00393                                         cout<< "Number of flips: " << numFlips_ << endl;
00394                                 }
00395                         }                               
00396                 }  // End outter while
00397                 
00398                 if (!hstate_->bMaxOnly_)  // HMCS
00399                 {
00400                         if (hmwsdebug)
00401                         {
00402                                 cout << "Total flips num: " << totaltrynum << ". Succeed:" << numsuccesstry << " times." << endl;
00403                         }
00404                         
00405                         if (numsuccesstry == 0) //no satisfying assignment found, should reset last time's assignmetn here to low state 
00406                         {
00407                                 //print out false clauses & constraints
00408                                 hstate_->saveLastAsCurrentAssignment();
00409                                 hstate_->updateCost();
00410                                 hstate_->saveLowStateAll();
00411                         }
00412 
00413                         hstate_->saveLowToCurrentAll();
00414                         // If keeping track of true clause groundings
00415                         if (trackClauseTrueCnts_)
00416                         {
00417                                 hstate_->updateNumTrueLits();
00418                                 hstate_->getNumClauseGndings(clauseTrueCnts_, true);   
00419                                 hstate_->getContClauseGndings(clauseTrueCntsCont_);
00420                         }
00421                 }  // HMCS ends.
00422                 else  // HMWS
00423                 {
00424                         cout << "finish hybrid MaxWalkSAT." << endl;
00425                         cout << "Lowest state cost:" << lowCost << endl; //                     
00426                         numhardfalse = 0;
00427                         for(int i = 0; i < hstate_->getNumFalseClauses(); i++)
00428                         {
00429                                 GroundClause* clause = (*(hstate_->gndClauses_))[hstate_->falseClause_[i]];
00430                                 if (clause->isHardClause())
00431                                 {
00432                                         numhardfalse++;
00433                                 }
00434                         }                       
00435                         cout << "after HMWS, false dis clause#: " << hstate_->getNumFalseClauses() << " false hard clause#: " << numhardfalse<< endl;
00436                         hstate_->saveLowToCurrentAll();
00437                         if (trackClauseTrueCnts_)
00438                         {
00439                                 hstate_->updateNumTrueLits();
00440                                 hstate_->getNumClauseGndings(clauseTrueCnts_, true);
00441                                 hstate_->getContClauseGndings(clauseTrueCntsCont_);
00442                         }
00443                 }
00444         }
00445 
00446         const int getHeuristic()
00447         {
00448                 return heuristic_;
00449         }
00450 
00451         void setHeuristic(const int& heuristic)
00452         {
00453                 heuristic_ = heuristic;
00454         }
00455         
00456         virtual const Array<double>* getClauseTrueCnts() 
00457         { 
00458                 //assert(clauseTrueCnts_->size());
00459                 if (!trackClauseTrueCnts_)
00460                 {
00461                         hstate_->updateNumTrueLits();
00462                         hstate_->getNumClauseGndings(clauseTrueCnts_, true);
00463                 }               
00464                 return clauseTrueCnts_; 
00465         }
00466 
00467         virtual const Array<double>* getClauseTrueCntsCont() 
00468         { 
00469                 if (!trackClauseTrueCnts_)
00470                 {
00471                         hstate_->getContClauseGndings(clauseTrueCntsCont_);
00472                 }
00473                 return clauseTrueCntsCont_; 
00474         }
00475 
00479 
00480         //math:
00481         // k = (y2 - y1) / (x2 - x1);
00482         // b = y1 - (y2 - y1)*x1 / (x2 - x1);
00483         // dist = (k*x - y + b) / (sqrt(1+k^2));
00484         // logsigmoid
00485         // for the inequality/DoubleRange constraints of depth property, 
00486         // we assume we know which side the segments should belong to, 
00487         // and we use the absolute depth values in our constraints for tooshallow and too deep
00488         
00489         //collapsely solving the depth constraints
00490         double collapseDepthConstraint(double th)
00491         {
00492                 return 0;
00493         }
00494 
00495 protected:
00496 
00503         void flipAtom (int toFlip)
00504         {
00505                 //if (hmwsdebug) cout << "Entering HMaxWalkSat::flipAtom" << endl;
00506                 if (toFlip == NOVALUE)
00507                         return;
00508 
00509                 // Flip the atom in the state
00510                 hstate_->flipAtom(toFlip, -1);
00511                 // Mark this flip as last time atom was changed if tabu is used
00512                 if (heuristic_ == TABU || heuristic_ == SS || heuristic_ == HMWS)
00513                 {
00514                         changed_[toFlip] = numFlips_;
00515                         changed_.growToSize(hstate_->getNumAtoms() + 1, -(tabuLength_ + 1));
00516                 }
00517 
00518                 if (lazyLowState_)
00519                 {
00520                         // Mark this variable as flipped since last low state. If already
00521                         // present, then it has been flipped back to its value in the low
00522                         // state and we can remove it.
00523                         if (varsFlippedSinceLowState_.find(toFlip) !=
00524                                 varsFlippedSinceLowState_.end())
00525                         {
00526                                 varsFlippedSinceLowState_.erase(toFlip);
00527                         }
00528                         else
00529                         {
00530                                 varsFlippedSinceLowState_.insert(toFlip);
00531                         }
00532                 }
00533       if (hmwsdebug) cout << "Leaving HMaxWalkSat::flipAtom" << endl;
00534         }
00535 
00542         int pickRandom()
00543         {
00544                 return 0;
00545         }
00546 
00553         int pickBest()
00554         {
00555                 return 0;
00556         }
00557 
00563         int pickHMCS()
00564         {
00565                 if (wjhmwsdebug)
00566                 {
00567                         cout << "HMCS" << endl;
00568                 }
00569 
00570                 assert(!inBlock_);
00571                 // Clause to fix picked at random
00572                 // need to be changed to deal with hybrid case
00573                 bool noisyPick = (numerator_ > 0 && random() % denominator_ < numerator_); 
00574                 // Pick a clause.
00575                 // For H-MCSAT, the picked clause is either a false discrete clause, or a hybrid one not satisfying the inequality constraint.
00576                 // For HMWS, the picked clause is either a false discrete clause or a hybrid one.
00577                 int toFix = hstate_->getRandomFalseClauseIndexHMCS();  // HMCS version.
00578                 if (toFix ==     NOVALUE) // No false clause.
00579                 {
00580                         return NOVALUE;
00581                 }
00582                 else if (toFix > 0) //discrete clause, clause idx = toFix - 1;
00583                 {
00584                         toFix --;
00585                         if (wjhmwsdebug)
00586                         {
00587                                 cout << "Pick false dis clause: " << toFix << ", "; hstate_->printDisClause(toFix, cout); cout << "Cost: " << hstate_->clauseCost_[toFix] << endl;
00588                         }
00589                         long double improvement;
00590                         int clauseSize = hstate_->getClauseSize(toFix);
00591                         long double cost = hstate_->getClauseCost(toFix);
00592                         // Holds the best atoms so far
00593                         Array<int> best;
00594                         // How many are tied for best
00595                         register int numbest = 0;
00596                         // Best value so far
00597                         long double bestvalue = -LDBL_MAX;
00598                         // With prob. do a noisy pick, prob = denominator / numerator.
00599                         // if random move, exclude illegitimate ones and place others in a lottery
00600                         if (noisyPick)
00601                         {
00602                                 for (int i = 0; i < clauseSize; ++i)
00603                                 {       
00604                                         register int lit = hstate_->getAtomInClause(i, toFix);
00605                                         // Neg. clause: Only look at true literals
00606                                         if (cost < 0 && !hstate_->isTrueLiteral(lit)) continue;
00607                                         best.append(abs(lit));
00608                                         numbest++;
00609                                 }
00610                         }  // Noisy pick ends.
00611                         else  // Greedy: pick the best value
00612                         {
00613                                 for (int i = 0; i < clauseSize; ++i)
00614                                 {
00615                                         register int lit = hstate_->getAtomInClause(i, toFix);
00616                                         // Neg. clause: Only look at true literals
00617                                         if (cost < 0 && !hstate_->isTrueLiteral(lit)) continue;
00618                                         // var is the index of the atom
00619                                         register int var = abs(lit);
00620                                         improvement = calculateImprovementDisHMCS(var);
00621                                         if (mwsdebug) {
00622                                                 cout << "Improvement of var " << var << " is: " << improvement << endl;
00623                                         }
00624 
00625                                         // TABU: If pos. improvement, then always add it to best
00626                                         if (improvement > 0 && improvement >= bestvalue)
00627                                         { // Tied or better than previous best
00628                                                 if (improvement > bestvalue)
00629                                                 {
00630                                                         numbest = 0;
00631                                                         best.clear();
00632                                                 }
00633                                                 bestvalue = improvement;
00634                                                 best.append(var);
00635                                                 numbest++;
00636                                         } else if (improvement > -LDBL_MAX && tabuLength_ < numFlips_ - changed_[var]) {
00637                                                 if (improvement >= bestvalue)
00638                                                 { // Tied or better than previous best
00639                                                         if (improvement > bestvalue)
00640                                                         {
00641                                                                 numbest = 0;
00642                                                                 best.clear();
00643                                                         }
00644                                                         bestvalue = improvement;
00645                                                         best.append(var);
00646                                                         numbest++;
00647                                                 }
00648                                         }
00649                                 }
00650                         }
00651 
00652                         if (numbest == 0) 
00653                         {
00654                                 if (wjhmwsdebug) cout << "Leaving MaxWalkSat::pickHMCS (NOVALUE)" << endl;
00655                                 return NOVALUE;
00656                         }
00657                         int toFlip = NOVALUE;
00658                         // Exactly one best atom
00659                         if (numbest == 1) {
00660                                 toFlip = best[0];
00661                         } else {
00662                                 // Choose one of the best at random
00663                                 toFlip = best[random()% best.size()];
00664                         }
00665 
00666                         if (wjhmwsdebug) 
00667                         {
00668                                 cout << "Improvement:" << bestvalue << endl;
00669                         }
00670                         return toFlip;
00671                 }  // Discrete clause
00672                 else  // Hybrid clause, clause idx = - (toFix + 1); toFix < 0
00673                 {
00674                         toFix++;
00675                         int contClauseIdx = -toFix;
00676                         // If the weight of the hybrid constraint is 0, then we skip the current pick.
00677                         if (hstate_->hybridWts_[contClauseIdx] == 0) return NOVALUE;
00678 
00679                         if (wjhmwsdebug) {
00680                                 cout << "Pick false hybrid clause: " << contClauseIdx << ", constraint:"; hstate_->printHybridConstraint(contClauseIdx, cout);
00681                         }
00682                         int contVarNum = hstate_->hybridContClause_[contClauseIdx].size();
00683                         int disVarNum = hstate_->hybridDisClause_[contClauseIdx].size();
00684                         int totalVarNum = contVarNum + disVarNum;
00685                         if (noisyPick)  // Random pick and then flip, p = numerator_/denominator_;
00686                         {
00687                                 set<int> pickedContVars;
00688                                 int inIdx = random() % totalVarNum;
00689                                 if (inIdx < contVarNum)  // Continuous variable
00690                                 {
00691                                         int contAtomIdx = hstate_->hybridContClause_[contClauseIdx][inIdx];
00692                                         // Solve the constraint in regarding with the chosen continuous variable.
00693                                         // Then compute the improvement in term of #false clause reduction.
00694                                         pickedContValue_ = hstate_->SolveHybridConstraintToContVarSample(contClauseIdx, inIdx);
00695                                         if (pickedContValue_ == FLIPDIS) {
00696                                                 // Generate a random solution to the discrete part of the hybrid clause, so that making it true.
00697                                                 Array<bool> solution;
00698                                                 GetClauseRandomSolution(hstate_->hybridDisClause_[contClauseIdx].size(), true, hstate_->hybridConjunctionDisjunction_[contClauseIdx], &solution);
00699                                                 // Update each discrete variable.
00700                                                 for (int i = 0; i < solution.size(); ++i) {
00701                                                         int atomIdx = hstate_->hybridDisClause_[contClauseIdx][i];
00702                                                         if (solution[i] != hstate_->getValueOfAtom(atomIdx)) {
00703                                                                 flipAtom(atomIdx);
00704                                                                 bool atomValue = hstate_->getValueOfAtom(atomIdx);
00705                                                                 hstate_->UpdateHybridClauseInfoByDisAtom(atomIdx, atomValue);
00706                                                         }
00707                                                 }
00708                                                 // Then check if the continuous part's value satisfies the constraint or not.
00709                                                 double cont_part_value = hstate_->HybridClauseContPartValue(contClauseIdx);
00710                                                 if (cont_part_value < hstate_->hybridConstraints_[contClauseIdx].vThreshold_)                                           {
00711                                                         // If not, solve the continuous part for the given variable, set both solutions and update status.
00712                                                         double cont_var_value = hstate_->SolveConstraintAndRandomSample(contClauseIdx, inIdx);
00713                                                         if (cont_var_value == UNSOLVABLE)
00714                                                                 return NOVALUE;
00715                                                         else {
00716                                                                 // Update by the continuous variable.
00717                                                                 hstate_->UpdateHybridClauseInfoByContAtom(contAtomIdx, cont_var_value);
00718                                                         }
00719                                                 }
00720         
00721                                                 // Return the status that no action needs to be performed.
00722                                                 return NOVALUE;
00723                                         }  // FLIP_DIS ends
00724 
00725                                         return -contAtomIdx;
00726                                 }
00727                                 else  // discrete variable
00728                                 {
00729                                         // Check if flipping this discrete variable could satisfy this constraint.
00730                                         // If so, return it, if not, do nothing.
00731                                         int atomIdx = abs(hstate_->hybridDisClause_[contClauseIdx][inIdx - contVarNum]);
00732                                         hstate_->atom_[atomIdx] = !hstate_->atom_[atomIdx];
00733                                         double hybrid_clause_val = hstate_->HybridClauseValue(contClauseIdx);
00734                                         hstate_->atom_[atomIdx] = !hstate_->atom_[atomIdx];
00735                                         if (hstate_->isSatisfied(hstate_->hybridConstraints_[contClauseIdx], hybrid_clause_val)) {
00736                                                 return atomIdx;
00737                                         } else {
00738                                                 return NOVALUE;
00739                                         }
00740                                 }
00741                         }  // Noisy pick
00742                         else //greedy try to flip every variable and find the one get biggest improvement
00743                         {
00744                                 long double bestvalue = -LDBL_MAX;
00745                                 Array<int> best;
00746                                 int numbest = 0;
00747                                 map<int, double> pickedContValues;
00748                                 for (int i = 0; i < contVarNum; ++i) {
00749                                         int contAtomIdx = hstate_->hybridContClause_[contClauseIdx][i];
00750                                         // Solve the constraint in regarding with the chosen continuous variable.
00751                                         // Then compute the improvement in term of #false clause reduction.
00752                                         double cont_var_val = 0;
00753                                         double improvement =
00754                                                         hstate_->GetImprovementBySolvingHybridConstraintToContVar(contClauseIdx, i, cont_var_val);
00755                                         // Tied or better than previous best
00756                                         if (improvement != CANNOTSATCURRENT && improvement >= bestvalue) {
00757                                                 if (improvement > bestvalue) {
00758                                                         numbest = 0;
00759                                                         best.clear();
00760                                                 }
00761                                                 bestvalue = improvement;
00762                                                 best.append(-contAtomIdx);
00763                                                 numbest++;
00764                                                 pickedContValues[-contAtomIdx] = cont_var_val;
00765                                         }
00766                                 }
00767 
00768                                 for (int i = 0; i < disVarNum; ++i) {
00769                                         int disAtomIdx = hstate_->hybridDisClause_[contClauseIdx][i];
00770                                         double improvement = calculateImprovementDisHMCS(disAtomIdx);
00771 
00772                                         if (improvement >= bestvalue)
00773                                         { // Tied or better than previous best
00774                                                 if (improvement > bestvalue)
00775                                                 {
00776                                                         numbest = 0;
00777                                                         best.clear();
00778                                                 }
00779                                                 bestvalue = improvement;
00780                                                 best.append(disAtomIdx);
00781                                                 numbest++;
00782                                         }
00783                                 }
00784 
00785                                 int atomIdx = NOVALUE;
00786                                 // Exactly one best atom
00787                                 if (numbest == 1)
00788                                         atomIdx = best[0];
00789                                 else
00790                                         // Choose one of the best at random
00791                                         atomIdx = best[random()%numbest];
00792 
00793                                 if (atomIdx < 0)  // Picked variable is a continuous variable.
00794                                 {
00795                                         pickedContValue_ = pickedContValues[atomIdx];
00796                                 }
00797                                 return atomIdx;
00798                         }  // Greedy
00799                 }  // Hybrid clause.
00800                 return NOVALUE;
00801         }
00802 
00803         void checkAr(const Array<int>& ar)
00804         {
00805                 int v = ar[0];
00806                 for(int i = 0;i < ar.size(); i++)
00807                 {
00808                         if(ar[i] != v)
00809                         {
00810                                 cout << v << "\t" << ar[i] << ". Error!!!!!" <<endl;
00811                                 break;
00812                         }
00813                 }
00814         }
00815         
00816         struct FlipDisVarIdxCont
00817         {
00818                 Array<int> disIdx_;
00819         };
00820 
00821         int pickHMWS()
00822         {
00823                 if (wjhmwsdebug)
00824                 {
00825                         cout << "HMWSSTEP" << endl;
00826                 }
00827 
00828                 assert(!inBlock_);
00829                 // Clause to fix picked at random    
00830                 //need to be changed to deal with hybrid case
00831                 bool noisyPick = (numerator_ > 0 && random()%denominator_ < numerator_); 
00832 
00833                 // Pick a clause.
00834                 // For H-MCSAT, the picked clause is either a false discrete clause, or a hybrid one not satisfying the inequality constraint.
00835                 // For HMWS, the picked clause is either a false discrete clause or a hybrid one.
00836                 int toFix = hstate_->getRandomFalseClauseIndexHMWS();  // HMCS version.
00837 
00838                 if (toFix == NOVALUE) // no false clause
00839                 {
00840                         return NOVALUE;
00841                 } else if (toFix > 0) {  // Discrete clause, clause idx = toFix - 1;
00842                         toFix--;
00843                         if (wjhmwsdebug)
00844                         {
00845                                 cout << "Pick false dis clause: " << toFix << ", "; hstate_->printDisClause(toFix, cout);
00846                         }
00847                         long double improvement;
00848                         int clauseSize = hstate_->getClauseSize(toFix);
00849                         long double cost = hstate_->getClauseCost(toFix);
00850                         // Holds the best atoms so far
00851                         Array<int> best;
00852                         // How many are tied for best
00853                         register int numbest = 0;
00854                         // Best value so far
00855                         long double bestvalue = -LDBL_MAX;
00856                         // With prob. do a noisy pick, prob = denominator / numerator.
00857                         // if random move, exclude illegitimate ones and place others in a lottery
00858                         if (noisyPick)
00859                         {
00860                                 for (int i = 0; i < clauseSize; i++)
00861                                 {       
00862                                         register int lit = hstate_->getAtomInClause(i, toFix);
00863                                         // Neg. clause: Only look at true literals
00864                                         if (cost < 0 && !hstate_->isTrueLiteral(lit)) continue;
00865                                         best.append(abs(lit));
00866                                         numbest++;
00867                                 }
00868                         }
00869                         // greedy: pick the best value
00870                         else {
00871                                 for (int i = 0; i < clauseSize; i++)
00872                                 {
00873                                         register int lit = hstate_->getAtomInClause(i, toFix);
00874                                         // Neg. clause: Only look at true literals
00875                                         if (cost < 0 && !hstate_->isTrueLiteral(lit)) continue;
00876                                         // var is the index of the atom
00877                                         register int var = abs(lit);
00878                                         improvement = calculateImprovementDisHMWS(var);
00879                                         if (mwsdebug) {
00880                                                 cout << "Improvement of var " << var << " is: " << improvement << endl;
00881                                         }
00882 
00883                                         // TABU: If pos. improvement, then always add it to best
00884                                         if (improvement > 0 && improvement >= bestvalue)
00885                                         { // Tied or better than previous best
00886                                                 if (improvement > bestvalue)
00887                                                 {
00888                                                         numbest = 0;
00889                                                         best.clear();
00890                                                 }
00891                                                 bestvalue = improvement;
00892                                                 best.append(var);
00893                                                 numbest++;
00894                                         } else if (improvement > -LDBL_MAX && tabuLength_ < numFlips_ - changed_[var]) {
00895                                                 if (improvement >= bestvalue)
00896                                                 { // Tied or better than previous best
00897                                                         if (improvement > bestvalue)
00898                                                         {
00899                                                                 numbest = 0;
00900                                                                 best.clear();
00901                                                         }
00902                                                         bestvalue = improvement;
00903                                                         best.append(var);
00904                                                         numbest++;
00905                                                 }
00906                                         }
00907                                 }
00908                         }
00909 
00910                         if (numbest == 0)
00911                         {
00912                                 if (wjhmwsdebug) cout << "Leaving HMaxWalkSat::pickHMWS (NOVALUE)" << endl;
00913                                 return NOVALUE;
00914                         }
00915 
00916                         int toFlip = NOVALUE;
00917                         // Exactly one best atom
00918                         if (numbest == 1)
00919                                 toFlip = best[0];
00920                         else
00921                                 // Choose one of the best at random
00922                                 toFlip = best[random()%numbest];
00923 
00924                         if (wjhmwsdebug) 
00925                         {
00926                                 cout << "Picked dis atom to flip: " << toFlip << ",";hstate_->printDisAtom(toFlip, cout);
00927                                 cout << ". Improvement:" <<bestvalue <<endl;
00928                         }
00929 
00930                         return toFlip;
00931                 }  // Discrete clause
00932                 else  // Hybrid clause, clause idx = - (toFix + 1); toFix < 0
00933                 {
00934                         toFix++;
00935                         int contClauseIdx = -toFix;
00936                         if (hstate_->hybridWts_[contClauseIdx] == 0) return NOVALUE;
00937                         if (wjhmwsdebug) {
00938                                 cout << "Pick hybrid clause: " << contClauseIdx << ", constraint:";
00939                                 hstate_->printHybridConstraint(contClauseIdx, cout);
00940                         }
00941                         
00942                         int contVarNum =  hstate_->hybridContClause_[contClauseIdx].size();
00943                         int disVarNum = hstate_->hybridDisClause_[contClauseIdx].size();
00944                         int totalVarNum = contVarNum + disVarNum;
00945                         if (noisyPick) //random pick and then flip, p = numerator_/denominator_;
00946                         {
00947                                 set<int> pickedContVars;
00948                                 int inIdx = random() % totalVarNum;
00949                                 if (inIdx < contVarNum)  // continuous variable
00950                                 {
00951                                         int contAtomIdx = hstate_->hybridContClause_[contClauseIdx][inIdx];
00952                                         // 1. If the discrete part of this hybrid constraint is 0, then do nth.
00953                                         // 2. If the discrete part of this hybrid constraint is 1, then return the continuous variable (Optimize this hybrid constraint along this variable direction w./ L-BFGS).
00954                                         if (hstate_->HybridClauseDisPartValue(contClauseIdx)) {
00955                                                 // TODO: optimize the constraint along this variable to its optimal state.
00956                                                 // We need to compute the assignment to the continuous variable corresponding to the optimal state.
00957                                                 pickedContValue_ = hstate_->OptimizeHybridClauseToContVar(contClauseIdx, inIdx);
00958                                                 return -contAtomIdx;
00959                                         }
00960                                         else return NOVALUE;
00961                                 }
00962                                 else  // discrete variable
00963                                 {
00964                                         // Check if flipping this discrete variable could improve the current hybrid clause's weighted contribution;
00965                                         // If so, return it, if not, do nothing.
00966                                         int disAtomIdx = abs(hstate_->hybridDisClause_[contClauseIdx][inIdx - contVarNum]);                                     
00967                                         double hybridClauseValueBeforeFlipping = hstate_->HybridClauseValue(contClauseIdx);
00968                                         hstate_->atom_[disAtomIdx] = !hstate_->atom_[disAtomIdx];
00969                                         double hybridClauseValueAfterFlipping = hstate_->HybridClauseValue(contClauseIdx);
00970                                         hstate_->atom_[disAtomIdx] = !hstate_->atom_[disAtomIdx];
00971                                         if (hybridClauseValueAfterFlipping - hybridClauseValueBeforeFlipping >= 0) return disAtomIdx;
00972                                         else return NOVALUE;
00973                                 }
00974                         }  // Noisy pick
00975                         else //greedy try to flip every variable and find the one get biggest improvement
00976                         {
00977                                 long double bestvalue = -LDBL_MAX;
00978                                 Array<int> best;
00979                                 int numbest = 0;
00980                                 map<int, double> pickedContValues;
00981 
00982                                 for (int i = 0; i < contVarNum; ++i)
00983                                 {
00984                                         int contAtomIdx = hstate_->hybridContClause_[contClauseIdx][i];
00985                                         double assign = 0;
00986                                         // compute the improvement by optimizing the contribution of contAtomIdx.
00987                                         double improvement = hstate_->ReduceClauseAndOptimize(contAtomIdx, &assign);
00988                                         if (improvement == NOVALUE) continue;
00989                                         if (improvement >= bestvalue)
00990                                         { // Tied or better than previous best
00991                                                 if (improvement > bestvalue)
00992                                                 {
00993                                                         numbest = 0;
00994                                                         best.clear();
00995                                                 }
00996                                                 bestvalue = improvement;
00997                                                 best.append(-contAtomIdx);
00998                                                 numbest++;
00999                                                 pickedContValues.insert(map<int, double>::value_type(-contAtomIdx, assign));
01000                                         }
01001                                 }
01002                                 for (int i = 0; i < disVarNum; ++i) {
01003                                         int disAtomIdx = hstate_->hybridDisClause_[contClauseIdx][i];
01004                                         double improvement = calculateImprovementDisHMWS(disAtomIdx);
01005                                         if (improvement >= bestvalue)
01006                                         { // Tied or better than previous best
01007                                                 if (improvement > bestvalue)
01008                                                 {
01009                                                         numbest = 0;
01010                                                         best.clear();
01011                                                 }
01012                                                 bestvalue = improvement;
01013                                                 best.append(disAtomIdx);
01014                                                 numbest++;
01015                                         }
01016                                 }
01017 
01018                                 int atomIdx = NOVALUE;
01019                                 // Exactly one best atom
01020                                 if (numbest == 1)
01021                                         atomIdx = best[0];
01022                                 else
01023                                         // Choose one of the best at random
01024                                         atomIdx = best[random()%numbest];
01025 
01026                                 if (atomIdx < 0)  // Picked variable is a continuous variable.
01027                                 {
01028                                         pickedContValue_ = pickedContValues[atomIdx];
01029                                 }
01030                                 return atomIdx;
01031                         }  // Greedy
01032                 }  // Hybrid clause.
01033                 return NOVALUE;
01034         }
01035 
01036         int pickSA()
01037         {
01038                 //      if (hmwsdebug) cout << "Entering HMaxWalkSat::pickSA" << endl;
01039                 if (wjhmwsdebug)
01040                 {
01041                         cout << "SA" << endl;
01042 
01043                 }
01044 
01045                 // Choose a random atom to flip
01046                 int toFlip = hstate_->getIndexOfRandomAtom(); //change to hybrid, pos, discrete, neg, continuous
01047                 if (toFlip > 0)//discrete atom
01048                 {
01049                         if (wjhmwsdebug)
01050                         {
01051                                 cout << "Choose to flip dis atom " << toFlip << ":";hstate_->printDisAtom(toFlip, cout);
01052                         }
01053                         long double improvement = hstate_->getImprovementInWeightSumByFlipping(toFlip);
01054                         
01055                         if (wjhmwsdebug)
01056                         {
01057                                 cout << "By flipping, improvement is " << improvement << endl;
01058                         }
01059 
01060                         // If pos. or no improvement, then the atom will be flipped
01061                         // Or neg. improvement: According to temp. flip atom anyway
01062                         if ((improvement >= 0) ||
01063                                 (random() <= exp(improvement/(saTemp_)) * RAND_MAX))
01064                         {
01065                                 // If atom can not be flipped, then null flip
01066                                 saSteps_ ++;
01067                                 if (saSteps_ % saInterval_ == 0)
01068                                 {
01069                                         saTemp_ = saTemp_ * saTempDownRatio_;
01070                                 }
01071                                 return toFlip;
01072                         }
01073                         else
01074                         {
01075                                 return NOVALUE;
01076                         }
01077                 }
01078                 else //continuous atom
01079                 {
01080                         //generate the new value for the continuous variable according to the proposal distribution
01081                         int contAtomIdx = -toFlip;
01082                         double vContAtomFlipped = hstate_->getContVarValueByRandomMove(contAtomIdx);    
01083                         //compute the proposed cont value here
01084 
01085                         long double improvement = hstate_->getImprovementRandomMoveCont(contAtomIdx, vContAtomFlipped); // change to hybrid
01086 
01087                         if (wjhmwsdebug)
01088                         {
01089                                 cout << "Choose to flip cont atom " << contAtomIdx << ":";hstate_->printContAtom(contAtomIdx, cout);
01090                         }
01091                         if (wjhmwsdebug)
01092                         {
01093                                 cout << "By flipping to " << vContAtomFlipped << ", improvement is " << improvement << endl;
01094                         }
01095                         if ((improvement >= 0) || (random() <= exp(improvement/(saTemp_)) * RAND_MAX))
01096                         {       
01097                                 pickedContValue_ = vContAtomFlipped; //the value picked.
01098                                 saSteps_ ++;
01099                                 if (saSteps_ % saInterval_ == 0)
01100                                 {
01101                                         saTemp_ = saTemp_ * saTempDownRatio_;
01102                                 }
01103                                 return toFlip; //neg, indicate cont variable.
01104                         } else {
01105                                 return NOVALUE;
01106                         }
01107                 }       
01108                 //need to update the temperature here
01109         }
01116         int pickSS()
01117         {
01118                 long double costOfFalseClauses = hstate_->getCostOfTotalFalseConstraints();
01119                 // If we have already reached a solution or if in an SA step,
01120                 // then perform SA
01121                 if (costOfFalseClauses <= targetCost_ + SMALLVALUE || (random() % 100 < saRatio_ && !lateSa_))
01122                 {
01123                         if (wjhmwsdebug)
01124                         {
01125                                 cout << "SASTEP" << endl;
01126                         }
01127                         // Choose a random atom to flip
01128                         int toFlip = hstate_->getIndexOfRandomAtom(); //change to hybrid, pos, discrete, neg, continuous
01129                         if (toFlip > 0)  // Discrete atom.
01130                         {
01131                                 if (wjhmwsdebug)
01132                                 {
01133                                         cout << "Choose to flip dis atom " << toFlip << ":";hstate_->printDisAtom(toFlip, cout);
01134                                 }
01135                                 long double improvement = calculateImprovementDisHMCS(toFlip); 
01136 
01137                                 if (wjhmwsdebug)
01138                                 {
01139                                         cout << "By flipping, improvement is " << improvement << endl;
01140                                 }
01141 
01142                                 // If pos. or no improvement, then the atom will be flipped
01143                                 // Or neg. improvement: According to temp. flip atom anyway
01144                                 if ((improvement >= 0) || (random() <= exp(improvement/(saTemp_/100.0)) * RAND_MAX))
01145                                 {
01146                                         return toFlip;
01147                                 }
01148                                 else
01149                                 {
01150                                         return NOVALUE;
01151                                 }
01152                         }
01153                         else  // Continuous variable.
01154                         {
01155                                 //generate the new value for the continuous variable according to the proposal distribution
01156                                 int contAtomIdx = -toFlip;
01157                                 double vContAtomFlipped;                                
01158                                 long double improvement = hstate_->GetImprovementByMovingContVar(contAtomIdx, vContAtomFlipped); 
01159                                 
01160                                 if (wjhmwsdebug)
01161                                 {
01162                                         cout << "Choose to move cont atom " << contAtomIdx << ":";hstate_->printContAtom(contAtomIdx, cout);
01163                                         cout << " To " << vContAtomFlipped << ", improvement is " << improvement << endl;
01164                                 }
01165 
01166                                 if ((improvement >= 0) ||
01167                                         (random() <= exp(improvement/(saTemp_/100.0)) * RAND_MAX))
01168                                 {       
01169                                         pickedContValue_ = vContAtomFlipped; //the value picked.
01170                                         return toFlip; //neg, indicate cont variable.
01171                                 }         
01172                                 else
01173                                 {
01174                                         return NOVALUE;
01175                                 }
01176                         }       
01177                 }
01178                 // Not in a solution or SA step: perform Hybrid WalkSAT step
01179                 else
01180                 {
01181                         return pickHMCS();  // TODO: juewang
01182                 }
01183         }
01200         long double calculateImprovementDisHMCS(const int& atomIdx)     //should return the number of constraints satisfied by flipping minus the number of constraints violated by flipping
01201         {
01202                 return hstate_->getImprovementByFlippingDisHMCS(atomIdx);
01203         }
01204 
01205 
01206         // No consideration of handling lazy and blocking is taken into account.
01207         // The improvement is computed based on the actual weighted feature values.
01208         long double calculateImprovementDisHMWS(int atomIdx)
01209         {
01210                 if (atomIdx > 0) //discrete
01211                 {
01212                         return hstate_->getImprovementByFlippingDisHMWS(atomIdx);
01213                 }
01214                 return 0;       
01215         }
01216 
01221         void reconstructLowState()
01222         {
01223                 assert(lazyLowState_);
01224                 if (hmwsdebug) cout << "Reconstructing low state ..." << endl;
01225                 hash_set<int>::const_iterator it = varsFlippedSinceLowState_.begin();
01226                 for (; it != varsFlippedSinceLowState_.end(); it++)
01227                 {
01228                         if (hmwsdebug)
01229                         {
01230                                 cout << "Flipping atom " << (*it) << endl;
01231                         }
01232                         hstate_->flipAtomValue(*it, -1);
01233                 }
01234                 hstate_->saveLowState();
01235                 if (hmwsdebug) cout << "Done reconstructing low state ..." << endl;
01236         }
01237 
01238 private:
01239         int saInterval_;
01240         unsigned int saSteps_;
01241         double maxSeconds_;
01242         double saTempDownRatio_;
01243         double saTempInit_;
01244         double pickedContValue_;
01245         int pickedContIdx_;
01246         //Array<int> pick2VarIdx_;
01247         Array<int> pickDisIdx_;
01248         //Array<double> pick2VarValue_;
01249 
01251         // Heuristic to be used to pick an atom
01252         int heuristic_;
01253         // At least this many flips must occur before flipping the same atom
01254         int tabuLength_;
01255 
01256         // BEGIN: SampleSat parameters
01257         // Percent of sim. annealing steps
01258         int saRatio_;
01259         // Sim. annealing temperature
01260         double saTemp_;
01261         // Run sim. annealing only at a plateur
01262         bool lateSa_;
01263         // END: SampleSat parameters
01265 
01266         // Function pointer holds which function is to be used to pick an atom
01267         // = {pickRandom, pickBest, pickTabu, pickSS};
01268         int (HMaxWalkSat::*pickcode[15])(void);
01269         // If true, never break a highest cost clause
01270         bool hard_;
01271 
01272         // Make random flip with numerator/denominator probability
01273         int numerator_;
01274         int denominator_;
01275 
01276         // Which other atom to flip in block
01277         bool inBlock_;
01278         int flipInBlock_;
01279 
01280         // If false, the naive way of saving low states (each time a low state is
01281         // found, the whole state is saved) is used; otherwise, a list of variables
01282         // flipped since the last low state is kept and the low state is
01283         // reconstructed. This can be much faster for very large data sets.
01284         bool lazyLowState_;
01285         // List of variables flipped since last low state was found. This is used
01286         // to reconstruct the low state when lazyLowState_ is set.
01287         hash_set<int> varsFlippedSinceLowState_;
01288         //unsigned falseDisNum_;
01289 };
01290 
01291 #endif

Generated on Sun Jun 7 11:55:12 2009 for Alchemy by  doxygen 1.5.1