void CbcTree::validateHeap () { if (comparison_.test_ == 0) { std::cout << " Invalid heap (no predicate)!" << std::endl ; return ; } std::vector<CbcNode *>::const_iterator curNode,lastNode ; curNode = nodes_.begin() ; lastNode = nodes_.end() ; int curNdx = 0 ; int parNdx = 0 ; if (curNode == lastNode) return ; if (*curNode == 0) { std::cout << " Invalid heap[" << curNdx << "] (null entry)!" << std::endl ; } std::vector<CbcNode *>::const_iterator parent ; std::vector<CbcNode*>::const_iterator &child = curNode ; for (parent = curNode ; ++curNode != lastNode ; ++parent, ++parNdx) { curNdx++ ; if (*parent == 0) { std::cout << " Invalid heap[" << parNdx << "] (parent null entry)!" << std::endl ; curNode++ ; curNdx++ ; continue ; } if (*curNode == 0) { std::cout << " Invalid heap[" << curNdx << "] (left child null entry)!" << std::endl ; } else { if (!check_pred(*comparison_.test_,*parent,*child)) { std::cout << " Invalid heap (left child better)!" << std::endl ; CbcNode *node = *parent ; std::cout << " Parent [" << parNdx << "] (" << std::hex << node << std::dec << ") unsat " << node->numberUnsatisfied() << ", depth " << node->depth() << ", obj " << node->objectiveValue() << "." << std::endl ; node = *child ; std::cout << " Child [" << curNdx << "] (" << std::hex << node << std::dec << ") unsat " << node->numberUnsatisfied() << ", depth " << node->depth() << ", obj " << node->objectiveValue() << "." << std::endl ; } } curNode++ ; curNdx++ ; if (curNode == lastNode) break ; if (*curNode == 0) { std::cout << " Invalid heap[" << curNdx << "] (right child null entry)!" << std::endl ; } else { if (!check_pred(*comparison_.test_,*parent,*child)) { std::cout << " Invalid heap (right child better)!" << std::endl ; CbcNode *node = *parent ; std::cout << " Parent [" << parNdx << "] (" << std::hex << node << std::dec << ") unsat " << node->numberUnsatisfied() << ", depth " << node->depth() << ", obj " << node->objectiveValue() << "." << std::endl ; node = *child ; std::cout << " Child [" << curNdx << "] (" << std::hex << node << std::dec << ") unsat " << node->numberUnsatisfied() << ", depth " << node->depth() << ", obj " << node->objectiveValue() << "." << std::endl ; } } } return ; }
// Gets best node and takes off heap CbcNode * CbcTreeArray::bestNode(double cutoff) { CbcNode * best = NULL; // See if we want last node or best on heap if (lastNode_) { #ifdef CBCTREE_PRINT printf("Best lastNode_ %x (%x at depth %d) - nodeNumber %d obj %g\n", lastNode_, lastNode_->nodeInfo(), lastNode_->depth(), lastNode_->nodeNumber(), lastNode_->objectiveValue()); #endif assert (lastNode_->onTree()); int nodeNumber = lastNode_->nodeNumber(); bool useLastNode = false; if (nodeNumber + 1 == maximumNodeNumber_) { // diving - look further CbcCompareDefault * compareDefault = dynamic_cast<CbcCompareDefault *> (comparison_.test_); assert (compareDefault); double bestPossible = compareDefault->getBestPossible(); double cutoff = compareDefault->getCutoff(); double objValue = lastNode_->objectiveValue(); if (cutoff < 1.0e20) { if (objValue - bestPossible < 0.999*(cutoff - bestPossible)) useLastNode = true; } else { useLastNode = true; } } if (useLastNode) { lastNode_->setOnTree(false); best = lastNode_; lastNode_ = NULL; assert(best->objectiveValue() != COIN_DBL_MAX && best->nodeInfo()); if (best->objectiveValue() != COIN_DBL_MAX && best->nodeInfo()) assert (best->nodeInfo()->numberBranchesLeft()); if (best->objectiveValue() >= cutoff) { // double check in case node can change its mind! best->checkIsCutoff(cutoff); } lastNodePopped_ = best; return best; } else { // put on tree nodes_.push_back(lastNode_); lastNode_->setNodeNumber(maximumNodeNumber_); maximumNodeNumber_++; lastNode_ = NULL; std::push_heap(nodes_.begin(), nodes_.end(), comparison_); } } while (!best && nodes_.size()) { best = nodes_.front(); if (best) assert(best->objectiveValue() != COIN_DBL_MAX && best->nodeInfo()); if (best && best->objectiveValue() != COIN_DBL_MAX && best->nodeInfo()) assert (best->nodeInfo()->numberBranchesLeft()); if (best && best->objectiveValue() >= cutoff) { // double check in case node can change its mind! best->checkIsCutoff(cutoff); } if (!best || best->objectiveValue() >= cutoff) { // let code get rid of it assert (best); } } lastNodePopped_ = best; #ifdef CBCTREE_PRINT if (best) printf("Heap returning node %x (%x at depth %d) - nodeNumber %d - obj %g\n", best, best->nodeInfo(), best->depth(), best->nodeNumber(), best->objectiveValue()); else printf("Heap returning Null\n"); #endif if (best) { // take off std::pop_heap(nodes_.begin(), nodes_.end(), comparison_); nodes_.pop_back(); } #ifdef DEBUG_CBC_HEAP if (best) { int n = nodes_.size(); bool good = true; for (int i = 0; i < n; i++) { // temp assert (nodes_[i]); if (!comparison_.compareNodes(nodes_[i], best)) { good = false; CbcNode * x = nodes_[i]; printf("i=%d x is better nun %d depth %d obj %g, best nun %d depth %d obj %g\n", i, x->numberUnsatisfied(), x->depth(), x->objectiveValue(), best->numberUnsatisfied(), best->depth(), best->objectiveValue()); } } if (!good) { // compare best to all int i; for (i = 0; i < n; i++) { CbcNode * x = nodes_[i]; printf("i=%d x is nun %d depth %d obj %g", i, x->numberUnsatisfied(), x->depth(), x->objectiveValue()); if (!comparison_.compareNodes(x, best)) { printf(" - best is worse!\n"); } else { printf("\n"); } } // Now compare amongst rest for (i = 0; i < n; i++) { CbcNode * x = nodes_[i]; printf("For i=%d ", i); for (int j = i + 1; j < n; j++) { CbcNode * y = nodes_[j]; if (!comparison_.compareNodes(x, y)) { printf(" b %d", j); } else { printf(" w %d", j); } } printf("\n"); } assert(good); } } #endif if (best) best->setOnTree(false); return best; }
// Gets best node and takes off heap CbcNode * CbcTree::bestNode(double cutoff) { CbcNode * best = NULL; while (!best && nodes_.size()) { best = nodes_.front(); if (best) assert(best->objectiveValue() != COIN_DBL_MAX && best->nodeInfo()); if (best && best->objectiveValue() != COIN_DBL_MAX && best->nodeInfo()) assert (best->nodeInfo()->numberBranchesLeft()); if (best && best->objectiveValue() >= cutoff) { // double check in case node can change its mind! best->checkIsCutoff(cutoff); } if (!best || best->objectiveValue() >= cutoff) { #ifdef JJF_ZERO // take off std::pop_heap(nodes_.begin(), nodes_.end(), comparison_); nodes_.pop_back(); delete best; best = NULL; #else // let code get rid of it assert (best); #endif } } // switched off for now if (best && comparison_.test_->fullScan() && false) { CbcNode * saveBest = best; int n = nodes_.size(); int iBest = -1; for (int i = 0; i < n; i++) { // temp assert (nodes_[i]); assert (nodes_[i]->nodeInfo()); if (nodes_[i] && nodes_[i]->objectiveValue() != COIN_DBL_MAX && nodes_[i]->nodeInfo()) assert (nodes_[i]->nodeInfo()->numberBranchesLeft()); if (nodes_[i] && nodes_[i]->objectiveValue() < cutoff && comparison_.alternateTest(best, nodes_[i])) { best = nodes_[i]; iBest = i; } } if (best == saveBest) { // can pop // take off std::pop_heap(nodes_.begin(), nodes_.end(), comparison_); nodes_.pop_back(); } else { // make impossible nodes_[iBest] = NULL; } } else if (best) { // take off #ifdef JJF_ZERO std::pop_heap(nodes_.begin(), nodes_.end(), comparison_); nodes_.pop_back(); #else realpop(); #endif } #ifdef DEBUG_CBC_HEAP if (best) { int n = nodes_.size(); bool good = true; for (int i = 0; i < n; i++) { // temp assert (nodes_[i]); if (!comparison_.compareNodes(nodes_[i], best)) { good = false; CbcNode * x = nodes_[i]; printf("i=%d x is better nun %d depth %d obj %g, best nun %d depth %d obj %g\n", i, x->numberUnsatisfied(), x->depth(), x->objectiveValue(), best->numberUnsatisfied(), best->depth(), best->objectiveValue()); } } if (!good) { // compare best to all int i; for (i = 0; i < n; i++) { CbcNode * x = nodes_[i]; printf("i=%d x is nun %d depth %d obj %g", i, x->numberUnsatisfied(), x->depth(), x->objectiveValue()); if (!comparison_.compareNodes(x, best)) { printf(" - best is worse!\n"); } else { printf("\n"); } } // Now compare amongst rest for (i = 0; i < n; i++) { CbcNode * x = nodes_[i]; printf("For i=%d ", i); for (int j = i + 1; j < n; j++) { CbcNode * y = nodes_[j]; if (!comparison_.compareNodes(x, y)) { printf(" b %d", j); } else { printf(" w %d", j); } } printf("\n"); } assert(good); } } #endif if (best) best->setOnTree(false); return best; }