/home/coin/SVN-release/OS-2.4.0/Bonmin/src/Algorithms/OaGenerators/BonOaNlpOptim.cpp

Go to the documentation of this file.
00001 // (C) Copyright Carnegie Mellon University 2005
00002 // All Rights Reserved.
00003 // This code is published under the Common Public License.
00004 //
00005 // Authors :
00006 // P. Bonami, Carnegie Mellon University
00007 //
00008 // Date :  05/26/2005
00009 
00010 #include "BonOaNlpOptim.hpp"
00011 #include "OsiAuxInfo.hpp"
00012 #include "CbcModel.hpp"
00013 #include "BonBabInfos.hpp"
00014 #include "BonCbc.hpp"
00015 
00016 namespace Bonmin
00017 {
00018    static const char * txt_id = "NLP relax. for OA";
00019 
00021   OaNlpOptim::OaNlpOptim(OsiTMINLPInterface * si,
00022       int maxDepth, bool addOnlyViolated, bool global)
00023       :
00024       CglCutGenerator(),
00025       nlp_(si),
00026       maxDepth_(maxDepth),
00027       nSolve_(0),
00028       addOnlyViolated_(addOnlyViolated),
00029       global_(global)
00030   {
00031     handler_ = new CoinMessageHandler();
00032     handler_ -> setLogLevel(1);
00033     messages_ = OaMessages();
00034   }
00035 
00036   OaNlpOptim::OaNlpOptim(BabSetupBase &b):
00037       CglCutGenerator(),
00038       nlp_(b.nonlinearSolver()),
00039       maxDepth_(1000),
00040       nSolve_(0)
00041   {
00042     int ivalue;
00043     b.options()->GetEnumValue("add_only_violated_oa", ivalue,b.prefix());
00044     addOnlyViolated_ = ivalue;
00045     b.options()->GetEnumValue("oa_cuts_scope", ivalue,b.prefix());
00046     global_ = ivalue;
00047 
00048     b.options()->GetIntegerValue("nlp_solve_max_depth", maxDepth_,b.prefix());
00049     b.options()->GetNumericValue("nlp_solves_per_depth", solves_per_level_,b.prefix());
00050     handler_ = new CoinMessageHandler();
00051     handler_ -> setLogLevel(1);
00052     messages_ = OaMessages();
00053   }
00055   void
00056   OaNlpOptim::assignInterface(OsiTMINLPInterface * si)
00057 
00058   {
00059     nlp_ = si;
00060   }
00062   void
00063   OaNlpOptim::generateCuts( const OsiSolverInterface & si, OsiCuts & cs,
00064       const CglTreeInfo info) const
00065   {
00066     if (nlp_ == NULL) {
00067       CoinError("Error in cut generator for outer approximation no ipopt NLP assigned", "generateCuts", "OaNlpOptim");
00068     }
00069 
00070     int numcols = nlp_->getNumCols();
00071 
00072     //Get the continuous solution
00073     //const double *colsol = si.getColSolution();
00074     //Check for integer feasibility
00075    if(!info.inTree || info.pass > 0) return;
00076 #if 1
00077     BabInfo * babInfo = dynamic_cast<BabInfo *> (si.getAuxiliaryInfo());
00078     assert(babInfo);
00079     assert(babInfo->babPtr());
00080     const CbcNode * node = babInfo->babPtr()->model().currentNode();
00081     int level = (node == NULL) ? 0 : babInfo->babPtr()->model().currentNode()->depth();
00082     if (info.level > maxDepth_)
00083       return;
00084     if(solves_per_level_ < 1e10){
00085       double rand = CoinDrand48();
00086       double score = pow(2.,-level)*solves_per_level_;
00087       //printf("depth %i, score %g , rand %g\n", level, score, rand);
00088       if (score <= rand)
00089         return;
00090     }
00091 #endif
00092     //Fix the variable which have to be fixed, after having saved the bounds
00093     double * saveColLb = new double[numcols];
00094     double * saveColUb = new double[numcols];
00095     CoinCopyN(nlp_->getColLower(), numcols , saveColLb);
00096     CoinCopyN(nlp_->getColUpper(), numcols , saveColUb);
00097     for (int i = 0; i < numcols ; i++) {
00098       if (nlp_->isInteger(i)) {
00099         nlp_->setColBounds(i,si.getColLower()[i],si.getColUpper()[i]);
00100       }
00101     }
00102 
00103     //Now solve the NLP get the cuts, reset bounds and get out
00104 
00105     //  nlp_->turnOnIpoptOutput();
00106     nSolve_++;
00107     nlp_->resolve(txt_id);
00108     const double * violatedPoint = (addOnlyViolated_)? si.getColSolution():
00109         NULL;
00110     nlp_->getOuterApproximation(cs, 1, violatedPoint,global_);
00111     if (nlp_->isProvenOptimal()) {
00112       handler_->message(LP_ERROR,messages_)
00113       <<nlp_->getObjValue()-si.getObjValue()<<CoinMessageEol;
00114       bool feasible = 1;
00115       const double * colsol2 = nlp_->getColSolution();
00116       for (int i = 0 ; i < numcols && feasible; i++) {
00117         if (nlp_->isInteger(i)) {
00118           if (fabs(colsol2[i] - floor(colsol2[i] + 0.5) ) > 1e-07)
00119             feasible = 0;
00120         }
00121       }
00122       if (feasible ) {
00123 #if 1
00124         // Also store into solver
00125         OsiAuxInfo * auxInfo = si.getAuxiliaryInfo();
00126         OsiBabSolver * auxiliaryInfo = dynamic_cast<OsiBabSolver *> (auxInfo);
00127         if (auxiliaryInfo) {
00128           double * lpSolution = new double[numcols + 1];
00129           CoinCopyN(colsol2, numcols, lpSolution);
00130           lpSolution[numcols] = nlp_->getObjValue();
00131           auxiliaryInfo->setSolution(lpSolution, numcols + 1, lpSolution[numcols]);
00132           delete [] lpSolution;
00133         }
00134         else
00135           fprintf(stderr,"No auxiliary info in nlp solve!\n");
00136 #endif
00137 
00138       }
00139     }
00140     else if (nlp_->isAbandoned() || nlp_->isIterationLimitReached()) {
00141       throw CoinError("Unsolved NLP ... exit", "generateCuts", "OaNlpOptim");
00142     }
00143     else {
00144       //       //Add an infeasibility local constraint
00145       //       CoinPackedVector v;
00146       //       double rhs = 1.;
00147       //       for(int i = 0; i < numcols ; i++)
00148       //        {
00149       //          if(nlp_->isInteger(i) && (si.getColUpper()[i] - si.getColLower()[i] < 0.9))
00150       //            {
00151       //              double value = floor(colsol[i] + 0.5);
00152       //              assert(fabs(colsol[i]-value)<1e-8 && value >= -1e-08 && value <= 1+ 1e08);
00153       //              v.insert(i, -(2*value - 1));
00154       //              rhs -= value;
00155       //            }
00156       //        }
00157       //       OsiRowCut cut;
00158       //       cut.setRow(v);
00159       //       cut.setLb(rhs);
00160       //       cut.setUb(1e300);
00161       //       cut.setGloballyValid();
00162       //       cs.insert(cut);
00163     }
00164     for (int i = 0; i < numcols ; i++) {
00165       if (nlp_->isInteger(i)) {
00166         nlp_->setColBounds(i,saveColLb[i],saveColUb[i]);
00167       }
00168     }
00169 #if 0
00170     nlp_->deleteLastRows(numberCuts);
00171 #endif
00172     delete [] saveColLb;
00173     delete [] saveColUb;
00174   }
00175 
00176   void
00177   OaNlpOptim::registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions)
00178   {
00179     roptions->SetRegisteringCategory("Nlp solve options in B-Hyb", RegisteredOptions::BonminCategory);
00180     roptions->AddLowerBoundedIntegerOption("nlp_solve_frequency",
00181         "Specify the frequency (in terms of nodes) at which NLP relaxations are solved in B-Hyb.",
00182         0,10,
00183         "A frequency of 0 amounts to to never solve the NLP relaxation.");
00184     roptions->setOptionExtraInfo("nlp_solve_frequency",1);
00185     roptions->AddLowerBoundedIntegerOption("nlp_solve_max_depth",
00186         "Set maximum depth in the tree at which NLP relaxations are solved in B-Hyb.",
00187         0,10,
00188         "A depth of 0 amounts to to never solve the NLP relaxation.");
00189     roptions->setOptionExtraInfo("nlp_solve_max_depth",1);
00190     roptions->AddLowerBoundedNumberOption("nlp_solves_per_depth",
00191         "Set average number of nodes in the tree at which NLP relaxations are solved in B-Hyb for each depth.",
00192         0.,false,1e100);
00193     roptions->setOptionExtraInfo("nlp_solves_per_depth",1);
00194   }
00195 
00196 
00197 }/* End namespace Bonmin. */

Generated on Thu Sep 22 03:05:53 2011 by  doxygen 1.4.7