#include <maxwalksat.h>
Inheritance diagram for MaxWalkSat:
Public Member Functions | |
MaxWalkSat (VariableState *state, int seed, const bool &trackClauseTrueCnts, MaxWalksatParams *params) | |
Constructor: user-set parameters are set. | |
~MaxWalkSat () | |
Destructor (destructors from superclasses are called). | |
void | init () |
Initializes the MaxWalkSat algorithm. | |
void | infer () |
Performs the given number of MaxWalkSat inference tries. | |
const int | getHeuristic () |
void | setHeuristic (const int &heuristic) |
int | getMaxSteps () |
void | setMaxSteps (const int &maxSteps) |
void | setPrintInfo (const bool &printInfo) |
const bool | getPrintInfo () |
Protected Member Functions | |
void | flipAtom (int toFlip) |
Flips the truth value of an atom and marks this iteration as the last time it was flipped. | |
int | pickRandom () |
Pick a random atom in a random unsatisfied pos. | |
int | pickBest () |
Pick the best atom (clauses made satisfied - clauses made unsatisfied) in a random unsatisfied clause. | |
int | pickTabu () |
Pick an atom from a random unsatisfied clause based on the tabu heuristic. | |
int | pickSS () |
Pick an atom according to the SampleSat heuristic. | |
long double | calculateImprovement (const int &atomIdx, Array< int > &canNotFlip, Array< int > &candidateBlockedVars, Array< int > &othersToFlip, int &blockIdx) |
Calculates the improvement (makecost - breakcost) by flipping an atom. | |
void | reconstructLowState () |
Reconstructs the state with the lowest cost by flipping atoms back to their value in this state. |
This code is based on the MaxWalkSat package of Kautz et al. and SampleSat by Wei et al.
Walksat is achieved by using unit weights (1 and -1) in the clauses in the state and setting the target cost to 0.
SampleSat is achieved by using unit weights (1 and -1) in the clauses in the state and setting the target cost to 0 and the heuristic to SS.
Definition at line 94 of file maxwalksat.h.
void MaxWalkSat::init | ( | ) | [inline, virtual] |
Initializes the MaxWalkSat algorithm.
A random assignment is given to the atoms and the state is initialized.
Implements Inference.
Definition at line 161 of file maxwalksat.h.
References SAT::changed_, VariableState::getNumAtoms(), Array< Type >::growToSize(), VariableState::initRandom(), Array< Type >::shrinkToSize(), Array< Type >::size(), and Inference::state_.
Referenced by infer(), SimulatedTempering::init(), MCSAT::init(), and GibbsSampler::init().
00162 { 00163 // Init changed array if using tabu 00164 if (heuristic_ == TABU || heuristic_ == SS) 00165 { 00166 int numAtoms = state_->getNumAtoms(); 00167 if (changed_.size() != numAtoms + 1) 00168 { 00169 if (changed_.size() < numAtoms + 1) 00170 changed_.growToSize(numAtoms + 1); 00171 else 00172 changed_.shrinkToSize(numAtoms + 1); 00173 } 00174 for (int i = 1; i <= numAtoms; i++) 00175 changed_[i] = -(tabuLength_ + 1); 00176 } 00177 state_->initRandom(); 00178 }
void MaxWalkSat::flipAtom | ( | int | toFlip | ) | [inline, protected] |
Flips the truth value of an atom and marks this iteration as the last time it was flipped.
toFlip | Index of atom to flip. |
Definition at line 333 of file maxwalksat.h.
References SAT::changed_, VariableState::flipAtom(), VariableState::getNumAtoms(), Array< Type >::growToSize(), SAT::numFlips_, and Inference::state_.
Referenced by infer().
00334 { 00335 //if (mwsdebug) cout << "Entering MaxWalkSat::flipAtom" << endl; 00336 if (toFlip == NOVALUE) 00337 return; 00338 00339 // Flip the atom in the state 00340 state_->flipAtom(toFlip, inBlock_); 00341 // Mark this flip as last time atom was changed if tabu is used 00342 if (heuristic_ == TABU || heuristic_ == SS) 00343 { 00344 changed_.growToSize(state_->getNumAtoms() + 1, -(tabuLength_ + 1)); 00345 changed_[toFlip] = numFlips_; 00346 } 00347 00348 if (lazyLowState_) 00349 { 00350 // Mark this variable as flipped since last low state. If already 00351 // present, then it has been flipped back to its value in the low 00352 // state and we can remove it. 00353 if (varsFlippedSinceLowState_.find(toFlip) != 00354 varsFlippedSinceLowState_.end()) 00355 { 00356 if (mwsdebug) 00357 { 00358 //cout << "Atom " << toFlip << " has been flipped since low state, " 00359 // << "so removing it" << endl; 00360 } 00361 varsFlippedSinceLowState_.erase(toFlip); 00362 } 00363 else 00364 { 00365 if (mwsdebug) 00366 { 00367 //cout << "Atom " << toFlip << " not flipped since low state, " 00368 // << "so adding it" << endl; 00369 } 00370 varsFlippedSinceLowState_.insert(toFlip); 00371 } 00372 } 00373 //if (mwsdebug) cout << "Leaving MaxWalkSat::flipAtom" << endl; 00374 }
int MaxWalkSat::pickRandom | ( | ) | [inline, protected] |
Pick a random atom in a random unsatisfied pos.
clause or a random true literal in a random satsified neg. clause to flip.
Definition at line 382 of file maxwalksat.h.
References VariableState::activateAtom(), Domain::getBlockEvidence(), VariableState::getBlockIndex(), Domain::getBlockSize(), VariableState::getDomain(), VariableState::getImprovementByFlipping(), VariableState::getIndexOfAtomInRandomFalseClause(), VariableState::getIndexOfGroundPredicate(), Domain::getPredInBlock(), Domain::getRandomPredInBlock(), VariableState::getValueOfAtom(), and Inference::state_.
Referenced by MaxWalkSat(), and pickBest().
00383 { 00384 //if (mwsdebug) cout << "Entering MaxWalkSat::pickRandom" << endl; 00385 assert(inBlock_ == -1); 00386 int atomIdx = state_->getIndexOfAtomInRandomFalseClause(); 00387 if (atomIdx == NOVALUE) return NOVALUE; 00388 if (state_->getImprovementByFlipping(atomIdx) == -LDBL_MAX) return NOVALUE; 00389 00390 // if false => fix atoms 00391 bool ignoreActivePreds = false; 00392 bool groundOnly = false; 00393 if (!state_->activateAtom(atomIdx, ignoreActivePreds, groundOnly)) 00394 return NOVALUE; 00395 00396 // If atom is in a block, then another one has to be picked 00397 int blockIdx = state_->getBlockIndex(atomIdx - 1); 00398 if (blockIdx >= 0) 00399 { 00400 // Atom is in a block 00401 // If evidence atom exists or in block of size 1, then can not flip 00402 if (state_->getDomain()->getBlockEvidence(blockIdx) || 00403 state_->getDomain()->getBlockSize(blockIdx) == 1) 00404 return NOVALUE; 00405 else 00406 { 00407 //Dealing with atom in a block 00408 int blockSize = state_->getDomain()->getBlockSize(blockIdx); 00409 // 0->1: choose atom in block which is already 1 00410 if (state_->getValueOfAtom(atomIdx) == 0) 00411 { 00412 for (int i = 0; i < blockSize; i++) 00413 { 00414 const Predicate* pred = 00415 state_->getDomain()->getPredInBlock(i, blockIdx); 00416 GroundPredicate* gndPred = new GroundPredicate((Predicate*)pred); 00417 00418 int idx = state_->getIndexOfGroundPredicate(gndPred); 00419 00420 delete gndPred; 00421 delete pred; 00422 00423 // Pred is in the state 00424 if (idx >= 0) 00425 { 00426 if (state_->getValueOfAtom(idx + 1) == 1) 00427 { 00428 inBlock_ = blockIdx; 00429 flipInBlock_ = idx + 1; 00430 return atomIdx; 00431 } 00432 } 00433 } 00434 } 00435 // 1->0: choose to flip the other randomly 00436 else 00437 { 00438 bool ok = false; 00439 while (!ok) 00440 { 00441 const Predicate* pred = 00442 state_->getDomain()->getRandomPredInBlock(blockIdx); 00443 GroundPredicate* gndPred = new GroundPredicate((Predicate*)pred); 00444 00445 int idx = state_->getIndexOfGroundPredicate(gndPred); 00446 00447 delete gndPred; 00448 delete pred; 00449 00450 if (idx + 1 != atomIdx) 00451 { 00452 inBlock_ = blockIdx; 00453 flipInBlock_ = idx + 1; 00454 return atomIdx; 00455 } 00456 } 00457 } 00458 } 00459 } 00460 //if (mwsdebug) cout << "Leaving MaxWalkSat::pickRandom" << endl; 00461 return atomIdx; 00462 }
int MaxWalkSat::pickBest | ( | ) | [inline, protected] |
Pick the best atom (clauses made satisfied - clauses made unsatisfied) in a random unsatisfied clause.
Definition at line 470 of file maxwalksat.h.
References VariableState::activateAtom(), Array< Type >::append(), calculateImprovement(), Array< Type >::clear(), Array< Type >::find(), VariableState::getAtomInClause(), VariableState::getClauseCost(), VariableState::getClauseSize(), VariableState::getRandomFalseClauseIndex(), Array< Type >::growToSize(), VariableState::isFixedAtom(), pickRandom(), and Inference::state_.
Referenced by MaxWalkSat().
00471 { 00472 //if (mwsdebug) cout << "Entering MaxWalkSat::pickBest" << endl; 00473 // With prob. do a noisy pick 00474 bool noisyPick = (numerator_ > 0 && random()%denominator_ < numerator_); 00475 if (noisyPick) 00476 return pickRandom(); 00477 00478 assert(inBlock_ == -1); 00479 // Clause to fix picked at random 00480 int toFix = state_->getRandomFalseClauseIndex(); 00481 if (toFix == NOVALUE) return NOVALUE; 00482 00483 if (mwsdebug) cout << "Looking to fix clause " << toFix << endl; 00484 00485 int clauseSize = state_->getClauseSize(toFix); 00486 long double cost = state_->getClauseCost(toFix); 00487 00488 long double improvement; 00489 // Arrays to hold information on candidate flips 00490 Array<Array<int> > canNotFlip; 00491 // If var in candidateBlockedVars is chosen, then 00492 // corresponding var in othersToFlip is flipped as well 00493 Array<Array<int> > candidateBlockedVars; 00494 Array<Array<int> > othersToFlip; 00495 Array<int> blockIdx; 00496 00497 canNotFlip.growToSize(clauseSize); 00498 candidateBlockedVars.growToSize(clauseSize); 00499 othersToFlip.growToSize(clauseSize); 00500 blockIdx.growToSize(clauseSize); 00501 00502 // Holds the best atoms so far 00503 Array<int> best; 00504 // How many are tied for best 00505 register int numbest = 0; 00506 // Best value so far 00507 long double bestvalue = -LDBL_MAX; 00508 00509 // Look at each atom and pick best ones 00510 for (int i = 0; i < clauseSize; i++) 00511 { 00512 register int lit = state_->getAtomInClause(i, toFix); 00513 // Neg. clause: Only look at true literals 00514 if (cost < 0 && !state_->isTrueLiteral(lit)) continue; 00515 // var is the index of the atom 00516 register int var = abs(lit); 00517 00518 if (state_->isFixedAtom(var)) continue; 00519 bool ignoreActivePreds = false; 00520 bool groundOnly = false; 00521 if (!state_->activateAtom(var, ignoreActivePreds, groundOnly)) 00522 return NOVALUE; 00523 00524 improvement = calculateImprovement(var, canNotFlip[i], 00525 candidateBlockedVars[i], 00526 othersToFlip[i], blockIdx[i]); 00527 if (mwsdebug) 00528 cout << "Improvement of var " << var << " is: " << improvement << endl; 00529 00530 if (improvement > -LDBL_MAX && improvement >= bestvalue) 00531 { // Tied or better than previous best 00532 if (improvement > bestvalue) 00533 { 00534 numbest = 0; 00535 best.clear(); 00536 } 00537 bestvalue = improvement; 00538 best.append(i); 00539 numbest++; 00540 } 00541 } 00542 00543 // If only false literals in a neg. clause, then numbest is 0 00544 if (numbest == 0) return NOVALUE; 00545 // Choose one of the best at random 00546 // (default if none of the following 2 cases occur) 00547 int toFlip = best[random()%numbest]; 00548 00549 // Exactly one best atom 00550 if (numbest == 1) 00551 toFlip = best[0]; 00552 int toFlipAtom = abs(state_->getAtomInClause(toFlip, toFix)); 00553 00554 if (blockIdx[toFlip] > -1) 00555 { 00556 // If atom can not be flipped, then null flip 00557 if (canNotFlip[toFlip].contains(toFlipAtom)) 00558 toFlipAtom = NOVALUE; 00559 else 00560 { // If toFlip is in block, then set other to flip 00561 int idx = candidateBlockedVars[toFlip].find(toFlipAtom); 00562 if (idx >= 0) 00563 { 00564 inBlock_ = blockIdx[toFlip]; 00565 flipInBlock_ = othersToFlip[toFlip][idx]; 00566 } 00567 } 00568 } 00569 00570 //if (mwsdebug) cout << "Leaving MaxWalkSat::pickBest" << endl; 00571 return toFlipAtom; 00572 }
int MaxWalkSat::pickTabu | ( | ) | [inline, protected] |
Pick an atom from a random unsatisfied clause based on the tabu heuristic.
Definition at line 579 of file maxwalksat.h.
References VariableState::activateAtom(), Array< Type >::append(), calculateImprovement(), SAT::changed_, Array< Type >::clear(), Array< Type >::find(), VariableState::getAtomInClause(), VariableState::getClauseCost(), VariableState::getClauseSize(), VariableState::getRandomFalseClauseIndex(), Array< Type >::growToSize(), VariableState::isFixedAtom(), SAT::numFlips_, and Inference::state_.
Referenced by MaxWalkSat(), and pickSS().
00580 { 00581 //if (mwsdebug) cout << "Entering MaxWalkSat::pickTabu" << endl; 00582 assert(inBlock_ == -1); 00583 // Clause to fix picked at random 00584 int toFix = state_->getRandomFalseClauseIndex(); 00585 if (toFix == NOVALUE) 00586 { 00587 //if (mwsdebug) cout << "Leaving MaxWalkSat::pickTabu (NOVALUE)" << endl; 00588 return NOVALUE; 00589 } 00590 if (mwsdebug) cout << "Looking to fix clause " << toFix << endl; 00591 00592 int clauseSize = state_->getClauseSize(toFix); 00593 long double cost = state_->getClauseCost(toFix); 00594 00595 long double improvement; 00596 // Arrays to hold information on candidate flips 00597 Array<Array<int> > canNotFlip; 00598 // If var in candidateBlockedVars is chosen, then 00599 // corresponding var in othersToFlip is flipped as well 00600 Array<Array<int> > candidateBlockedVars; 00601 Array<Array<int> > othersToFlip; 00602 Array<int> blockIdx; 00603 00604 canNotFlip.growToSize(clauseSize); 00605 candidateBlockedVars.growToSize(clauseSize); 00606 othersToFlip.growToSize(clauseSize); 00607 blockIdx.growToSize(clauseSize); 00608 00609 // Holds the best atoms so far 00610 Array<int> best; 00611 // How many are tied for best 00612 register int numbest = 0; 00613 // Best value so far 00614 long double bestvalue = -LDBL_MAX; 00615 00616 // With prob. do a noisy pick 00617 bool noisyPick = (numerator_ > 0 && random()%denominator_ < numerator_); 00618 00619 // if random move, exclude illegitimate ones and place others in a lottery 00620 if (noisyPick) 00621 { 00622 for (int i = 0; i < clauseSize; i++) 00623 { 00624 register int lit = state_->getAtomInClause(i, toFix); 00625 // Neg. clause: Only look at true literals 00626 if (cost < 0 && !state_->isTrueLiteral(lit)) continue; 00627 // var is the index of the atom 00628 register int var = abs(lit); 00629 00630 if (state_->isFixedAtom(var)) continue; 00631 bool ignoreActivePreds = false; 00632 bool groundOnly = false; 00633 if (!state_->activateAtom(var, ignoreActivePreds, groundOnly)) 00634 return NOVALUE; 00635 00636 // We don't need improvement, but this function fills the block arrays 00637 calculateImprovement(var, canNotFlip[i], 00638 candidateBlockedVars[i], 00639 othersToFlip[i], blockIdx[i]); 00640 00641 best.append(i); 00642 numbest++; 00643 } 00644 } 00645 // greedy: pick the best value 00646 else for (int i = 0; i < clauseSize; i++) 00647 { 00648 register int lit = state_->getAtomInClause(i, toFix); 00649 // Neg. clause: Only look at true literals 00650 if (cost < 0 && !state_->isTrueLiteral(lit)) continue; 00651 // var is the index of the atom 00652 register int var = abs(lit); 00653 00654 if (state_->isFixedAtom(var)) continue; 00655 bool ignoreActivePreds = false; 00656 bool groundOnly = false; 00657 if (!state_->activateAtom(var, ignoreActivePreds, groundOnly)) 00658 return NOVALUE; 00659 00660 improvement = calculateImprovement(var, canNotFlip[i], 00661 candidateBlockedVars[i], 00662 othersToFlip[i], blockIdx[i]); 00663 if (mwsdebug) 00664 cout << "Improvement of var " << var << " is: " << improvement << endl; 00665 00666 // TABU: If pos. improvement, then always add it to best 00667 if (improvement > 0 && improvement >= bestvalue) 00668 { // Tied or better than previous best 00669 if (improvement > bestvalue) 00670 { 00671 numbest = 0; 00672 best.clear(); 00673 } 00674 bestvalue = improvement; 00675 best.append(i); 00676 numbest++; 00677 } 00678 else if (improvement > -LDBL_MAX && 00679 tabuLength_ < numFlips_ - changed_[var]) 00680 { 00681 if (improvement >= bestvalue) 00682 { // Tied or better than previous best 00683 if (improvement > bestvalue) 00684 { 00685 numbest = 0; 00686 best.clear(); 00687 } 00688 bestvalue = improvement; 00689 best.append(i); 00690 numbest++; 00691 } 00692 } 00693 } 00694 00695 if (numbest == 0) 00696 { 00697 //if (mwsdebug) cout << "Leaving MaxWalkSat::pickTabu (NOVALUE)" << endl; 00698 return NOVALUE; 00699 } 00700 00701 int toFlip = NOVALUE; 00702 // Exactly one best atom 00703 if (numbest == 1) 00704 toFlip = best[0]; 00705 else 00706 // Choose one of the best at random 00707 toFlip = best[random()%numbest]; 00708 int toFlipAtom = abs(state_->getAtomInClause(toFlip, toFix)); 00709 00710 if (blockIdx[toFlip] > -1) 00711 { 00712 // If atom can not be flipped, then null flip 00713 if (canNotFlip[toFlip].contains(toFlipAtom)) 00714 toFlipAtom = NOVALUE; 00715 else 00716 { // If toFlip is in block, then set other to flip 00717 int idx = candidateBlockedVars[toFlip].find(toFlipAtom); 00718 if (idx >= 0) 00719 { 00720 inBlock_ = blockIdx[toFlip]; 00721 flipInBlock_ = othersToFlip[toFlip][idx]; 00722 } 00723 } 00724 } 00725 00726 //if (mwsdebug) cout << "Leaving MaxWalkSat::pickTabu" << endl; 00727 return toFlipAtom; 00728 }
int MaxWalkSat::pickSS | ( | ) | [inline, protected] |
Pick an atom according to the SampleSat heuristic.
This means sometimes sim. annealing, sometimes MaxWalkSat.
Definition at line 736 of file maxwalksat.h.
References VariableState::activateAtom(), calculateImprovement(), Array< Type >::contains(), Array< Type >::find(), VariableState::getCostOfFalseClauses(), VariableState::getIndexOfRandomAtom(), VariableState::isFixedAtom(), pickTabu(), VariableState::setActive(), Inference::state_, and SAT::targetCost_.
Referenced by MaxWalkSat().
00737 { 00738 //if (mwsdebug) cout << "Entering MaxWalkSat::pickSS" << endl; 00739 assert(inBlock_ == -1); 00740 Array<int> canNotFlip; 00741 // If var in candidateBlockedVars is chosen, then 00742 // corresponding var in othersToFlip is flipped as well 00743 Array<int> candidateBlockedVars; 00744 Array<int> othersToFlip; 00745 int blockIdx; 00746 00747 long double costOfFalseClauses = state_->getCostOfFalseClauses(); 00748 00749 // If we have already reached a solution or if in an SA step, 00750 // then perform SA 00751 // Add 0.0001 to targetCost_ because of double precision error 00752 // This needs to be fixed 00753 if (costOfFalseClauses <= targetCost_ + 0.0001 || 00754 (!lateSa_ && random() % 100 < saRatio_ )) 00755 { 00756 // Choose a random atom to flip 00757 int toFlip = state_->getIndexOfRandomAtom(); 00758 if (toFlip == NOVALUE) return NOVALUE; 00759 00760 if (state_->isFixedAtom(toFlip)) return NOVALUE; 00761 bool ignoreActivePreds = false; 00762 // SA step: we don't want to activate 00763 bool groundOnly = true; 00764 if (!state_->activateAtom(toFlip, ignoreActivePreds, groundOnly)) 00765 return NOVALUE; 00766 long double improvement = calculateImprovement(toFlip, canNotFlip, 00767 candidateBlockedVars, 00768 othersToFlip, blockIdx); 00769 if (mwsdebug) cout << "Total improvement: " << improvement << endl; 00770 00771 // If pos. or no improvement, then the atom will be flipped 00772 // Or neg. improvement: According to temp. flip atom anyway 00773 if (improvement > -LDBL_MAX && 00774 ((improvement >= 0) || 00775 (random() <= exp(improvement/(saTemp_/100.0)) * RAND_MAX))) 00776 { 00777 // If atom can not be flipped, then null flip 00778 if (canNotFlip.contains(toFlip)) toFlip = NOVALUE; 00779 else 00780 { // If toflip is in block, then set other to flip 00781 int idx = candidateBlockedVars.find(toFlip); 00782 if (idx >= 0) 00783 { 00784 inBlock_ = blockIdx; 00785 flipInBlock_ = othersToFlip[idx]; 00786 } 00787 } 00788 00789 // SA 00790 if (toFlip != NOVALUE) 00791 { 00792 state_->setActive(toFlip); 00793 } 00794 return toFlip; 00795 } 00796 else 00797 { 00798 return NOVALUE; 00799 } 00800 } 00801 // Not in a solution or SA step: perform normal MWS step 00802 else 00803 { 00804 return pickTabu(); 00805 } 00806 }
long double MaxWalkSat::calculateImprovement | ( | const int & | atomIdx, | |
Array< int > & | canNotFlip, | |||
Array< int > & | candidateBlockedVars, | |||
Array< int > & | othersToFlip, | |||
int & | blockIdx | |||
) | [inline, protected] |
Calculates the improvement (makecost - breakcost) by flipping an atom.
If the atom is in a block, then its index is saved in candidateBlockedVars and the index of another atom chosen to be flipped in the block is appended to othersToFlip. If the atom is in a block with evidence, then its index is appended to canNotFlip.
atomIdx | Index of atom for which the improvement is calculated. | |
canNotFlip | Holds indices of atoms which can not be flipped due to evidence in a block. | |
candidateBlockedVars | If dealing with an atom in a block, then its index is appended here. | |
othersToFlip | If dealing with an atom in a block, then the index of the other atom chosen to be flipped is appended here. | |
blockIdx | Index of block if atom with atomIdx is in a block. Otherwise, -1. |
Definition at line 826 of file maxwalksat.h.
References Array< Type >::append(), Domain::getBlockEvidence(), VariableState::getBlockIndex(), Domain::getBlockSize(), VariableState::getDomain(), VariableState::getImprovementByFlipping(), VariableState::getIndexOfGroundPredicate(), Domain::getPredInBlock(), Domain::getRandomPredInBlock(), VariableState::getValueOfAtom(), and Inference::state_.
Referenced by pickBest(), pickSS(), and pickTabu().
00829 { 00830 blockIdx = state_->getBlockIndex(atomIdx - 1); 00831 if (blockIdx == -1) 00832 { 00833 // Atom not in a block 00834 return state_->getImprovementByFlipping(atomIdx); 00835 } 00836 else 00837 { 00838 // Atom is in a block 00839 // If evidence atom exists or in block of size 1, then can not flip 00840 if (state_->getDomain()->getBlockEvidence(blockIdx) || 00841 state_->getDomain()->getBlockSize(blockIdx) == 1) 00842 { 00843 canNotFlip.append(atomIdx); 00844 return -LDBL_MAX; 00845 } 00846 else 00847 { 00848 // Dealing with atom in a block 00849 int blockSize = state_->getDomain()->getBlockSize(blockIdx); 00850 int chosen = -1; 00851 int otherToFlip = -1; 00852 00853 // 0->1: choose atom in block which is already 1 00854 if (state_->getValueOfAtom(atomIdx) == 0) 00855 { 00856 for (int i = 0; i < blockSize; i++) 00857 { 00858 const Predicate* pred = 00859 state_->getDomain()->getPredInBlock(i, blockIdx); 00860 GroundPredicate* gndPred = new GroundPredicate((Predicate*)pred); 00861 00862 int idx = state_->getIndexOfGroundPredicate(gndPred); 00863 00864 delete gndPred; 00865 delete pred; 00866 00867 // Pred is in the state 00868 if (idx >= 0) 00869 { 00870 if (state_->getValueOfAtom(idx + 1) == 1) 00871 { 00872 chosen = idx + 1; 00873 break; 00874 } 00875 } 00876 } 00877 } 00878 // 1->0: choose to flip the other randomly 00879 // TODO: choose to flip the other with best improvement 00880 else 00881 { 00882 bool ok = false; 00883 while (!ok) 00884 { 00885 const Predicate* pred = 00886 state_->getDomain()->getRandomPredInBlock(blockIdx); 00887 GroundPredicate* gndPred = new GroundPredicate((Predicate*)pred); 00888 00889 int idx = state_->getIndexOfGroundPredicate(gndPred); 00890 if (idx == -1) 00891 { 00892 delete gndPred; 00893 delete pred; 00894 continue; 00895 // TODO: Other atom not yet in state (lazy) - must activate it 00896 } 00897 chosen = idx + 1; 00898 00899 delete gndPred; 00900 delete pred; 00901 00902 if (chosen != atomIdx) 00903 ok = true; 00904 } 00905 } 00906 00907 assert(chosen >= 0); 00908 candidateBlockedVars.append(atomIdx); 00909 otherToFlip = chosen; 00910 othersToFlip.append(otherToFlip); 00911 return (state_->getImprovementByFlipping(atomIdx) + 00912 state_->getImprovementByFlipping(otherToFlip)); 00913 } 00914 } 00915 }