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
00072 #include "lazysat.h"
00073 #include "lazyutil.h"
00074 #include "lazyinfo.h"
00075 #include "timer.h"
00076
00084 LazySat::LazySat(LazyInfo *lazyInfo, int memLimit)
00085 {
00086 clauseStorePtr = NULL;
00087 clauseFreeStore = 0;
00088
00089 atomStorePtr = NULL;
00090 atomFreeStore = 0;
00091
00092 atomFSMgr = new FreeStoreManager(BLOCKSIZE);
00093 clauseFSMgr = new FreeStoreManager(BLOCKSIZE);
00094
00095 costexpected = true;
00096 hard = 0;
00097 noApprox = false;
00098
00099 this->lazyInfo = lazyInfo;
00100 this->memLimit = memLimit;
00101 clauseLimit = INT_MAX;
00102 haveDeactivated = false;
00103
00104 numatom = 0;
00105 basenumatom = 0;
00106 numclause = 0;
00107 numliterals = 0;
00108
00109
00110
00111
00112 clausemem = 0;
00113 atommem = 0;
00114
00115
00116 maxFixedAtoms = lazyInfo->getNumDBAtoms() + 1;
00117 fixedAtoms_ = new bool[maxFixedAtoms];
00118 for (int i = 0; i < maxFixedAtoms; i++)
00119 fixedAtoms_[i] = false;
00120
00121 }
00122
00123 LazySat::~LazySat()
00124 {
00125 clauseFSMgr->releaseAllStorePtr();
00126 atomFSMgr->releaseAllStorePtr();
00127
00128 deleteClauseMemory();
00129 deleteAtomMemory();
00130
00131 delete clauseFSMgr;
00132 delete atomFSMgr;
00133
00134 for(int i = 0; i < newClauses.size(); i++)
00135 delete newClauses[i];
00136 newClauses.clear();
00137 newClauseWeights.clear();
00138
00139 for(int i = 0; i < allClauses.size(); i++)
00140 delete allClauses[i];
00141 allClauses.clear();
00142 allClauseWeights.clear();
00143
00144 for(int i = 0; i < supersetClauses_.size(); i++)
00145 {
00146 supersetClauses_[i]->deleteIntPredicates();
00147 delete supersetClauses_[i];
00148 }
00149 supersetClauses_.clear();
00150
00151 delete [] fixedAtoms_;
00152 }
00153
00154
00155 void LazySat::randomizeActiveAtoms()
00156 {
00157 lazyInfo->getWalksatClauses(newClauses, newClauseWeights);
00158 for(int i = 0; i < newClauses.size(); i++)
00159 delete newClauses[i];
00160
00161 newClauses.clear();
00162 newClauseWeights.clear();
00163
00164 for(int i = 1; i < lazyInfo->getVarCount() + 1; i++)
00165 {
00166 lazyInfo->setVarVal(i, random()%2);
00167 }
00168 }
00169
00170
00171 bool LazySat::sample(const MaxWalksatParams* const & mwsParams,
00172 const SampleSatParams& sampleSatParams,
00173 const bool& initial)
00174 {
00175
00176 saRatio = sampleSatParams.saRatio;
00177 temperature = sampleSatParams.temperature;
00178 latesa = sampleSatParams.latesa;
00179 numerator = sampleSatParams.ws_noise;
00180
00181 int numsol = sampleSatParams.numsol;
00182
00183
00184 bool includeUnsatSolutions = false;
00185 Array<Array<bool>*> solutions;
00186 Array<int> numBad;
00187 infer(mwsParams, numsol, includeUnsatSolutions,
00188 solutions, numBad, initial);
00189
00190 for(int i = 0; i < newClauses.size(); i++)
00191 delete newClauses[i];
00192 newClauses.clear();
00193 newClauseWeights.clear();
00194
00195 for(int i = 0; i < allClauses.size(); i++)
00196 delete allClauses[i];
00197 allClauses.clear();
00198 allClauseWeights.clear();
00199
00200 int solutionsSize = solutions.size();
00201
00202 for (int i = 0; i < solutions.size(); i++)
00203 if (solutions[i]) delete solutions[i];
00204 solutions.clearAndCompress();
00205
00206 if (solutionsSize >= 1)
00207 return true;
00208 else
00209 return false;
00210 }
00211
00212
00213
00214 void LazySat::infer(const MaxWalksatParams* const & params,
00215 const int& numSolutions, const bool& includeUnsatSolutions,
00216 Array<Array<bool>*>& solutions, Array<int>& numBad,
00217 const bool& initial)
00218 {
00219
00220 bool printonlysol = false;
00221 bool printfalse = false;
00222 bool printlow = true;
00223 int printtrace = 1000;
00224
00225 long int totalflip = 0;
00226 int numtry = 0;
00227 int numsuccesstry = 0;
00228 int numsol = numSolutions;
00229 int seed;
00230 struct timeval tv;
00231 struct timezone tzp;
00232 double setuptime;
00233 double expertime;
00234 double totaltime;
00235
00236 long int lowbad;
00237 long int lowcost;
00238 double seconds_per_flip;
00239
00240 int worst_cost, computed_cost;
00241
00242 gettimeofday(&tv,&tzp);
00243 seed = (( tv.tv_sec & 0177 ) * 1000000) + tv.tv_usec;
00244 srandom(seed);
00245
00246 heuristic = BEST;
00247 numerator = NOVALUE;
00248 denominator = 100;
00249
00250 int targetcost = params->targetWt;
00251 if (targetcost == INT_MAX) targetcost = 0;
00252 if (params->hard) hard = true;
00253
00254 int cutoff = params->maxSteps;
00255 int numrun = params->tries;
00256
00257
00258 if (numrun < numsol) numrun = numsol;
00259 if (params->lazyNoApprox) noApprox = true;
00260
00261 if (numerator == NOVALUE)
00262 {
00263 if (heuristic == BEST)
00264 numerator = 50;
00265 else
00266 numerator = 0;
00267 }
00268
00269
00270 if (memLimit > 0)
00271 {
00272
00273
00274
00275 int atomSize = 2*sizeof(int)*sizeof(int) + 11*sizeof(int);
00276 int clauseSize = (2 * ((sizeof(int)*sizeof(int) + 5*sizeof(int))
00277 + atomSize / 5));
00278
00279 clauseLimit = ((memLimit/2) / clauseSize) * 1024;
00280
00281 }
00282
00283 setuptime = 0;
00284 expertime = 0;
00285 elapsed_seconds();
00286
00287 if (initial)
00288 {
00289 init();
00290 }
00291 else if (lazyInfo->getSampleSat())
00292 {
00293 newClauses.clear();
00294 newClauseWeights.clear();
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 resetSampleSat();
00305
00306 lazyInfo->selectClauses(supersetClauses_, newClauses,
00307 newClauseWeights);
00308
00309 initFixedAtoms(newClauses, newClauseWeights);
00310 lazyInfo->propagateFixedAtoms(newClauses, newClauseWeights,
00311 fixedAtoms_, maxFixedAtoms);
00312
00313 clauseFSMgr->releaseAllStorePtr();
00314 atomFSMgr->releaseAllStorePtr();
00315
00316 deleteClauseMemory();
00317 deleteAtomMemory();
00318
00319 delete clauseFSMgr;
00320 delete atomFSMgr;
00321
00322 clauseStorePtr = NULL;
00323 clauseFreeStore = 0;
00324
00325 atomStorePtr = NULL;
00326 atomFreeStore = 0;
00327
00328 atomFSMgr = new FreeStoreManager(BLOCKSIZE);
00329 clauseFSMgr = new FreeStoreManager(BLOCKSIZE);
00330
00331 numatom = 0;
00332 numclause = 0;
00333 numliterals = 0;
00334 numfalse = 0;
00335 costofnumfalse = 0;
00336
00337
00338 bool initial = true;
00339 addNewClauses(initial);
00340 }
00341
00342 setuptime = elapsed_seconds();
00343
00344 abort_flag = false;
00345 numnullflip = 0;
00346 lowcost = BIG;
00347
00348
00349 for (int k = 0; k < numrun; k++)
00350 {
00351 initrun();
00352 lowbad = numfalse;
00353 lowcost = costofnumfalse;
00354 save_low_assign();
00355 numflip = 0;
00356
00357 if (printtrace)
00358 {
00359 cout<<"in the beginning, costofnumfalse = "<<costofnumfalse<<endl;
00360 cout<<"cutoff = "<<cutoff<<endl;
00361 cout<<"numflip = "<<numflip<<endl;
00362 cout<<"numfalse = "<<numfalse<<endl;
00363 cout<<"numclause = "<<numclause<<endl;
00364 cout<<"targetcost = "<<targetcost<<endl;
00365 cout<<"hard = "<<hard<<endl;
00366
00367 cout<<"costofnumfalse \t numfalse \t numflip \t numclause"<<endl;
00368 }
00369
00370 while((numflip < cutoff) )
00371 {
00372 if (numclause == 0) break;
00373 if (printtrace && (numflip % printtrace == 0))
00374 {
00375 printf("%10i \t %10i \t %10li \t %10i\n",
00376 costofnumfalse, numfalse, numflip, numclause);
00377 fflush(stdout);
00378 }
00379
00380 numflip++;
00381
00382
00383 if (numclause > clauseLimit)
00384 {
00385 trimClauses();
00386 initrun();
00387 lowbad = numfalse;
00388 lowcost = costofnumfalse;
00389 save_low_assign();
00390 continue;
00391 }
00392
00393
00394 if (!lazyInfo->getSampleSat() || !simAnnealing())
00395 {
00396 if (hard && eqhighest && costexpected)
00397 {
00398 fix(selecthigh(1 + random()%numhighest));
00399 }
00400 else
00401 {
00402 fix(falseclause[random()%numfalse]);
00403 }
00404 }
00405
00406 if (costofnumfalse <= lowcost)
00407 {
00408 lowcost = costofnumfalse;
00409 lowbad = numfalse;
00410 save_low_assign();
00411 }
00412
00413 if (costofnumfalse <= targetcost)
00414 break;
00415 }
00416
00417 numtry++;
00418 totalflip += numflip;
00419 if(costofnumfalse <= targetcost)
00420 {
00421 numsuccesstry++;
00422 }
00423
00424 countlowunsatcost(&computed_cost, &worst_cost);
00425
00426
00427 if (printlow && (!printonlysol || costofnumfalse <= targetcost))
00428 {
00429 if (includeUnsatSolutions || lowbad == 0)
00430 {
00431 Array<bool>* solution = new Array<bool>(numatom);
00432 for (int i = 0; i < numatom; i++) solution->append(false);
00433
00434 for (int i = 1; i <= numatom; i++)
00435 {
00436 if (lowatom[i] == 1) (*solution)[i-1] = true;
00437 else (*solution)[i-1] = false;
00438 }
00439 solutions.append(solution);
00440 numBad.append(lowbad);
00441 }
00442 }
00443 if (numfalse > 0 && printfalse)
00444 print_false_clauses_cost(lowbad);
00445
00446 if (numsuccesstry >= numsol) break;
00447 if (abort_flag) break;
00448 fflush(stdout);
00449 }
00450
00451
00452 lazyInfo->setVarVals(lowatom);
00453
00454
00455 if (lazyInfo->getSampleSat())
00456 undoFixedAtoms();
00457
00458 expertime += elapsed_seconds();
00459 totaltime = setuptime + expertime;
00460 seconds_per_flip = expertime / totalflip;
00461
00462
00463 return;
00464 }
00465
00466 int LazySat::getNumInitClauses()
00467 {
00468 return initClauseCount;
00469 }
00470
00471 int LazySat::getNumInitAtoms()
00472 {
00473 return initAtomCount;
00474 }
00475
00476 int LazySat::getNumClauses()
00477 {
00478 return numclause;
00479 }
00480
00486 void LazySat::resetSampleSat()
00487 {
00488
00489 for(int atom = basenumatom + 1; atom <= numatom; atom++)
00490 {
00491 lazyInfo->setVarVal(atom, false);
00492 lazyInfo->setInactive(atom);
00493 }
00494
00495
00496 for(int i = allClauses.size() - 1; i >= 0; i++)
00497 {
00498 delete allClauses[i];
00499 allClauses.removeLastItem();
00500 allClauseWeights.removeLastItem();
00501 }
00502 allClauses.shrinkToSize(initClauseCount);
00503 numclause = 0;
00504 }
00505
00506
00507
00508
00509
00510
00511
00518 void LazySat::init()
00519 {
00520 Timer timer;
00521 double begSec = timer.time();
00522
00523
00524 highestcost = BIG;
00525
00526 numclause = 0;
00527 numatom = 0;
00528 numliterals = 0;
00529
00530
00531
00532 bool sample = lazyInfo->getSampleSat();
00533
00534 for(int i = 0; i < newClauses.size(); i++)
00535 delete newClauses[i];
00536 newClauses.clear();
00537 newClauseWeights.clear();
00538
00539 int defaultCnt = 0;
00540 double defaultCost = 0;
00541
00542 if (sample)
00543 {
00544 lazyInfo->getSupersetClauses(supersetClauses_);
00545
00546 defaultCnt = supersetClauses_.size();
00547 for(int i = 0; i < defaultCnt; i++)
00548 defaultCost += supersetClauses_[i]->getWt();
00549
00550 for(int i = 0; i < supersetClauses_.size(); i++)
00551 {
00552 supersetClauses_[i]->deleteIntPredicates();
00553 delete supersetClauses_[i];
00554 }
00555
00556 supersetClauses_.clear();
00557 }
00558 else
00559 {
00560 lazyInfo->getWalksatClauses(newClauses, newClauseWeights);
00561 for(int i = 0; i < newClauses.size(); i++)
00562 delete newClauses[i];
00563
00564 defaultCnt = newClauses.size();
00565 for(int i = 0; i < defaultCnt; i++)
00566 defaultCost += newClauseWeights[i];
00567
00568 newClauses.clear();
00569 newClauseWeights.clear();
00570 }
00571
00572 cout<<endl;
00573 cout<<"Default => Cost\t"<<"******\t"<<" Clause Cnt\t"<<endl;
00574 cout<<" "<<defaultCost<<"\t"<<"******\t"<<defaultCnt<<"\t"<<endl<<endl;
00575
00576 basenumatom = lazyInfo->getVarCount();
00577 cout << "Number of Baseatoms = " << basenumatom << endl;
00578
00579 for(int i = 1; i < basenumatom + 1; i++)
00580 lazyInfo->setActive(i);
00581
00582
00583 if (sample)
00584 {
00585 lazyInfo->getSupersetClauses(supersetClauses_);
00586
00587
00588 cout << "Superset:" << endl;
00589 lazyInfo->printIntClauses(supersetClauses_);
00590
00591 lazyInfo->selectClauses(supersetClauses_, newClauses,
00592 newClauseWeights);
00593 initFixedAtoms(newClauses, newClauseWeights);
00594 lazyInfo->propagateFixedAtoms(newClauses, newClauseWeights,
00595 fixedAtoms_, maxFixedAtoms);
00596
00597 }
00598 else
00599 lazyInfo->getWalksatClauses(newClauses, newClauseWeights);
00600
00601
00602 bool initial = true;
00603 addNewClauses(initial);
00604
00605 initAtomCount = lazyInfo->getVarCount();
00606 initClauseCount = allClauses.size();
00607
00608 cout << "Atoms in memory: " << initAtomCount << endl;
00609 cout << "Initial active clauses: " << initClauseCount << endl;
00610
00611 cout << "time taken for init = "; Timer::printTime(cout, timer.time()-begSec);
00612 cout << endl;
00613 }
00614
00615
00616
00617 void LazySat::initrun()
00618 {
00619
00620 int newval;
00621 numfalse = 0;
00622 costofnumfalse = 0;
00623 eqhighest = false;
00624 numhighest = 0;
00625
00626
00627
00628 for(int i = 1; i < numatom + 1; i++)
00629 {
00630 changed[i] = -BIG;
00631 breakcost[i] = 0;
00632
00633 if (fixedAtoms_[i])
00634 {
00635 newval = lazyInfo->getVarVal(i);
00636 }
00637 else
00638 {
00639 if (i <= basenumatom && !lazyInfo->inBlock(i))
00640 newval = random()%2;
00641 else
00642 newval = initatom[i];
00643 }
00644
00645 if (atom[i] != newval)
00646 {
00647 lazyInfo->flipVar(i);
00648 atom[i] = newval;
00649 }
00650 }
00651 initializeBreakCost(0);
00652
00653
00654 }
00655
00656
00657 void LazySat::fix(int tofix)
00658 {
00659 Timer timer;
00660
00661 double interimSec;
00662
00663
00664 if (cost[tofix] < 0)
00665 {
00666
00667 if (numtruelit[tofix] > 0)
00668 {
00669 for (int i = 0; i < size[tofix]; i++)
00670 {
00671 int atm = abs(clause[tofix][i]);
00672
00673 if((clause[tofix][i] > 0) == atom[atm])
00674 {
00675
00676
00677
00678 if ((haveDeactivated && lazyInfo->isDeactivated(atm)) ||
00679 (lazyInfo->inBlockWithEvidence(atm)))
00680 continue;
00681
00682 if(!lazyInfo->isActive(atm))
00683 {
00684 interimSec = timer.time();
00685
00686
00687 lazyInfo->getWalksatClausesWhenFlipped(atm, newClauses, newClauseWeights);
00688
00689 bool initial = false;
00690 addNewClauses(initial);
00691 lazyInfo->setActive(atm);
00692
00693
00694 }
00695 else
00696 {
00697
00698 if (lazyInfo->inBlock(atm))
00699 {
00700 lazyInfo->chooseOtherToFlip(atm, newClauses, newClauseWeights);
00701 bool initial = false;
00702 addNewClauses(initial);
00703 }
00704 }
00705
00706 if (lazyInfo->getInBlock())
00707 lazyInfo->setActive(lazyInfo->getOtherAtom());
00708
00709 flipatom(atm);
00710 if (lazyInfo->getInBlock())
00711 {
00712 flipatom(lazyInfo->getOtherAtom());
00713 }
00714
00715 lazyInfo->flipVar(atm);
00716 if (lazyInfo->getInBlock())
00717 lazyInfo->flipVar(lazyInfo->getOtherAtom());
00718
00719
00720 lazyInfo->setInBlock(false);
00721 lazyInfo->setOtherAtom(-1);
00722
00723
00724 }
00725 }
00726 }
00727
00728 else
00729 {
00730 numnullflip++;
00731 }
00732 }
00733
00734 else
00735 {
00736
00737 int numbreak[MAXLENGTH];
00738
00739 int i;
00740 int choice;
00741
00742 for(i = 0; i < size[tofix]; i++)
00743 {
00744
00745 int atm = abs(clause[tofix][i]);
00746
00747
00748
00749 if ((haveDeactivated && lazyInfo->isDeactivated(atm)) ||
00750 (lazyInfo->inBlockWithEvidence(atm)))
00751 {
00752 numbreak[i] = INT_MAX;
00753 continue;
00754 }
00755
00756
00757
00758
00759 if(!lazyInfo->isActive(atm))
00760 {
00761 interimSec = timer.time();
00762
00763 numbreak[i] = lazyInfo->getUnSatCostWhenFlipped(atm, newClauses, newClauseWeights);
00764 bool initial = false;
00765 addNewClauses(initial);
00766 lazyInfo->setActive(atm);
00767
00768 }
00769 else
00770 {
00771 numbreak[i] = breakcost[atm];
00772 }
00773
00774 }
00775
00776 switch(heuristic)
00777 {
00778 case RANDOM:
00779 choice = pickrandom(numbreak,size[tofix],tofix);
00780 break;
00781 case PRODUCTSUM:
00782 choice = pickproductsum(numbreak,size[tofix],tofix);
00783 break;
00784 case RECIPROCAL:
00785 choice = pickreciprocal(numbreak,size[tofix],tofix);
00786 break;
00787 case ADDITIVE:
00788 choice = pickadditive(numbreak,size[tofix],tofix);
00789 break;
00790 case BEST:
00791 interimSec = timer.time();
00792
00793 choice = pickbest(numbreak,size[tofix],tofix);
00794
00795
00796
00797
00798 break;
00799 case EXPONENTIAL:
00800 choice = pickexponential(numbreak,size[tofix],tofix);
00801 break;
00802 case TABU:
00803 choice = picktabu(numbreak,size[tofix],tofix);
00804 break;
00805 default:
00806 choice = pickbest(numbreak,size[tofix],tofix);
00807 }
00808
00809 if (choice == NOVALUE)
00810 numnullflip++;
00811 else
00812 {
00813 int atm = abs(clause[tofix][choice]);
00814
00815
00816
00817 if ((haveDeactivated && lazyInfo->isDeactivated(atm)) ||
00818 (lazyInfo->inBlockWithEvidence(atm)))
00819 {
00820 numnullflip++;
00821 return;
00822 }
00823
00824 if(!lazyInfo->isActive(atm))
00825 {
00826 interimSec = timer.time();
00827
00828
00829 lazyInfo->getWalksatClausesWhenFlipped(atm, newClauses, newClauseWeights);
00830
00831 bool initial = false;
00832 addNewClauses(initial);
00833 lazyInfo->setActive(atm);
00834
00835
00836
00837 }
00838 else
00839 {
00840
00841 if (lazyInfo->inBlock(atm))
00842 {
00843 lazyInfo->chooseOtherToFlip(atm, newClauses, newClauseWeights);
00844 bool initial = false;
00845 addNewClauses(initial);
00846 }
00847 }
00848
00849 if (lazyInfo->getInBlock())
00850 lazyInfo->setActive(lazyInfo->getOtherAtom());
00851
00852 flipatom(atm);
00853 if (lazyInfo->getInBlock())
00854 {
00855 flipatom(lazyInfo->getOtherAtom());
00856 }
00857
00858 lazyInfo->flipVar(atm);
00859 if (lazyInfo->getInBlock())
00860 lazyInfo->flipVar(lazyInfo->getOtherAtom());
00861
00862
00863 lazyInfo->setInBlock(false);
00864 lazyInfo->setOtherAtom(-1);
00865 }
00866 }
00867
00868
00869 }
00870
00871
00872 void LazySat::addNewClauses(bool initial)
00873 {
00874
00875 allClauses.append(newClauses);
00876 allClauseWeights.append(newClauseWeights);
00877 newClauses.clear();
00878 newClauseWeights.clear();
00879
00880 int i;
00881 int j;
00882
00883 int lit;
00884 int litindex;
00885
00886
00887 int oldnumclause = numclause;
00888 int oldnumatom = numatom;
00889
00890 numatom = lazyInfo->getVarCount();
00891 numclause = allClauses.size();
00892
00893
00894
00895
00896
00897
00898 if(clausemem < numclause )
00899 {
00900
00901 if (2*numclause > clauseLimit)
00902 allocateClauseMemory(clauseLimit);
00903 else
00904 allocateClauseMemory(2*numclause);
00905 }
00906
00907
00908 if(atommem < numatom)
00909 {
00910 allocateAtomMemory(2*numatom);
00911 }
00912
00913
00914 for(int i = oldnumatom + 1; i < numatom + 1; i++)
00915 {
00916 atom[i] = lazyInfo->getVarVal(i);
00917 initatom[i] = atom[i];
00918 lowatom[i] = atom[i];
00919 changed[i] = -BIG;
00920 breakcost[i] = 0;
00921 }
00922
00923 for(int i = 2*oldnumatom + 1; i < 2*numatom + 1; i++)
00924 {
00925 numoccurence[i] = 0;
00926 newnumoccurence[i] = 0;
00927 occurencemem[i] = 0;
00928 }
00929
00930 for(i = oldnumclause; i < numclause; i++)
00931 {
00932 size[i] = 0;
00933 if (costexpected)
00934 {
00935 cost[i] = allClauseWeights[i];
00936 }
00937 else
00938 {
00939
00940 if (allClauseWeights[i] >= 0)
00941 cost[i] = 1;
00942 else
00943 cost[i] = -1;
00944 }
00945
00946 if (clauseFreeStore < MAXLENGTH)
00947 {
00948 clauseStorePtr = clauseFSMgr->getStorePtr();
00949 clauseFreeStore = clauseFSMgr->getBlockSize();
00950 }
00951 clause[i] = clauseStorePtr;
00952
00953 Array<int> *iclause = allClauses[i];
00954 for (j = 0; j < iclause->size(); j++)
00955 {
00956 size[i]++;
00957 if(size[i] > MAXLENGTH)
00958 {
00959 printf("ERROR - clause too long\n");
00960 exit(-1);
00961 }
00962 lit = (*iclause)[j];
00963
00964 if(lit != 0)
00965 {
00966 *(clauseStorePtr++) = lit;
00967 clauseFreeStore--;
00968 numliterals++;
00969 litindex = 2*abs(lit) - LazyUtil::mySign(lit);
00970 newnumoccurence[litindex]++;
00971 }
00972 }
00973 }
00974
00975
00976
00977 for(i = oldnumclause; i < numclause;i++)
00978 {
00979 for (j = 0; j <size[i]; j++)
00980 {
00981 lit = clause[i][j];
00982 litindex = 2*abs(lit) - LazyUtil::mySign(lit);
00983 int totaloccurence = newnumoccurence[litindex] + numoccurence[litindex];
00984
00985 if(occurencemem[litindex] < totaloccurence)
00986 {
00987 int tmpoccurencemem = 2*totaloccurence;
00988 if(atomFreeStore < tmpoccurencemem)
00989 {
00990 atomStorePtr = atomFSMgr->getStorePtr();
00991 atomFreeStore = atomFSMgr->getBlockSize();
00992
00993 }
00994
00995 int *tmpoccurence = atomStorePtr;
00996 atomFreeStore -= tmpoccurencemem;
00997 atomStorePtr += tmpoccurencemem;
00998 for(int k = 0; k < occurencemem[litindex]; k++)
00999 tmpoccurence[k] = occurence[litindex][k];
01000 occurencemem[litindex] = tmpoccurencemem;
01001 occurence[litindex] = tmpoccurence;
01002
01003 }
01004 }
01005 }
01006
01007 for(i = oldnumclause; i < numclause; i++)
01008 {
01009 for(j = 0; j < size[i]; j++)
01010 {
01011 lit = clause[i][j];
01012 if(lit == 0)
01013 continue;
01014 litindex = 2*abs(lit) - LazyUtil::mySign(lit);
01015 occurence[litindex][numoccurence[litindex]] = i;
01016 numoccurence[litindex]++;
01017 newnumoccurence[litindex]--;
01018 }
01019 }
01020 if(!initial)
01021 initializeBreakCost(oldnumclause);
01022
01023 }
01024
01025
01026 void LazySat::trimClauses()
01027 {
01028 Array<int> idxOfDeactivated;
01029 if (!haveDeactivated)
01030 {
01031 haveDeactivated = true;
01032
01033 for (int i = 1; i <= numatom; i++)
01034 if (lazyInfo->isActive(i) && breakcost[i] == 0)
01035 idxOfDeactivated.append(i);
01036 }
01037 else
01038 {
01039 int sumOfBreakCost = 0;
01040
01041 Array<pair<int, int> > costs;
01042 for (int i = 1; i <= numatom; i++)
01043 {
01044 if (lazyInfo->isActive(i))
01045 {
01046 sumOfBreakCost += breakcost[i];
01047 costs.append(pair<int, int>(breakcost[i], i));
01048 }
01049 }
01050
01051 costs.quicksort();
01052
01053 int sumOfDeactivated = 0;
01054 int numOfDeactivated = 0;
01055 for (int i = 0; i < costs.size(); i++)
01056 {
01057 sumOfDeactivated += costs[i].first;
01058
01059 if (sumOfDeactivated * 10 <= sumOfBreakCost)
01060 {
01061 numOfDeactivated++;
01062 idxOfDeactivated.append(costs[i].second);
01063 }
01064 else
01065 break;
01066 }
01067 }
01068
01069 clauseFSMgr->releaseAllStorePtr();
01070 atomFSMgr->releaseAllStorePtr();
01071
01072 deleteClauseMemory();
01073 deleteAtomMemory();
01074
01075 delete clauseFSMgr;
01076 delete atomFSMgr;
01077
01078 clauseStorePtr = NULL;
01079 clauseFreeStore = 0;
01080
01081 atomStorePtr = NULL;
01082 atomFreeStore = 0;
01083
01084 atomFSMgr = new FreeStoreManager(BLOCKSIZE);
01085 clauseFSMgr = new FreeStoreManager(BLOCKSIZE);
01086
01087 numatom = 0;
01088 basenumatom = 0;
01089 numclause = 0;
01090 numliterals = 0;
01091 numfalse = 0;
01092 costofnumfalse = 0;
01093
01094 lazyInfo->removeVars(idxOfDeactivated);
01095
01096 for(int i = 0; i < newClauses.size(); i++)
01097 delete newClauses[i];
01098 newClauses.clear();
01099 newClauseWeights.clear();
01100
01101 for(int i = 0; i < allClauses.size(); i++)
01102 delete allClauses[i];
01103 allClauses.clear();
01104 allClauseWeights.clear();
01105
01106 lazyInfo->getWalksatClauses(newClauses, newClauseWeights);
01107
01108
01109 bool initial = true;
01110 addNewClauses(initial);
01111 }
01112
01113
01114 void LazySat::initializeBreakCost(int startclause)
01115 {
01116
01117 int thetruelit = -1;
01118 for(int i = startclause; i < numclause; i++)
01119 {
01120 numtruelit[i] = 0;
01121 for(int j = 0; j < size[i]; j++)
01122 {
01123
01124 if((clause[i][j] > 0) == atom[abs(clause[i][j])])
01125 {
01126 numtruelit[i]++;
01127 thetruelit = clause[i][j];
01128 }
01129 }
01130
01131
01132 if(numtruelit[i] == 0 && cost[i] >= 0)
01133 {
01134 wherefalse[i] = numfalse;
01135 falseclause[numfalse] = i;
01136 ++numfalse;
01137 costofnumfalse += cost[i];
01138 if (highestcost == cost[i]) {eqhighest = true; numhighest++;}
01139 }
01140
01141 else if(numtruelit[i] > 0 && cost[i] < 0)
01142 {
01143 wherefalse[i] = numfalse;
01144 falseclause[numfalse] = i;
01145 ++numfalse;
01146 costofnumfalse += abs(cost[i]);
01147 if (highestcost == abs(cost[i])) {eqhighest = true; numhighest++;}
01148 }
01149
01150 else if (numtruelit[i] == 1 && cost[i] >= 0)
01151 {
01152 breakcost[abs(thetruelit)] += cost[i];
01153 }
01154
01155 else if (numtruelit[i] == 0 && cost[i] < 0)
01156 {
01157 for(int j = 0; j < size[i]; j++)
01158 {
01159 breakcost[abs(clause[i][j])] += abs(cost[i]);
01160 }
01161 }
01162 }
01163
01164 }
01165
01166
01167 void LazySat::allocateClauseMemory(int allocCount)
01168 {
01169
01170 int **tmpclause = new int*[allocCount];
01171 int *tmpcost = new int[allocCount];
01172 int *tmpsize = new int[allocCount];
01173
01174 int *tmpfalseclause = new int[allocCount];
01175 int *tmpwherefalse = new int[allocCount];
01176 int *tmpnumtruelit = new int[allocCount];
01177
01178 for(int i = 0; i < clausemem; i++)
01179 {
01180 tmpclause[i] = clause[i];
01181 tmpcost[i] = cost[i];
01182 tmpsize[i] = size[i];
01183
01184 tmpfalseclause[i] = falseclause[i];
01185 tmpwherefalse[i] = wherefalse[i];
01186 tmpnumtruelit[i] = numtruelit[i];
01187 }
01188
01189 deleteClauseMemory();
01190
01191 clause = tmpclause;
01192 cost = tmpcost;
01193 size = tmpsize;
01194
01195 falseclause = tmpfalseclause;
01196 wherefalse = tmpwherefalse;
01197 numtruelit = tmpnumtruelit;
01198
01199 clausemem = allocCount;
01200 }
01201
01202
01203 void LazySat::allocateAtomMemory(int allocCount)
01204 {
01205
01206 int **tmpoccurence = new int*[2*allocCount+1];
01207 int *tmpnumoccurence = new int[2*allocCount+1];
01208 int *tmpnewnumoccurence = new int[2*allocCount+1];
01209 int *tmpoccurencemem = new int[2*allocCount+1];
01210
01211 int *tmpatom = new int[allocCount+1];
01212 int *tmpinitatom = new int[allocCount+1];
01213 int *tmplowatom = new int[allocCount+1];
01214 int *tmpchanged = new int[allocCount+1];
01215 int *tmpbreakcost = new int[allocCount+1];
01216
01217 if(atommem > 0)
01218 {
01219 for(int i = 0; i < 2*atommem + 1; i++)
01220 {
01221 tmpoccurence[i] = occurence[i];
01222 tmpnumoccurence[i] = numoccurence[i];
01223 tmpnewnumoccurence[i] = newnumoccurence[i];
01224 tmpoccurencemem[i] = occurencemem[i];
01225 }
01226
01227 for(int i = 0; i < atommem + 1; i++)
01228 {
01229 tmpatom[i] = atom[i];
01230 tmpinitatom[i] = initatom[i];
01231 tmplowatom[i] = lowatom[i];
01232 tmpchanged[i] = changed[i];
01233 tmpbreakcost[i] = breakcost[i];
01234 }
01235 }
01236
01237 deleteAtomMemory();
01238
01239 occurence = tmpoccurence;
01240 numoccurence = tmpnumoccurence;
01241 newnumoccurence = tmpnewnumoccurence;
01242 occurencemem = tmpoccurencemem;
01243
01244 atom = tmpatom;
01245 initatom = tmpinitatom;
01246 lowatom = tmplowatom;
01247 changed = tmpchanged;
01248 breakcost = tmpbreakcost;
01249
01250 atommem = allocCount;
01251 }
01252
01253
01254 void LazySat::deleteClauseMemory()
01255 {
01256 if(clausemem == 0)
01257 return;
01258
01259 delete [] clause;
01260 delete [] cost;
01261 delete [] size;
01262 delete [] falseclause;
01263 delete [] wherefalse;
01264 delete [] numtruelit;
01265
01266 clausemem = 0;
01267 }
01268
01269 void LazySat::deleteAtomMemory()
01270 {
01271 if(atommem == 0)
01272 return;
01273
01274 delete [] occurence;
01275 delete [] numoccurence;
01276 delete [] newnumoccurence;
01277 delete [] occurencemem;
01278
01279 delete [] atom;
01280 delete [] initatom;
01281 delete [] lowatom;
01282 delete [] changed;
01283 delete [] breakcost;
01284
01285 atommem = 0;
01286 }
01287
01288
01289 void LazySat::flipatom(int toflip)
01290 {
01291 int i, j;
01292 int litindex;
01293 register int cli;
01294 register int lit;
01295 int numocc;
01296 register int sz;
01297 register int * litptr;
01298 int * occptr;
01299
01300 changed[toflip] = numflip;
01301 atom[toflip] = 1 - atom[toflip];
01302
01303 int sign, oppsign;
01304
01305 sign = atom[toflip];
01306
01307 oppsign = sign ^ 1;
01308
01309 litindex = 2*toflip - oppsign;
01310 numocc = numoccurence[litindex];
01311 occptr = occurence[litindex];
01312
01313 for(i = 0; i < numocc; i++)
01314 {
01315 cli = *(occptr++);
01316
01317
01318 if (cost[cli] < 0)
01319 {
01320
01321 if (--numtruelit[cli] == 0)
01322 {
01323 numfalse--;
01324 costofnumfalse -= abs(cost[cli]);
01325 falseclause[wherefalse[cli]] = falseclause[numfalse];
01326 wherefalse[falseclause[numfalse]] = wherefalse[cli];
01327
01328 if (abs(cost[cli]) == highestcost)
01329 { numhighest--; if (numhighest == 0) eqhighest = false; }
01330
01331
01332 sz = size[cli];
01333 litptr = clause[cli];
01334 for(j = 0; j < sz; j++)
01335 {
01336 lit = *(litptr++);
01337 breakcost[abs(lit)] += abs(cost[cli]);
01338 }
01339 }
01340 }
01341
01342 else
01343 {
01344 if (--numtruelit[cli] == 0)
01345 {
01346 falseclause[numfalse] = cli;
01347 wherefalse[cli] = numfalse;
01348 numfalse++;
01349 costofnumfalse += cost[cli];
01350
01351 breakcost[toflip] -= cost[cli];
01352 if (cost[cli] == highestcost) { eqhighest = true; numhighest++; }
01353 }
01354 else if (numtruelit[cli] == 1)
01355 {
01356
01357 sz = size[cli];
01358 litptr = clause[cli];
01359 for (j = 0; j < sz; j++)
01360 {
01361
01362 lit = *(litptr++);
01363 if((lit > 0) == atom[abs(lit)])
01364 {
01365 breakcost[abs(lit)] += cost[cli];
01366 break;
01367 }
01368 }
01369 }
01370 }
01371 }
01372
01373 litindex = 2*toflip - sign;
01374 numocc = numoccurence[litindex];
01375 occptr = occurence[litindex];
01376
01377 for(i = 0; i < numocc; i++)
01378 {
01379 cli = *(occptr++);
01380
01381
01382 if (cost[cli] < 0)
01383 {
01384
01385 if (++numtruelit[cli] == 1)
01386 {
01387 wherefalse[cli] = numfalse;
01388 falseclause[numfalse] = cli;
01389 ++numfalse;
01390 costofnumfalse += abs(cost[cli]);
01391 if (highestcost == abs(cost[cli])) {eqhighest = true; numhighest++;}
01392
01393
01394 sz = size[cli];
01395 litptr = clause[cli];
01396 for(j = 0; j < sz; j++)
01397 {
01398 lit = *(litptr++);
01399 breakcost[abs(lit)] -= abs(cost[cli]);
01400 }
01401 }
01402 }
01403
01404 else
01405 {
01406 if (++numtruelit[cli] == 1)
01407 {
01408 numfalse--;
01409 costofnumfalse -= cost[cli];
01410 falseclause[wherefalse[cli]] = falseclause[numfalse];
01411 wherefalse[falseclause[numfalse]] = wherefalse[cli];
01412
01413
01414 breakcost[toflip] += cost[cli];
01415 if (cost[cli] == highestcost)
01416 { numhighest--; if (numhighest==0) eqhighest = false; }
01417 }
01418 else if (numtruelit[cli] == 2)
01419 {
01420
01421
01422 sz = size[cli];
01423 litptr = clause[cli];
01424 for (j = 0; j < sz; j++)
01425 {
01426
01427 lit = *(litptr++);
01428 if(((lit > 0) == atom[abs(lit)]) &&
01429 (toflip != abs(lit)) )
01430 {
01431 breakcost[abs(lit)] -= cost[cli];
01432 break;
01433 }
01434 }
01435 }
01436 }
01437 }
01438 }
01439
01440
01441 long LazySat::super(int i)
01442 {
01443 long power;
01444 int k;
01445
01446 if (i <= 0)
01447 {
01448 fprintf(stderr, "bad argument super(%d)\n", i);
01449 exit(1);
01450 }
01451
01452 k = 1;
01453 power = 2;
01454 while (power < (i+1))
01455 {
01456 k += 1;
01457 power *= 2;
01458 }
01459 if (power == (i+1)) return (power/2);
01460 return (super(i - (power/2) + 1));
01461 }
01462
01463
01464 void LazySat::scanone(int argc, char *argv[], int i, int *varptr)
01465 {
01466 if (i >= argc || sscanf(argv[i],"%i",varptr)!=1)
01467 {
01468 fprintf(stderr, "Bad argument %s\n", i<argc ? argv[i] : argv[argc-1]);
01469 exit(-1);
01470 }
01471 }
01472
01473 void LazySat::print_false_clauses_cost(long int lowbad)
01474 {
01475 int i, j;
01476 bool bad;
01477 int lit, sign;
01478
01479 printf("Unsatisfied pos. clauses and satisfied neg. clauses:\n");
01480 for (i = 0; i < numclause; i++)
01481 {
01482
01483 if (cost[i] < 0)
01484 bad = false;
01485
01486 else
01487 bad = true;
01488
01489 for (j = 0; j < size[i]; j++)
01490 {
01491 lit = clause[i][j];
01492 sign = lit > 0 ? 1 : 0;
01493
01494 if ( lowatom[abs(lit)] == sign )
01495 {
01496
01497 if (cost[i] < 0)
01498 bad = true;
01499
01500 else
01501 bad = false;
01502 break;
01503 }
01504 }
01505
01506 if (bad)
01507 {
01508 printf("Cost %i ", cost[i]);
01509 for (j = 0; j < size[i]; j++)
01510 {
01511 printf("%d ", clause[i][j]);
01512 }
01513 printf("0\n");
01514 }
01515 }
01516 printf("End unsatisfied pos. clauses and satisfied neg. clauses\n");
01517 }
01518
01519
01520 int LazySat::countunsat(void)
01521 {
01522 int i, j, unsat, lit, sign;
01523 bool bad;
01524
01525 unsat = 0;
01526 for (i = 0; i < numclause; i++)
01527 {
01528
01529 if (cost[i] < 0)
01530 bad = false;
01531
01532 else
01533 bad = true;
01534
01535 for (j = 0; j < size[i]; j++)
01536 {
01537 lit = clause[i][j];
01538 sign = lit > 0 ? 1 : 0;
01539 if ( atom[abs(lit)] == sign )
01540 {
01541
01542 if (cost[i] < 0)
01543 bad = true;
01544
01545 else
01546 bad = false;
01547 break;
01548 }
01549 }
01550 if (bad) unsat++;
01551 }
01552 return unsat;
01553 }
01554
01555 void LazySat::countlowunsatcost(int * unsatcostptr, int * worstcostptr)
01556 {
01557 int i, j, lit, sign, unsatcost, worstcost;
01558 bool bad;
01559
01560 unsatcost = 0;
01561 worstcost = 0;
01562 for (i = 0; i < numclause; i++)
01563 {
01564
01565 if (cost[i] < 0)
01566 bad = false;
01567
01568 else
01569 bad = true;
01570
01571 for (j = 0; j < size[i]; j++)
01572 {
01573 lit = clause[i][j];
01574 sign = lit > 0 ? 1 : 0;
01575 if ( lowatom[abs(lit)] == sign )
01576 {
01577
01578 if (cost[i] < 0)
01579 bad = true;
01580
01581 else
01582 bad = false;
01583 break;
01584 }
01585 }
01586 if (bad)
01587 {
01588 unsatcost += abs(cost[i]);
01589 if (abs(cost[i]) > worstcost) worstcost = abs(cost[i]);
01590 }
01591 }
01592 * unsatcostptr = unsatcost;
01593 * worstcostptr = worstcost;
01594 return;
01595 }
01596
01597
01598 double LazySat::elapsed_seconds(void)
01599 {
01600 double answer;
01601
01602 static struct rusage prog_rusage;
01603 static long prev_rusage_seconds = 0;
01604 static long prev_rusage_micro_seconds = 0;
01605
01606 getrusage(0, &prog_rusage);
01607 answer = (double)(prog_rusage.ru_utime.tv_sec - prev_rusage_seconds)
01608 + ((double)(prog_rusage.ru_utime.tv_usec - prev_rusage_micro_seconds)) /
01609 1000000.0 ;
01610 prev_rusage_seconds = prog_rusage.ru_utime.tv_sec ;
01611 prev_rusage_micro_seconds = prog_rusage.ru_utime.tv_usec ;
01612 return answer;
01613 }
01614
01615
01616 void LazySat::print_low_assign(long int lowbad)
01617 {
01618 int i, j;
01619
01620 cout<<"Begin assign with lowest # bad = "<<lowbad<<" (atoms assigned true)\n";
01621 j = 1;
01622 for (i = 1; i <= numatom; i++)
01623 {
01624 if (lowatom[i]>0)
01625 {
01626 printf(" %d", i);
01627 if (j++ % 10 == 0) printf("\n");
01628 }
01629 }
01630 if ((j-1) % 10 != 0) printf("\n");
01631 printf("End assign\n");
01632 }
01633
01634 void LazySat::save_low_assign(void)
01635 {
01636 for (int i = 1; i <= numatom; i++)
01637 lowatom[i] = atom[i];
01638 }
01639
01640
01641 void LazySat::printClause(int cl)
01642 {
01643 cout<<"(";
01644 for(int i = 0; i < size[cl]; i++)
01645 {
01646 cout << clause[cl][i];
01647 if (i != size[cl] - 1)
01648 cout <<",";
01649 }
01650 cout<<")"<<endl;
01651 }
01652
01653 int LazySat::selecthigh(int high)
01654 {
01655
01656 int counter = 0;
01657 int i = 0;
01658 while ((i < numfalse) && (counter < high))
01659 {
01660 if (abs(cost[falseclause[i]]) == highestcost)
01661 counter++;
01662 i++;
01663 }
01664
01665
01666 return(falseclause[i-1]);
01667 }
01668
01669
01670 int LazySat::pickrandom(int *numbreak, int clausesize, int tofix)
01671
01672 {
01673 return(random()%clausesize);
01674 }
01675
01676 int LazySat::pickproductsum(int *numbreak, int clausesize, int tofix)
01677
01678
01679 {
01680 int i;
01681 int weight[MAXLENGTH];
01682 int tochange;
01683 int totalproduct = 1;
01684 int totalsum = 0;
01685
01686 if(clausesize == 1)
01687 return(0);
01688 if((tochange = pickzero(numbreak,clausesize)) != NOVALUE)
01689 return(tochange);
01690 for(i = 0; i < clausesize; i++)
01691 {
01692 totalproduct *= numbreak[i];
01693 totalsum += numbreak[i];
01694 }
01695 for(i = 0; i < clausesize; i++)
01696 {
01697 weight[i] = (totalproduct/numbreak[i])*
01698 (totalsum-numbreak[i]);
01699 }
01700 return(pickweight(weight,clausesize));
01701 }
01702
01703 int LazySat::pickreciprocal(int *numbreak, int clausesize, int tofix)
01704
01705 {
01706 int i;
01707 int weight[MAXLENGTH];
01708 int tochange;
01709 int totalproduct = 1;
01710
01711 if(clausesize == 1)
01712 return(0);
01713 if((tochange = pickzero(numbreak,clausesize)) != NOVALUE)
01714 return(tochange);
01715 for(i = 0;i < clausesize;i++)
01716 totalproduct *= numbreak[i];
01717 for(i = 0;i < clausesize;i++)
01718 weight[i] = (totalproduct/numbreak[i]);
01719 return(pickweight(weight,clausesize));
01720 }
01721
01722 int LazySat::pickadditive(int *numbreak, int clausesize, int tofix)
01723
01724 {
01725 int i;
01726 int weight[MAXLENGTH];
01727 int tochange;
01728 int totalsum = 0;
01729
01730 if(clausesize == 1)
01731 return(0);
01732 if((tochange = pickzero(numbreak,clausesize)) != NOVALUE)
01733 return(tochange);
01734 for(i = 0; i < clausesize;i++)
01735 totalsum += numbreak[i];
01736 for(i = 0; i < clausesize;i++)
01737 weight[i] = (totalsum-numbreak[i]);
01738 return(pickweight(weight,clausesize));
01739 }
01740
01741 int LazySat::pickbest(int *numbreak, int clausesize, int tofix)
01742 {
01743 int i;
01744 int best[MAXLENGTH];
01745 int numbest;
01746 int bestvalue;
01747
01748 numbest = 0;
01749 bestvalue = INT_MAX;
01750
01751 for (i = 0; i < clausesize; i++)
01752 {
01753 if (numbreak[i] <= bestvalue)
01754 {
01755 if (numbreak[i] < bestvalue) numbest = 0;
01756 bestvalue = numbreak[i];
01757 best[numbest++] = i;
01758 }
01759 }
01760
01761 if (bestvalue > 0 && (random()%denominator < numerator))
01762 {
01763 if (!hard || abs(cost[tofix]) >= highestcost)
01764 return(random()%clausesize);
01765
01766
01767 numbest = 0;
01768 for (i = 0; i < clausesize; i++)
01769 {
01770 if (numbreak[i] < highestcost)
01771 {
01772 best[numbest++] = i;
01773 }
01774 }
01775
01776 if (numbest == 0) { return(random()%clausesize); }
01777 }
01778
01779 if (numbest == 1) return best[0];
01780
01781
01782 if (numbest == 0) { return(random()%clausesize); }
01783
01784 return(best[random()%numbest]);
01785 }
01786
01787
01788 int LazySat::picktabu(int *numbreak,int clausesize, int tofix)
01789 {
01790 int i;
01791 int best[MAXLENGTH];
01792 int numbest;
01793 int bestvalue;
01794
01795 numbest = 0;
01796 bestvalue = BIG;
01797
01798 if (numerator>0 && (random()%denominator < numerator))
01799 {
01800 for (i = 0; i < clausesize; i++)
01801 {
01802 if ((tabu_length < numflip - changed[abs(clause[tofix][i])]) ||
01803 numbreak[i] == 0)
01804 {
01805 if (numbreak[i]==0) numbest=0;
01806 best[numbest++] = i;
01807 }
01808 }
01809 }
01810 else
01811 {
01812 for (i = 0; i < clausesize; i++)
01813 {
01814 if (numbreak[i] <= bestvalue &&
01815 ((tabu_length < numflip - changed[abs(clause[tofix][i])]) ||
01816 numbreak[i] == 0))
01817 {
01818 if (numbreak[i] < bestvalue) numbest=0;
01819 bestvalue = numbreak[i];
01820 best[numbest++] = i;
01821 }
01822 }
01823 }
01824
01825 if (numbest == 0) return NOVALUE;
01826 if (numbest == 1) return best[0];
01827 return (best[random()%numbest]);
01828 }
01829
01830 int LazySat::pickexponential(int *numbreak,int clausesize, int tofix)
01831 {
01832 int i;
01833 int weight[MAXLENGTH];
01834 int tochange;
01835
01836 if(clausesize == 1)
01837 return(0);
01838 if((tochange = pickzero(numbreak,clausesize)) != NOVALUE)
01839 return(tochange);
01840 for(i = 0; i < clausesize; i++)
01841 weight[i] = 2*2*2*2*2*2*2*2*2*2*2*2*2*2;
01842 for(i = 0; i < clausesize; i++)
01843 {
01844 weight[i] >>= numbreak[i];
01845 }
01846
01847 return(pickweight(weight,clausesize));
01848 }
01849
01850 int LazySat::pickzero(int *numbreak,int clausesize)
01851 {
01852 int i;
01853 int numzero = 0;
01854 int select;
01855
01856 for(i = 0; i < clausesize; i++)
01857 {
01858 if(numbreak[i] == 0)
01859 numzero++;
01860 }
01861 if(numzero == 0)
01862 return(NOVALUE);
01863 select = random()%numzero;
01864 for(i = 0;select >= 0; i++)
01865 {
01866 if(numbreak[i] == 0)
01867 select--;
01868 }
01869 return(i-1);
01870 }
01871
01872 int LazySat::pickweight(int *weight,int clausesize)
01873 {
01874 int i;
01875 int total = 0;
01876 int select;
01877 int subtotal = 0;
01878
01879 for(i = 0; i < clausesize; i++)
01880 total += weight[i];
01881 if(total == 0)
01882 return(random()%clausesize);
01883 select = random()%total;
01884 for(i = 0; subtotal <= select; i++)
01885 subtotal += weight[i];
01886 return(i-1);
01887 }
01888
01889
01890 bool LazySat::simAnnealing()
01891 {
01892
01893 if (lazyInfo->getNumDBAtoms() == 0)
01894 {
01895 numnullflip++;
01896 return true;
01897 }
01898
01899 int toflip = -1;
01900
01901 int change;
01902
01903 if (numfalse == 0 || (random() % 100 < saRatio && !latesa))
01904 {
01905 bool initial = false;
01906
01907 if (lazyInfo->activateRandomAtom(newClauses, newClauseWeights, toflip))
01908 addNewClauses(initial);
01909
01910
01911 if ((haveDeactivated && lazyInfo->isDeactivated(toflip)) ||
01912 (lazyInfo->inBlockWithEvidence(toflip)))
01913 {
01914 numnullflip++;
01915 return true;
01916 }
01917
01918
01919
01920
01921 if(!lazyInfo->isActive(toflip))
01922 {
01923 change = -lazyInfo->getUnSatCostWhenFlipped(toflip, newClauses, newClauseWeights);
01924 bool initial = false;
01925 addNewClauses(initial);
01926 lazyInfo->setActive(toflip);
01927 }
01928 else
01929 {
01930 change = -breakcost[toflip];
01931 }
01932
01933
01934
01935 if (change >= 0 ||
01936 random() <= exp(change / (temperature / 100.0)) * RAND_MAX)
01937 {
01938 if(!lazyInfo->isActive(toflip))
01939 {
01940 lazyInfo->getWalksatClausesWhenFlipped(toflip, newClauses, newClauseWeights);
01941
01942 bool initial = false;
01943 addNewClauses(initial);
01944 lazyInfo->setActive(toflip);
01945 }
01946 else
01947 {
01948
01949 if (lazyInfo->inBlock(toflip))
01950 {
01951 lazyInfo->chooseOtherToFlip(toflip, newClauses, newClauseWeights);
01952 bool initial = false;
01953 addNewClauses(initial);
01954 }
01955 }
01956
01957 if (lazyInfo->getInBlock())
01958 lazyInfo->setActive(lazyInfo->getOtherAtom());
01959
01960 flipatom(toflip);
01961 if (lazyInfo->getInBlock())
01962 {
01963 flipatom(lazyInfo->getOtherAtom());
01964 }
01965
01966 lazyInfo->flipVar(toflip);
01967 if (lazyInfo->getInBlock())
01968 lazyInfo->flipVar(lazyInfo->getOtherAtom());
01969
01970
01971 lazyInfo->setInBlock(false);
01972 lazyInfo->setOtherAtom(-1);
01973 }
01974 else numnullflip++;
01975
01976 return true;
01977 }
01978 else
01979 return false;
01980 }
01981
01982 void LazySat::undoFixedAtoms()
01983 {
01984
01985
01986
01987 for (int i = 1; i < maxFixedAtoms; i++)
01988 {
01989 if (fixedAtoms_[i])
01990 {
01991 lazyInfo->setEvidence(i, false);
01992 lazyInfo->incrementNumDBAtoms();
01993 fixedAtoms_[i] = false;
01994 }
01995 }
01996
01997
01998
01999 }
02000
02001
02002
02003
02004
02005 void LazySat::initFixedAtoms(Array<Array<int> *> &clauses,
02006 Array<int> &clauseWeights)
02007 {
02008
02009
02010
02011
02012
02013
02014 bool done = false;
02015 while (!done)
02016 {
02017 done = true;
02018
02019
02020 for (int i = 0; i < clauses.size(); i++)
02021 {
02022 Array<int>* clause = clauses[i];
02023
02024
02025 if (clause->size() < 1)
02026 {
02027
02028
02029 delete clauses.removeItemFastDisorder(i);
02030 clauseWeights.removeItemFastDisorder(i);
02031 i--;
02032 continue;
02033 }
02034
02035
02036 if (clauseWeights[i] < 0)
02037 {
02038 for (int j = 0; j < clause->size(); j++)
02039 {
02040 int atm = (*clause)[j];
02041
02042 if (!fixedAtoms_[abs(atm)])
02043 {
02044 lazyInfo->setInactive(abs(atm));
02045 lazyInfo->setEvidence(abs(atm), true);
02046 lazyInfo->decrementNumDBAtoms();
02047 done = false;
02048 fixedAtoms_[abs(atm)] = true;
02049
02050 if (atm < 0)
02051 {
02052 lazyInfo->setVarVal(abs(atm), true);
02053 }
02054
02055 else if (atm > 0)
02056 {
02057 lazyInfo->setVarVal(abs(atm), false);
02058 }
02059 }
02060 }
02061
02062 delete clauses.removeItemFastDisorder(i);
02063 clauseWeights.removeItemFastDisorder(i);
02064 i--;
02065 continue;
02066 }
02067
02068
02069 if (clause->size() == 1)
02070 {
02071 int atm = (*clause)[0];
02072
02073
02074 if (!fixedAtoms_[abs(atm)])
02075 {
02076 lazyInfo->setInactive(abs(atm));
02077 lazyInfo->setEvidence(abs(atm), true);
02078 lazyInfo->decrementNumDBAtoms();
02079 done = false;
02080
02081 fixedAtoms_[abs(atm)] = true;
02082
02083
02084 if ((clauseWeights[i] > 0 && atm > 0) ||
02085 (clauseWeights[i] < 0 && atm < 0))
02086 {
02087 lazyInfo->setVarVal(abs(atm), true);
02088 }
02089
02090
02091 else if ((clauseWeights[i] > 0 && atm < 0) ||
02092 (clauseWeights[i] < 0 && atm > 0))
02093 {
02094 lazyInfo->setVarVal(abs(atm), false);
02095 }
02096 }
02097
02098 delete clauses.removeItemFastDisorder(i);
02099 clauseWeights.removeItemFastDisorder(i);
02100 i--;
02101
02102
02103 continue;
02104 }
02105
02106
02107 for (int j = 0; j < clause->size(); j++)
02108 {
02109 int atm = (*clause)[j];
02110 if (lazyInfo->getEvidence(abs(atm)))
02111 {
02112 bool sense = (atm > 0);
02113 TruthValue tv = lazyInfo->getVarVal(abs(atm)) ? TRUE : FALSE;
02114
02115 if (Database::sameTruthValueAndSense(tv, sense))
02116 {
02117
02118
02119 delete clauses.removeItemFastDisorder(i);
02120 clauseWeights.removeItemFastDisorder(i);
02121 i--;
02122 break;
02123 }
02124
02125 else
02126 {
02127 clause->removeItemFastDisorder(j);
02128 j--;
02129 done = false;
02130 }
02131 }
02132
02133
02134
02135 }
02136 }
02137 }
02138
02139
02140
02141
02142
02143
02144
02145 }