// Constructor from current state BonCbcPartialNodeInfo::BonCbcPartialNodeInfo (CbcModel * model,CbcNodeInfo *parent, CbcNode *owner, int numberChangedBounds, const int *variables, const double *boundChanges, const CoinWarmStartDiff *basisDiff) : CbcPartialNodeInfo(parent,owner,numberChangedBounds,variables, boundChanges,basisDiff), sequenceOfInfeasiblesSize_(0), sequenceOfUnsolvedSize_(0) { BonCbcPartialNodeInfo * nlpParent = dynamic_cast<BonCbcPartialNodeInfo *> (parent); int numberInfeasible = 0; int numberUnsolved = 0; if (nlpParent)//father is not root { numberInfeasible = nlpParent->getSequenceOfInfeasiblesSize(); numberUnsolved = nlpParent->getSequenceOfUnsolvedSize(); // if(!nlpParent->numberBranchesLeft_){ // IpoptWarmStartDiff * ipws = dynamic_cast<IpoptWarmStartDiff *>(nlpParent->basisDiff_); // ipws->flushPoint(); // } } else { BonCbcFullNodeInfo * nlpRoot = dynamic_cast<BonCbcFullNodeInfo *> (parent); if (nlpRoot) { numberInfeasible = nlpRoot->getSequenceOfInfeasiblesSize(); numberUnsolved = nlpRoot->getSequenceOfUnsolvedSize(); } } if (model->solver()->isAbandoned() || model->solver()->isIterationLimitReached()) sequenceOfUnsolvedSize_ = numberUnsolved + 1; if (model->solver()->isProvenPrimalInfeasible()) sequenceOfInfeasiblesSize_ = numberInfeasible + 1; }
/* After a CbcModel::resolve this can return a status -1 no effect 0 treat as optimal 1 as 0 but do not do any more resolves (i.e. no more cuts) 2 treat as infeasible */ int CbcNlpStrategy::status(CbcModel * model, CbcNodeInfo * parent,int whereFrom) { OsiSolverInterface * solver = model->solver();//get solver int feasible = 1; bool solved = true; int returnStatus = -1; BonCbcPartialNodeInfo * bmNodeInfo = dynamic_cast<BonCbcPartialNodeInfo *>(parent); if (!bmNodeInfo) return -1; int seqOfInfeasiblesSize = bmNodeInfo->getSequenceOfInfeasiblesSize(); int seqOfUnsolvedSize = bmNodeInfo->getSequenceOfUnsolvedSize(); if (solver->isAbandoned()) { solved = false; seqOfUnsolvedSize++; ; } else if (solver->isProvenPrimalInfeasible()) { feasible = 0; seqOfInfeasiblesSize++; } if ((seqOfUnsolvedSize==0) || (maxFailure_ == 0) && (maxInfeasible_== 0) || (seqOfInfeasiblesSize==0)) if (feasible && seqOfInfeasiblesSize > 1) { (*model->messageHandler())<<"Feasible node while father was infeasible." <<CoinMessageEol; } if (solved && seqOfUnsolvedSize > 1) { (*model->messageHandler())<<"Solved node while father was unsolved." <<CoinMessageEol; } if (seqOfInfeasiblesSize < maxInfeasible_ && solved && !feasible) { (*model->messageHandler())<<"Branching on infeasible node, sequence of infeasibles size " <<seqOfInfeasiblesSize<<CoinMessageEol; // Have to make sure that we will branch OsiTMINLPInterface * ipopt = dynamic_cast<OsiTMINLPInterface *>(solver); ipopt->forceBranchable(); //change objective value returnStatus = 0; } if (!solved && parent != NULL && seqOfUnsolvedSize <= maxFailure_) { (*model->messageHandler())<<"Branching on unsolved node, sequence of unsolved size "<<seqOfUnsolvedSize<<CoinMessageEol; // Have to make sure that we will branch OsiTMINLPInterface * osiMinlp = dynamic_cast<OsiTMINLPInterface *>(solver); osiMinlp->forceBranchable(); // feasible=1; returnStatus = 0; } if (solver->isAbandoned() && parent != NULL && seqOfUnsolvedSize > maxFailure_) { hasFailed_ = true; OsiTMINLPInterface * osiMinlp = dynamic_cast<OsiTMINLPInterface *>(solver); if (pretendFailIsInfeasible_) { //force infeasible osiMinlp->forceInfeasible(); returnStatus = 2; } else { std::string probName; osiMinlp->getStrParam(OsiProbName,probName); throw osiMinlp->newUnsolvedError(0, osiMinlp->problem(), probName); } } return returnStatus; }