00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #ifndef 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
00111
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
00122 saRatio_ = params->ssParams->saRatio;
00123 saTemp_ = params->ssParams->saTemp;
00124 saTempInit_ = saTemp_;
00125 lateSa_ = params->ssParams->lateSa;
00126
00127
00128 if (heuristic_ == TABU || heuristic_ == SS || heuristic_ == HMWS) {
00129 changed_.growToSize(numAtoms + 1);
00130 }
00131 numFlips_ = 0;
00132
00133
00134 numerator_ = 50;
00135 denominator_ = 100;
00136
00137 inBlock_ = false;
00138 flipInBlock_ = NOVALUE;
00139
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
00193 hstate_->initRandom();
00194
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
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
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
00255 while (numsuccesstry < numSolutions_ && numtry < maxTries_ && !timeUp)
00256 {
00257 numtry++;
00258 numFlips_ = 0;
00259 bool lowStateInThisTry = false;
00260
00261
00262
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
00288 if (atomIdx < 0)
00289 {
00290 atomIdx = -atomIdx;
00291 if (!hstate_->bMaxOnly_)
00292 {
00293 if (pickedContValue_ == UNSOLVABLE) {
00294 continue;
00295 }
00296 hstate_->UpdateHybridClauseInfoByContAtom(atomIdx, pickedContValue_);
00297 }
00298 else
00299 {
00300 if (pickedContValue_ == UNSOLVABLE) {
00301 continue;
00302 }
00303 hstate_->UpdateHybridClauseWeightSumByContAtom(atomIdx, pickedContValue_);
00304 }
00305 }
00306 else if (atomIdx >0 && atomIdx != NOVALUE)
00307 {
00308 if (!hstate_->bMaxOnly_)
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 }
00328 else
00329 {
00330 flipAtom(atomIdx);
00331 bool atomValue = hstate_->getValueOfAtom(atomIdx);
00332 hstate_->UpdateHybridClauseWeightSumByDisAtom(atomIdx, atomValue);
00333 }
00334 }
00335
00336
00337
00338
00339 double discost = 0, hybridcost = 0;
00340 long double costOfFalseConstraints = 0;
00341 if (!hstate_->bMaxOnly_)
00342 {
00343 costOfFalseConstraints = hstate_->getCostOfTotalFalseConstraints();
00344 }
00345 else
00346 {
00347 costOfFalseConstraints = hstate_->getCostOfAllClauses(discost, hybridcost);
00348 }
00349
00350
00351
00352
00353 if(!hstate_->bMaxOnly_)
00354 {
00355 if (costOfFalseConstraints <= lowCost)
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
00367
00368
00369 if (costOfFalseConstraints <= targetCost_ + SMALLVALUE)
00370 numsuccesstry++;
00371 }
00372 else
00373 {
00374 if (costOfFalseConstraints >= lowCost)
00375 {
00376 lowCost = costOfFalseConstraints;
00377 hstate_->saveLowStateAll();
00378 }
00379 }
00380 }
00381
00382 if (!hstate_->bMaxOnly_)
00383 {
00384 totaltrynum += numFlips_;
00385 if (lowStateInThisTry)
00386 reconstructLowState();
00387 hstate_->saveLowStateToDB();
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 }
00397
00398 if (!hstate_->bMaxOnly_)
00399 {
00400 if (hmwsdebug)
00401 {
00402 cout << "Total flips num: " << totaltrynum << ". Succeed:" << numsuccesstry << " times." << endl;
00403 }
00404
00405 if (numsuccesstry == 0)
00406 {
00407
00408 hstate_->saveLastAsCurrentAssignment();
00409 hstate_->updateCost();
00410 hstate_->saveLowStateAll();
00411 }
00412
00413 hstate_->saveLowToCurrentAll();
00414
00415 if (trackClauseTrueCnts_)
00416 {
00417 hstate_->updateNumTrueLits();
00418 hstate_->getNumClauseGndings(clauseTrueCnts_, true);
00419 hstate_->getContClauseGndings(clauseTrueCntsCont_);
00420 }
00421 }
00422 else
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
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
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 double collapseDepthConstraint(double th)
00491 {
00492 return 0;
00493 }
00494
00495 protected:
00496
00503 void flipAtom (int toFlip)
00504 {
00505
00506 if (toFlip == NOVALUE)
00507 return;
00508
00509
00510 hstate_->flipAtom(toFlip, -1);
00511
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
00521
00522
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
00572
00573 bool noisyPick = (numerator_ > 0 && random() % denominator_ < numerator_);
00574
00575
00576
00577 int toFix = hstate_->getRandomFalseClauseIndexHMCS();
00578 if (toFix == NOVALUE)
00579 {
00580 return NOVALUE;
00581 }
00582 else if (toFix > 0)
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
00593 Array<int> best;
00594
00595 register int numbest = 0;
00596
00597 long double bestvalue = -LDBL_MAX;
00598
00599
00600 if (noisyPick)
00601 {
00602 for (int i = 0; i < clauseSize; ++i)
00603 {
00604 register int lit = hstate_->getAtomInClause(i, toFix);
00605
00606 if (cost < 0 && !hstate_->isTrueLiteral(lit)) continue;
00607 best.append(abs(lit));
00608 numbest++;
00609 }
00610 }
00611 else
00612 {
00613 for (int i = 0; i < clauseSize; ++i)
00614 {
00615 register int lit = hstate_->getAtomInClause(i, toFix);
00616
00617 if (cost < 0 && !hstate_->isTrueLiteral(lit)) continue;
00618
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
00626 if (improvement > 0 && improvement >= bestvalue)
00627 {
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 {
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
00659 if (numbest == 1) {
00660 toFlip = best[0];
00661 } else {
00662
00663 toFlip = best[random()% best.size()];
00664 }
00665
00666 if (wjhmwsdebug)
00667 {
00668 cout << "Improvement:" << bestvalue << endl;
00669 }
00670 return toFlip;
00671 }
00672 else
00673 {
00674 toFix++;
00675 int contClauseIdx = -toFix;
00676
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)
00686 {
00687 set<int> pickedContVars;
00688 int inIdx = random() % totalVarNum;
00689 if (inIdx < contVarNum)
00690 {
00691 int contAtomIdx = hstate_->hybridContClause_[contClauseIdx][inIdx];
00692
00693
00694 pickedContValue_ = hstate_->SolveHybridConstraintToContVarSample(contClauseIdx, inIdx);
00695 if (pickedContValue_ == FLIPDIS) {
00696
00697 Array<bool> solution;
00698 GetClauseRandomSolution(hstate_->hybridDisClause_[contClauseIdx].size(), true, hstate_->hybridConjunctionDisjunction_[contClauseIdx], &solution);
00699
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
00709 double cont_part_value = hstate_->HybridClauseContPartValue(contClauseIdx);
00710 if (cont_part_value < hstate_->hybridConstraints_[contClauseIdx].vThreshold_) {
00711
00712 double cont_var_value = hstate_->SolveConstraintAndRandomSample(contClauseIdx, inIdx);
00713 if (cont_var_value == UNSOLVABLE)
00714 return NOVALUE;
00715 else {
00716
00717 hstate_->UpdateHybridClauseInfoByContAtom(contAtomIdx, cont_var_value);
00718 }
00719 }
00720
00721
00722 return NOVALUE;
00723 }
00724
00725 return -contAtomIdx;
00726 }
00727 else
00728 {
00729
00730
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 }
00742 else
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
00751
00752 double cont_var_val = 0;
00753 double improvement =
00754 hstate_->GetImprovementBySolvingHybridConstraintToContVar(contClauseIdx, i, cont_var_val);
00755
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 {
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
00787 if (numbest == 1)
00788 atomIdx = best[0];
00789 else
00790
00791 atomIdx = best[random()%numbest];
00792
00793 if (atomIdx < 0)
00794 {
00795 pickedContValue_ = pickedContValues[atomIdx];
00796 }
00797 return atomIdx;
00798 }
00799 }
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
00830
00831 bool noisyPick = (numerator_ > 0 && random()%denominator_ < numerator_);
00832
00833
00834
00835
00836 int toFix = hstate_->getRandomFalseClauseIndexHMWS();
00837
00838 if (toFix == NOVALUE)
00839 {
00840 return NOVALUE;
00841 } else if (toFix > 0) {
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
00851 Array<int> best;
00852
00853 register int numbest = 0;
00854
00855 long double bestvalue = -LDBL_MAX;
00856
00857
00858 if (noisyPick)
00859 {
00860 for (int i = 0; i < clauseSize; i++)
00861 {
00862 register int lit = hstate_->getAtomInClause(i, toFix);
00863
00864 if (cost < 0 && !hstate_->isTrueLiteral(lit)) continue;
00865 best.append(abs(lit));
00866 numbest++;
00867 }
00868 }
00869
00870 else {
00871 for (int i = 0; i < clauseSize; i++)
00872 {
00873 register int lit = hstate_->getAtomInClause(i, toFix);
00874
00875 if (cost < 0 && !hstate_->isTrueLiteral(lit)) continue;
00876
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
00884 if (improvement > 0 && improvement >= bestvalue)
00885 {
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 {
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
00918 if (numbest == 1)
00919 toFlip = best[0];
00920 else
00921
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 }
00932 else
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)
00946 {
00947 set<int> pickedContVars;
00948 int inIdx = random() % totalVarNum;
00949 if (inIdx < contVarNum)
00950 {
00951 int contAtomIdx = hstate_->hybridContClause_[contClauseIdx][inIdx];
00952
00953
00954 if (hstate_->HybridClauseDisPartValue(contClauseIdx)) {
00955
00956
00957 pickedContValue_ = hstate_->OptimizeHybridClauseToContVar(contClauseIdx, inIdx);
00958 return -contAtomIdx;
00959 }
00960 else return NOVALUE;
00961 }
00962 else
00963 {
00964
00965
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 }
00975 else
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
00987 double improvement = hstate_->ReduceClauseAndOptimize(contAtomIdx, &assign);
00988 if (improvement == NOVALUE) continue;
00989 if (improvement >= bestvalue)
00990 {
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 {
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
01020 if (numbest == 1)
01021 atomIdx = best[0];
01022 else
01023
01024 atomIdx = best[random()%numbest];
01025
01026 if (atomIdx < 0)
01027 {
01028 pickedContValue_ = pickedContValues[atomIdx];
01029 }
01030 return atomIdx;
01031 }
01032 }
01033 return NOVALUE;
01034 }
01035
01036 int pickSA()
01037 {
01038
01039 if (wjhmwsdebug)
01040 {
01041 cout << "SA" << endl;
01042
01043 }
01044
01045
01046 int toFlip = hstate_->getIndexOfRandomAtom();
01047 if (toFlip > 0)
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
01061
01062 if ((improvement >= 0) ||
01063 (random() <= exp(improvement/(saTemp_)) * RAND_MAX))
01064 {
01065
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
01079 {
01080
01081 int contAtomIdx = -toFlip;
01082 double vContAtomFlipped = hstate_->getContVarValueByRandomMove(contAtomIdx);
01083
01084
01085 long double improvement = hstate_->getImprovementRandomMoveCont(contAtomIdx, vContAtomFlipped);
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;
01098 saSteps_ ++;
01099 if (saSteps_ % saInterval_ == 0)
01100 {
01101 saTemp_ = saTemp_ * saTempDownRatio_;
01102 }
01103 return toFlip;
01104 } else {
01105 return NOVALUE;
01106 }
01107 }
01108
01109 }
01116 int pickSS()
01117 {
01118 long double costOfFalseClauses = hstate_->getCostOfTotalFalseConstraints();
01119
01120
01121 if (costOfFalseClauses <= targetCost_ + SMALLVALUE || (random() % 100 < saRatio_ && !lateSa_))
01122 {
01123 if (wjhmwsdebug)
01124 {
01125 cout << "SASTEP" << endl;
01126 }
01127
01128 int toFlip = hstate_->getIndexOfRandomAtom();
01129 if (toFlip > 0)
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
01143
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
01154 {
01155
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;
01170 return toFlip;
01171 }
01172 else
01173 {
01174 return NOVALUE;
01175 }
01176 }
01177 }
01178
01179 else
01180 {
01181 return pickHMCS();
01182 }
01183 }
01200 long double calculateImprovementDisHMCS(const int& atomIdx)
01201 {
01202 return hstate_->getImprovementByFlippingDisHMCS(atomIdx);
01203 }
01204
01205
01206
01207
01208 long double calculateImprovementDisHMWS(int atomIdx)
01209 {
01210 if (atomIdx > 0)
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
01247 Array<int> pickDisIdx_;
01248
01249
01251
01252 int heuristic_;
01253
01254 int tabuLength_;
01255
01256
01257
01258 int saRatio_;
01259
01260 double saTemp_;
01261
01262 bool lateSa_;
01263
01265
01266
01267
01268 int (HMaxWalkSat::*pickcode[15])(void);
01269
01270 bool hard_;
01271
01272
01273 int numerator_;
01274 int denominator_;
01275
01276
01277 bool inBlock_;
01278 int flipInBlock_;
01279
01280
01281
01282
01283
01284 bool lazyLowState_;
01285
01286
01287 hash_set<int> varsFlippedSinceLowState_;
01288
01289 };
01290
01291 #endif