/** Runs heuristic*/ int FixAndSolveHeuristic::solution(double & objectiveValue, double * newSolution){ //if(model_->getNodeCount() || model_->getCurrentPassNumber() > 1) return 0; if(model_->getSolutionCount() > 0) return 0; if(model_->getNodeCount() > 1000) return 0; if(model_->getNodeCount() % 100 != 0) return 0; int numberObjects = model_->numberObjects(); OsiObject ** objects = model_->objects(); OsiTMINLPInterface * nlp = dynamic_cast<OsiTMINLPInterface *> (model_->solver()); if(nlp == NULL){ nlp = dynamic_cast<OsiTMINLPInterface *> (setup_->nonlinearSolver()->clone()); } else { nlp = dynamic_cast<OsiTMINLPInterface *>(nlp->clone()); } OsiBranchingInformation info = model_->usefulInformation(); info.solution_ = model_->getColSolution(); int dummy; int nFixed = 0; for(int i = 0 ; i < numberObjects; i++){ if(objects[i]->infeasibility(&info, dummy) == 0.){ objects[i]->feasibleRegion(nlp, &info); nFixed ++; } } if(nFixed < numberObjects / 3) return 0; double cutoff = info.cutoff_; int r_val = doLocalSearch(nlp, newSolution, objectiveValue, cutoff); delete nlp; return r_val; }
/** Standard cut generation methods. */ void OaDecompositionBase::generateCuts(const OsiSolverInterface &si, OsiCuts & cs, const CglTreeInfo info) { if (nlp_ == NULL) { throw CoinError("Error in cut generator for outer approximation no NLP ipopt assigned", "generateCuts", "OaDecompositionBase"); } // babInfo is used to communicate with the b-and-b solver (Cbc or Bcp). BabInfo * babInfo = dynamic_cast<BabInfo *> (si.getAuxiliaryInfo()); assert(babInfo); assert(babInfo->babPtr()); numSols_ = babInfo->babPtr()->model().getSolutionCount (); CglTreeInfo info_copy = info; const CbcNode * node = babInfo->babPtr()->model().currentNode(); info_copy.level = (node == NULL) ? 0 : babInfo->babPtr()->model().currentNode()->depth(); if(babInfo->hasSolution()) numSols_ ++; if (babInfo) if (!babInfo->mipFeasible()) return; //Get the continuous solution const double *colsol = si.getColSolution(); vector<double> savedColLower(nlp_->getNumCols()); CoinCopyN(nlp_->getColLower(), nlp_->getNumCols(), savedColLower()); vector<double> savedColUpper(nlp_->getNumCols()); CoinCopyN(nlp_->getColUpper(), nlp_->getNumCols(), savedColUpper()); OsiBranchingInformation brInfo(nlp_, false); brInfo.solution_ = colsol; //Check integer infeasibility bool isInteger = integerFeasible(*nlp_, brInfo, parameters_.cbcIntegerTolerance_, objects_, nObjects_); //Check nodeNumber if it did not change scan savedCuts_ if one is violated force it and exit int nodeNumber = babInfo->babPtr()->model().getNodeCount(); if(nodeNumber == currentNodeNumber_){ #ifdef OA_DEBUG printf("OA decomposition recalled from the same node!\n"); #endif int numCuts = savedCuts_.sizeRowCuts(); for(int i = 0 ; i < numCuts ; i++){ //Check if cuts off solution if(savedCuts_.rowCut(i).violated(colsol) > 0.){ #ifdef OA_DEBUG printf("A violated saved cut has been found\n"); #endif savedCuts_.rowCut(i).setEffectiveness(9.99e99); cs.insert(savedCuts_.rowCut(i)); savedCuts_.eraseRowCut(i); return; i--; numCuts--; } } } else { currentNodeNumber_ = nodeNumber; savedCuts_.dumpCuts(); } if (!isInteger) { if (!doLocalSearch(babInfo))//create sub mip solver. return; } //get the current cutoff double cutoff; si.getDblParam(OsiDualObjectiveLimit, cutoff); // Save solvers state if needed solverManip * lpManip = NULL; if (lp_ != NULL) { assert(lp_ == &si); lpManip = new solverManip(lp_, true, leaveSiUnchanged_, true, true); } else { lpManip = new solverManip(si); } lpManip->setObjects(objects_, nObjects_); double milpBound = performOa(cs, *lpManip, babInfo, cutoff, info_copy); if(babInfo->hasSolution()){ babInfo->babPtr()->model().setSolutionCount (numSols_ - 1); } //Transmit the bound found by the milp { if (milpBound>-1e100) { // Also store into solver if (babInfo) babInfo->setMipBound(milpBound); } } //Clean everything : // Reset the two solvers if (leaveSiUnchanged_) lpManip->restore(); delete lpManip; nlp_->setColLower(savedColLower()); nlp_->setColUpper(savedColUpper()); return; }