/home/coin/SVN-release/OS-2.4.2/Bonmin/src/CbcBonmin/BonCbc.cpp

Go to the documentation of this file.
00001 // (C) Copyright International Business Machines Corporation 2007
00002 // All Rights Reserved.
00003 // This code is published under the Common Public License.
00004 //
00005 // Authors :
00006 // Pierre Bonami, International Business Machines Corporation
00007 //
00008 // Date : 04/19/2007
00009 
00010 
00011 #include "BonCbc.hpp"
00012 #include "BonOACutGenerator2.hpp"
00013 #include "BonCbcNlpStrategy.hpp"
00014 #include "BonBabInfos.hpp"
00015 #include "CbcModel.hpp"
00016 #include "CbcBranchActual.hpp"
00017 #include "CbcCutGenerator.hpp"
00018 #include "CbcCompareActual.hpp"
00019 #include "CbcCompareObjective.hpp"
00020 #include "CbcCompareEstimate.hpp"
00021 
00022 #include "BonExitCodes.hpp"
00023 
00024 #include "BonChooseVariable.hpp"
00025 #include "BonGuessHeuristic.hpp"
00026 
00027 #include "BonDiver.hpp"
00028 #include "BonLinearCutsGenerator.hpp"
00029 #include "BonTMINLPLinObj.hpp"
00030 // sets cutoff a bit above real one, to avoid single-point feasible sets
00031 #define CUTOFF_TOL 1e-6
00032 
00033 // Code to enable user interuption
00034 static CbcModel * currentBranchModel = NULL; //pointer to the main b&b
00035 Bonmin::OACutGenerator2 * currentOA = NULL; //pointer to the OA generator
00036 CbcModel * OAModel; // pointer to the submip if using Cbc
00037 bool BonminAbortAll;
00038 
00039 #define SIGNAL
00040 #ifdef SIGNAL
00041 #include "CoinSignal.hpp"
00042 
00043 extern "C"
00044 {
00045 
00046   static bool BonminInteruptedOnce =false;
00047   static void signal_handler(int whichSignal) {
00048     if (BonminInteruptedOnce) {
00049       std::cerr<<"User forced interuption"<<std::endl;
00050       exit(0);
00051     }
00052     if (currentBranchModel!=NULL)
00053       currentBranchModel->setMaximumNodes(0); // stop at next node
00054     if (OAModel!=NULL)
00055       OAModel->setMaximumNodes(0); // stop at next node
00056     if (currentOA!=NULL)
00057       currentOA->parameter().maxLocalSearchTime_ = 0.; // stop OA
00058     BonminAbortAll = true;
00059     BonminInteruptedOnce = true;
00060     return;
00061   }
00062 }
00063 #endif
00064 
00065 namespace Bonmin
00066 {
00067 
00069   Bab::Bab():
00070       bestSolution_(NULL),
00071       mipStatus_(),
00072       bestObj_(1e200),
00073       bestBound_(-1e200),
00074       continuousRelaxation_(-COIN_DBL_MAX),
00075       numNodes_(0),
00076       mipIterationCount_(0),
00077       model_(),
00078       modelHandler_(NULL),
00079       objects_(0),
00080       nObjects_(0),
00081       usingCouenne_(false)
00082   {}
00083 
00085   Bab::~Bab()
00086   {
00087     if (bestSolution_) delete [] bestSolution_;
00088     bestSolution_ = NULL;
00089     for ( int i = 0 ; i < nObjects_ ; i++) {
00090       delete objects_[i];
00091     }
00092     delete [] objects_;
00093     delete modelHandler_;
00094   }
00095 
00097   void
00098   Bab::operator()(BabSetupBase & s)
00099   {
00100     branchAndBound(s);
00101   }
00102 
00104   void
00105   Bab::branchAndBound(BabSetupBase & s)
00106   {
00107 
00108     double remaining_time = s.getDoubleParameter(BabSetupBase::MaxTime) + CoinCpuTime();
00109     /* Put a link to this into solver.*/
00110     OsiBabSolver *  babInfo = dynamic_cast<OsiBabSolver *>(s.continuousSolver()->getAuxiliaryInfo());
00111     assert(babInfo);
00112     Bonmin::BabInfo *  bonBabInfoPtr = dynamic_cast<Bonmin::BabInfo*>(babInfo);
00113     if (bonBabInfoPtr == NULL) {//Replace with a Bonmin::babInfo
00114       bonBabInfoPtr = new Bonmin::BabInfo(*babInfo);
00115       s.continuousSolver()->setAuxiliaryInfo(bonBabInfoPtr);
00116       delete bonBabInfoPtr;
00117       bonBabInfoPtr = dynamic_cast<Bonmin::BabInfo*>(s.continuousSolver()->getAuxiliaryInfo());
00118     }
00119     bonBabInfoPtr->setBabPtr(this);
00120 
00121     s.nonlinearSolver()->solver()->setup_global_time_limit(s.getDoubleParameter(BabSetupBase::MaxTime));
00122     OsiSolverInterface * solver = s.continuousSolver()->clone();
00123     delete modelHandler_;
00124     modelHandler_ = s.continuousSolver()->messageHandler()->clone();
00125     model_.passInMessageHandler(modelHandler_);
00126     model_.assignSolver(solver, true);
00127 
00128 
00129     //  s.continuousSolver() = model_.solver();
00130     //   if(s.continuousSolver()->objects()!=NULL){
00131     //     model_.addObjects(s.continuousSolver()->numberObjects(),s.continuousSolver()->objects());
00132     //   }
00133 
00134     int specOpt = s.getIntParameter(BabSetupBase::SpecialOption);
00135     if (specOpt) {
00136       model_.setSpecialOptions(specOpt);
00137       if (specOpt==16) {
00138         CbcNlpStrategy strat(s.getIntParameter(BabSetupBase::MaxFailures), 
00139                              s.getIntParameter(BabSetupBase::MaxInfeasible), 
00140                              s.getIntParameter(BabSetupBase::FailureBehavior));
00141         model_.setStrategy(strat);
00142       }
00143     }
00144 
00145     model_.setMaximumCutPasses(s.getIntParameter(BabSetupBase::NumCutPasses));
00146     model_.setMaximumCutPassesAtRoot(s.getIntParameter(BabSetupBase::NumCutPassesAtRoot));
00147 
00148     //Setup cutting plane methods
00149     for (BabSetupBase::CuttingMethods::iterator i = s.cutGenerators().begin() ;
00150         i != s.cutGenerators().end() ; i++) {
00151 
00152       OaDecompositionBase * oa = dynamic_cast<OaDecompositionBase *>(i->cgl);
00153       if (oa && oa->reassignLpsolver())
00154         oa->assignLpInterface(model_.solver());
00155       model_.addCutGenerator(i->cgl,i->frequency,i->id.c_str(), i->normal,
00156                                i->atSolution);
00157       if(i->always){
00158          model_.cutGenerators()[model_.numberCutGenerators()-1]
00159                   ->setMustCallAgain(true);
00160       }
00161     }
00162 
00163     for (BabSetupBase::HeuristicMethods::iterator i = s.heuristics().begin() ;
00164         i != s.heuristics().end() ; i++) {
00165       CbcHeuristic * heu = i->heuristic;
00166       heu->setModel(&model_);
00167       model_.addHeuristic(heu, i->id.c_str());
00168     }
00169 
00170 
00171     //need to record solver logLevel here
00172     int logLevel = s.continuousSolver()->messageHandler()->logLevel();
00173 
00174     //Set true branch-and-bound parameters
00175     model_.setLogLevel(s.getIntParameter(BabSetupBase::BabLogLevel));
00176 
00177     // Put back solver logLevel
00178     model_.solver()->messageHandler()->setLogLevel(logLevel);
00179 
00180     model_.setPrintFrequency(s.getIntParameter(BabSetupBase::BabLogInterval));
00181 
00182     bool ChangedObject = false;
00183     //Pass over user set branching priorities to Cbc
00184     if (s.continuousSolver()->objects()==NULL) {
00185       //assert (s.branchingMethod() == NULL);
00186       const OsiTMINLPInterface * nlpSolver = s.nonlinearSolver();
00187       //set priorities, prefered directions...
00188       const int * priorities = nlpSolver->getPriorities();
00189       const double * upPsCosts = nlpSolver->getUpPsCosts();
00190       const double * downPsCosts = nlpSolver->getDownPsCosts();
00191       const int * directions = nlpSolver->getBranchingDirections();
00192       bool hasPseudo = (upPsCosts!=NULL);
00193       model_.findIntegers(true,hasPseudo);
00194       OsiObject ** simpleIntegerObjects = model_.objects();
00195       int numberObjects = model_.numberObjects();
00196       if (priorities != NULL || directions != NULL || hasPseudo) {
00197         ChangedObject = true;
00198         for (int i = 0 ; i < numberObjects ; i++) {
00199           CbcObject * object = dynamic_cast<CbcObject *>
00200               (simpleIntegerObjects[i]);
00201           int iCol = object->columnNumber();
00202           if (priorities)
00203             object->setPriority(priorities[iCol]);
00204           if (directions)
00205             object->setPreferredWay(directions[iCol]);
00206           if (upPsCosts) {
00207             CbcSimpleIntegerPseudoCost * pscObject =
00208               dynamic_cast<CbcSimpleIntegerPseudoCost*> (object);
00209             pscObject->setUpPseudoCost(upPsCosts[iCol]);
00210             pscObject->setDownPseudoCost(downPsCosts[iCol]);
00211           }
00212         }
00213       }
00214 
00215 #if 1
00216       // Now pass user set Sos constraints (code inspired from CoinSolve.cpp)
00217       const TMINLP::SosInfo * sos = s.nonlinearSolver()->model()->sosConstraints();
00218       if (!s.getIntParameter(BabSetupBase::DisableSos) && sos && sos->num > 0) 
00219         //we have some sos constraints
00220       {
00221         const OsiTMINLPInterface * nlpSolver = s.nonlinearSolver();
00222         const int & numSos = sos->num;
00223        (*nlpSolver->messageHandler())<<"Adding "<<sos->num<<" sos constraints."
00224                                      <<CoinMessageEol;
00225 
00226         CbcObject ** objects = new CbcObject*[numSos];
00227         const int * starts = sos->starts;
00228         const int * indices = sos->indices;
00229         const char * types = sos->types;
00230         const double * weights = sos->weights;
00231         //verify if model has user set priorities
00232         bool hasPriorities = false;
00233         const int * varPriorities = nlpSolver->getPriorities();
00234         int numberObjects = model_.numberObjects();
00235         if (varPriorities)
00236         {
00237           for (int i = 0 ; i < numberObjects ; i++) {
00238             if (varPriorities[i]) {
00239               hasPriorities = true;
00240               break;
00241             }
00242           }
00243         }
00244         const int * sosPriorities = sos->priorities;
00245         if (sosPriorities)
00246         {
00247           for (int i = 0 ; i < numSos ; i++) {
00248             if (sosPriorities[i]) {
00249               hasPriorities = true;
00250               break;
00251             }
00252           }
00253         }
00254         for (int i = 0 ; i < numSos ; i++)
00255         {
00256           int start = starts[i];
00257           int length = starts[i + 1] - start;
00258 #ifdef DO_IT_NWAY
00259           printf("setting nway object\n"),
00260           objects[i] = new CbcNWay(&model_, length, &indices[start],
00261               i);
00262           objects[i]->setPriority(1);
00263 #else
00264           objects[i] = new CbcSOS(&model_, length, &indices[start],
00265               &weights[start], i, types[i]);
00266           objects[i]->setPriority(10);
00267 #endif
00268           if (hasPriorities && sosPriorities && sosPriorities[i]) {
00269             objects[i]->setPriority(sosPriorities[i]);
00270           }
00271         }
00272         model_.addObjects(numSos, objects);
00273         for (int i = 0 ; i < numSos ; i++)
00274           delete objects[i];
00275         delete [] objects;
00276       }
00277 #endif
00278       //If Setup contains more objects add them to Cbc
00279       if (s.objects().size()) {
00280         CbcObject ** objects = new CbcObject *[s.objects().size()];
00281         for (unsigned int i = 0 ; i < s.objects().size() ; i++) {
00282           objects[i] = dynamic_cast<CbcObject *> (s.objects()[i]);
00283           assert(objects[i]);
00284           objects[i]->setModel(&model_);
00285         }
00286         model_.addObjects(s.objects().size(), objects);
00287         delete [] objects;
00288       }
00289 
00290       replaceIntegers(model_.objects(), model_.numberObjects());
00291     }
00292     else {//Pass in objects to Cbc
00293     // Redundant definition of default branching (as Default == User)
00294     assert (s.branchingMethod() != NULL);
00295 
00296     if (!usingCouenne_)
00297       model_.addObjects (s.continuousSolver()->numberObjects(),
00298                          s.continuousSolver()->objects());
00299     else {
00300       // add nonlinear and integer objects (need to add OsiSOS)
00301       int nco = s.continuousSolver () -> numberObjects ();
00302       OsiObject **objs = new OsiObject * [nco];
00303       for (int i=0; i<nco; i++) 
00304         objs [i] = s.continuousSolver () -> objects () [i];
00305       model_.addObjects (nco, objs);
00306       delete [] objs;
00307     }
00308 
00309     CbcBranchDefaultDecision branch;
00310     s.branchingMethod()->setSolver(model_.solver());
00311     BonChooseVariable * strong2 = dynamic_cast<BonChooseVariable *>(s.branchingMethod());
00312     if (strong2)
00313       strong2->setCbcModel(&model_);
00314     branch.setChooseMethod(*s.branchingMethod());
00315 
00316     model_.setBranchingMethod(&branch);
00317         // prevent duplicating object when copying in CbcModel.cpp
00318         model_.solver()->deleteObjects();
00319     }
00320 
00321     model_.setDblParam(CbcModel::CbcCutoffIncrement, s.getDoubleParameter(BabSetupBase::CutoffDecr));
00322 
00323     model_.setCutoff(s.getDoubleParameter(BabSetupBase::Cutoff) + CUTOFF_TOL);
00324 
00325     model_.setDblParam(CbcModel::CbcAllowableGap, s.getDoubleParameter(BabSetupBase::AllowableGap));
00326     model_.setDblParam(CbcModel::CbcAllowableFractionGap, s.getDoubleParameter(BabSetupBase::AllowableFractionGap));
00327 
00328     // Definition of node selection strategy
00329 
00330     if (s.nodeComparisonMethod()==BabSetupBase::bestBound) {
00331       CbcCompareObjective compare;
00332       model_.setNodeComparison(compare);
00333     }
00334     else if (s.nodeComparisonMethod()==BabSetupBase::DFS) {
00335       CbcCompareDepth compare;
00336       model_.setNodeComparison(compare);
00337     }
00338     else if (s.nodeComparisonMethod()==BabSetupBase::BFS) {
00339       CbcCompareDefault compare;
00340       compare.setWeight(0.0);
00341       model_.setNodeComparison(compare);
00342     }
00343     else if (s.nodeComparisonMethod()==BabSetupBase::dynamic) {
00344       CbcCompareDefault compare;
00345       model_.setNodeComparison(compare);
00346     }
00347     else if (s.nodeComparisonMethod()==BabSetupBase::bestGuess) {
00348       // Right now, this is a mess.  We need a separation of the
00349       // pseudo costs from the ChooseVariable method
00350       CbcCompareEstimate compare;
00351       model_.setNodeComparison(compare);
00352       GuessHeuristic * guessHeu = new GuessHeuristic(model_);
00353       model_.addHeuristic(guessHeu);
00354       delete guessHeu;
00355     }
00356 
00357     if (s.treeTraversalMethod() == BabSetupBase::HeapOnly) {
00358       //Do nothing this is the default of Cbc.
00359     }
00360     else if (s.treeTraversalMethod() == BabSetupBase::DiveFromBest) {
00361       CbcDiver treeTraversal;
00362       treeTraversal.initialize(s);
00363       model_.passInTreeHandler(treeTraversal);
00364     }
00365     else if (s.treeTraversalMethod() == BabSetupBase::ProbedDive) {
00366       CbcProbedDiver treeTraversal;
00367       treeTraversal.initialize(s);
00368       model_.passInTreeHandler(treeTraversal);
00369     }
00370     else if (s.treeTraversalMethod() == BabSetupBase::DfsDiveFromBest) {
00371       CbcDfsDiver treeTraversal;
00372       treeTraversal.initialize(s);
00373       model_.passInTreeHandler(treeTraversal);
00374     }
00375     else if (s.treeTraversalMethod() == BabSetupBase::DfsDiveDynamic) {
00376       CbcDfsDiver treeTraversal;
00377       treeTraversal.initialize(s);
00378       model_.passInTreeHandler(treeTraversal);
00379 
00380       DiverCompare compare;
00381       compare.setComparisonDive(*model_.nodeComparison());
00382       compare.setComparisonBound(CbcCompareObjective());
00383       CbcDfsDiver * dfs = dynamic_cast<CbcDfsDiver *> (model_.tree());
00384       assert(dfs);
00385       compare.setDiver(dfs);
00386       model_.setNodeComparison(compare);
00387     }
00388 
00389     model_.setNumberStrong(s.getIntParameter(BabSetupBase::NumberStrong));
00390 
00391     model_.setNumberBeforeTrust(s.getIntParameter(BabSetupBase::MinReliability));
00392     model_.setNumberPenalties(8);
00393 
00394     model_.setDblParam(CbcModel::CbcMaximumSeconds, s.getDoubleParameter(BabSetupBase::MaxTime));
00395 
00396     model_.setMaximumNodes(s.getIntParameter(BabSetupBase::MaxNodes));
00397 
00398     model_.setMaximumNumberIterations(s.getIntParameter(BabSetupBase::MaxIterations));
00399 
00400     model_.setMaximumSolutions(s.getIntParameter(BabSetupBase::MaxSolutions));
00401 
00402     model_.setIntegerTolerance(s.getDoubleParameter(BabSetupBase::IntTol));
00403 
00404 
00405 
00406     //Get objects from model_ if it is not null means there are some sos constraints or non-integer branching object
00407     // pass them to cut generators.
00408     OsiObject ** objects = model_.objects();
00409     if (specOpt!=16 && objects) {
00410       int numberObjects = model_.numberObjects();
00411       if (objects_ != NULL) {
00412         for (int i = 0 ; i < nObjects_; i++)
00413           delete objects_[i];
00414       }
00415       delete [] objects_;
00416       objects_ = new OsiObject*[numberObjects];
00417       nObjects_ = numberObjects;
00418       for (int i = 0 ; i < numberObjects; i++) {
00419         OsiObject * obj = objects[i];
00420         CbcSimpleInteger * intObj = dynamic_cast<CbcSimpleInteger *> (obj);
00421         if (intObj) {
00422           objects_[i] = intObj->osiObject();
00423         }
00424         else {
00425           CbcSOS * sosObj = dynamic_cast<CbcSOS *>(obj);
00426           if (sosObj) objects_[i] = sosObj->osiObject(model_.solver());
00427           else {//Maybe an unsupported CbcObject
00428             CbcObject * cbcObj = dynamic_cast<CbcObject *>(obj);
00429             if (cbcObj) {
00430               std::cerr<<"Unsupported CbcObject appears in the code"<<std::endl;
00431               throw UNSUPPORTED_CBC_OBJECT;
00432             }
00433             else {//It has to be an OsiObject.
00434               objects_[i]=obj->clone();
00435             }
00436           }
00437         }
00438       }
00439       CbcCutGenerator ** gen = model_.cutGenerators();
00440       int numGen = model_.numberCutGenerators();
00441       for (int i = 0 ; i < numGen ; i++) {
00442         OaDecompositionBase * oa = dynamic_cast<OaDecompositionBase * >(gen[i]->generator());
00443         if (oa)//pass objects
00444           oa->setObjects(objects_,nObjects_);
00445       }
00446     }
00447 
00448 
00449     try {
00450     //Get the time and start.
00451     {
00452       OsiTMINLPInterface * tmpOsi = NULL;
00453       if(s.nonlinearSolver() == s.continuousSolver()){
00454         tmpOsi = dynamic_cast<OsiTMINLPInterface *> (model_.solver());
00455         tmpOsi->forceSolverOutput(s.getIntParameter(BabSetupBase::RootLogLevel)); 
00456       }
00457       model_.initialSolve();
00458       if(tmpOsi != NULL){
00459         tmpOsi->setSolverOutputToDefault(); 
00460       }
00461     }
00462 
00463     int ival;
00464     s.options()->GetEnumValue("enable_dynamic_nlp", ival, "bonmin.");
00465     if(s.nonlinearSolver() == s.continuousSolver() && ival)
00466     {
00467       if(!model_.solver()->isProvenOptimal() ){//Something went wrong check if objective is linear and alternate model
00468                                             // can be solved
00469         OsiTMINLPInterface * tmpOsi = dynamic_cast<OsiTMINLPInterface *> (model_.solver());
00470         TMINLPLinObj * tmp_tminlp = dynamic_cast<TMINLPLinObj *> (tmpOsi->model());
00471         tmpOsi->setModel(tmp_tminlp->tminlp());
00472         model_.initialSolve();
00473       } 
00474       else {
00475         LinearCutsGenerator cgl;
00476         cgl.initialize(s); 
00477         OsiCuts cuts;
00478         cgl.generateCuts(*model_.solver(), cuts);
00479         std::vector<OsiRowCut *> mycuts(cuts.sizeRowCuts());
00480         for(int i = 0 ; i < cuts.sizeRowCuts() ; i++){
00481           mycuts[i] = cuts.rowCutPtr(i);
00482         }
00483         model_.solver()->applyRowCuts(mycuts.size(), (const OsiRowCut **) &mycuts[0]);
00484       }
00485 
00486        //Added by Claudia
00487        OsiTMINLPInterface * nlpSolver = dynamic_cast<OsiTMINLPInterface *>(model_.solver());
00488        if(nlpSolver && nlpSolver->getNewCutoffDecr()!=COIN_DBL_MAX)
00489           model_.setDblParam(CbcModel::CbcCutoffIncrement, nlpSolver->getNewCutoffDecr());
00490 
00491        model_.solver()->resolve();
00492 
00493     }
00494 
00495     // for Couenne
00496     if (usingCouenne_)
00497       model_.passInSolverCharacteristics (bonBabInfoPtr);
00498 
00499     continuousRelaxation_ =model_.solver()->getObjValue();
00500     if (specOpt==16)//Set warm start point for Ipopt
00501     {
00502 #if 1
00503       const double * colsol = model_.solver()->getColSolution();
00504       const double * duals = model_.solver()->getRowPrice();
00505 
00506       OsiTMINLPInterface * tnlpSolver = dynamic_cast<OsiTMINLPInterface *>(model_.solver());
00507       // Primal dual point is not copied if one (supposedely a better one) has already been put into the solver.
00508       if(tnlpSolver->problem()->has_x_init() != 2){
00509         model_.solver()->setColSolution(colsol);
00510         model_.solver()->setRowPrice(duals);
00511       }
00512 #else
00513       OsiTMINLPInterface * tnlpSolver = dynamic_cast<OsiTMINLPInterface *>(model_.solver());
00514       CoinWarmStart * warm = tnlpSolver->solver()->getWarmStart(tnlpSolver->problem());
00515       tnlpSolver->solver()->setWarmStart(warm, tnlpSolver->problem());
00516       delete warm;
00517 #endif
00518 
00519 #if 0 // Sometimes primal dual point is problematic in the context of Cut-and-branch
00520     model_.solver()->resolve();
00521     if(!model_.solver()->isProvenOptimal())
00522        model_.solver()->setColSolution(NULL);
00523 #endif 
00524     }
00525 
00526 #ifdef SIGNAL
00527     CoinSighandler_t saveSignal=SIG_DFL;
00528     // register signal handler
00529     saveSignal = signal(SIGINT,signal_handler);
00530 #endif
00531 
00532     currentBranchModel = &model_;
00533 
00534     // to get node parent info in Cbc, pass parameter 3.
00535     //model_.branchAndBound(3);
00536     remaining_time -= CoinCpuTime();
00537     model_.setDblParam(CbcModel::CbcMaximumSeconds, remaining_time);
00538     if(remaining_time > 0.)
00539       model_.branchAndBound();
00540     }
00541     catch(TNLPSolver::UnsolvedError *E){
00542       s.nonlinearSolver()->model()->finalize_solution(TMINLP::MINLP_ERROR,
00543            0,
00544            NULL,
00545            DBL_MAX);
00546       throw E;
00547    
00548     }
00549     numNodes_ = model_.getNodeCount();
00550     bestObj_ = model_.getObjValue();
00551     bestBound_ = model_.getBestPossibleObjValue();
00552     mipIterationCount_ = model_.getIterationCount();
00553 
00554     bool hasFailed = false;
00555     if (specOpt==16)//Did we continue branching on a failure
00556     {
00557       CbcNlpStrategy * nlpStrategy = dynamic_cast<CbcNlpStrategy *>(model_.strategy());
00558       if (nlpStrategy)
00559         hasFailed = nlpStrategy->hasFailed();
00560       else
00561         throw -1;
00562     }
00563     else
00564       hasFailed = s.nonlinearSolver()->hasContinuedOnAFailure();
00565 
00566     // Output summarizing cut generators (taken from CbcSolver.cpp)
00567     // ToDo put into proper print level
00568 
00569     
00570 
00571     int numberGenerators = model_.numberCutGenerators();
00572     for (int iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
00573       CbcCutGenerator * generator = model_.cutGenerator(iGenerator);
00574       //CglStored * stored = dynamic_cast<CglStored*>(generator->generator());
00575       if (true&&!(generator->numberCutsInTotal() || generator->numberColumnCuts()))
00576         continue;
00577        if(modelHandler_->logLevel() >= 1) {
00578         *modelHandler_ << generator->cutGeneratorName()
00579                 << "was tried" << generator->numberTimesEntered()
00580                 << "times and created" << generator->numberCutsInTotal()+generator->numberColumnCuts()
00581                 << "cuts of which" << generator->numberCutsActive()
00582                 << "were active after adding rounds of cuts";
00583          if (generator->timing()) {
00584                 char timebuf[20];
00585                 sprintf(timebuf, "(%.3fs)", generator->timeInCutGenerator());
00586                 *modelHandler_ << timebuf << CoinMessageEol;
00587          }
00588          else {
00589                 *modelHandler_ << CoinMessageEol;
00590          }
00591        }
00592     }
00593 
00594     if (hasFailed && !usingCouenne_) {
00595         *model_.messageHandler()
00596       << "************************************************************" << CoinMessageEol
00597       << "WARNING : Optimization failed on an NLP during optimization"  << CoinMessageEol
00598       << "  (no optimal value found within tolerances)."  << CoinMessageEol
00599       << "  Optimization was not stopped because option"  << CoinMessageEol
00600       << "\"nlp_failure_behavior\" has been set to fathom but"  << CoinMessageEol
00601       << " beware that reported solution may not be optimal"  << CoinMessageEol
00602       << "************************************************************" << CoinMessageEol;
00603     }
00604     TMINLP::SolverReturn status = TMINLP::MINLP_ERROR;
00605 
00606     if (model_.numberObjects()==0) {
00607       if (bestSolution_)
00608         delete [] bestSolution_;
00609       OsiSolverInterface * solver = 
00610              (s.nonlinearSolver() == s.continuousSolver())? 
00611              model_.solver() : s.nonlinearSolver();
00612       bestSolution_ = new double[solver->getNumCols()];
00613       CoinCopyN(solver->getColSolution(), solver->getNumCols(),
00614           bestSolution_);
00615       bestObj_ = bestBound_ = solver->getObjValue();
00616     }
00617 
00618     if (bonBabInfoPtr->bestSolution2().size() > 0) {
00619       assert((int) bonBabInfoPtr->bestSolution2().size() == s.nonlinearSolver()->getNumCols());
00620       if (bestSolution_)
00621         delete [] bestSolution_;
00622       bestSolution_ = new double[s.nonlinearSolver()->getNumCols()];
00623       std::copy(bonBabInfoPtr->bestSolution2().begin(), bonBabInfoPtr->bestSolution2().end(),
00624           bestSolution_);
00625       bestObj_ = (bonBabInfoPtr->bestObj2());
00626        (*s.nonlinearSolver()->messageHandler())<<"\nReal objective function: "
00627                                             <<bestObj_<<CoinMessageEol;
00628     }
00629     else if (model_.bestSolution()) {
00630       if (bestSolution_)
00631         delete [] bestSolution_;
00632       bestSolution_ = new double[s.nonlinearSolver()->getNumCols()];
00633       CoinCopyN(model_.bestSolution(), s.nonlinearSolver()->getNumCols(), bestSolution_);
00634     }
00635     if(remaining_time <= 0.){
00636       status = TMINLP::LIMIT_EXCEEDED;
00637       if (bestSolution_) {
00638         mipStatus_ = Feasible;
00639       }
00640     }
00641     else if (model_.status() == 0) {
00642       if(model_.isContinuousUnbounded()){
00643         status = TMINLP::CONTINUOUS_UNBOUNDED;
00644         mipStatus_ = UnboundedOrInfeasible;
00645       }
00646       else
00647       if (bestSolution_) {
00648         status = TMINLP::SUCCESS;
00649         mipStatus_ = FeasibleOptimal;
00650       }
00651       else {
00652         status = TMINLP::INFEASIBLE;
00653         mipStatus_ = ProvenInfeasible;
00654       }
00655     }
00656     else if (model_.status() == 1) {
00657       status = TMINLP::LIMIT_EXCEEDED;
00658       if (bestSolution_) {
00659         mipStatus_ = Feasible;
00660       }
00661       else {
00662         mipStatus_ = NoSolutionKnown;
00663       }
00664     }
00665     else if (model_.status()==2) {
00666       status = TMINLP::MINLP_ERROR;
00667     }
00668     s.nonlinearSolver()->model()->finalize_solution(status,
00669         s.nonlinearSolver()->getNumCols(),
00670         bestSolution_,
00671         bestObj_);
00672   }
00673 
00674 
00676   double
00677   Bab::bestBound()
00678   {
00679     if (mipStatus_ == FeasibleOptimal) return bestObj_;
00680     else if (mipStatus_ == ProvenInfeasible) return 1e200;
00681     else return bestBound_;
00682   }
00683 
00684 
00685 }

Generated on Wed Nov 30 03:03:54 2011 by  doxygen 1.4.7