/home/coin/SVN-release/OS-2.0.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 
00013 namespace Bonmin
00014 {
00016   OaNlpOptim::OaNlpOptim(OsiTMINLPInterface * si,
00017       int maxDepth, bool addOnlyViolated, bool global)
00018       :
00019       CglCutGenerator(),
00020       nlp_(si),
00021       maxDepth_(maxDepth),
00022       nSolve_(0),
00023       addOnlyViolated_(addOnlyViolated),
00024       global_(global)
00025   {
00026     handler_ = new CoinMessageHandler();
00027     handler_ -> setLogLevel(1);
00028     messages_ = OaMessages();
00029   }
00030 
00031   OaNlpOptim::OaNlpOptim(BabSetupBase &b):
00032       CglCutGenerator(),
00033       nlp_(b.nonlinearSolver()),
00034       maxDepth_(1000),
00035       nSolve_(0)
00036   {
00037     int ivalue;
00038     b.options()->GetEnumValue("add_only_violated_oa", ivalue,"bonmin.");
00039     addOnlyViolated_ = ivalue;
00040     b.options()->GetEnumValue("oa_cuts_scope", ivalue,"bonmin.");
00041     global_ = ivalue;
00042 
00043     b.options()->GetIntegerValue("nlp_solve_max_depth", maxDepth_,"bonmin.");
00044     b.options()->GetNumericValue("nlp_solves_per_depth", solves_per_level_,"bonmin.");
00045     handler_ = new CoinMessageHandler();
00046     handler_ -> setLogLevel(1);
00047     messages_ = OaMessages();
00048   }
00050   void
00051   OaNlpOptim::assignInterface(OsiTMINLPInterface * si)
00052 
00053   {
00054     nlp_ = si;
00055   }
00056   static int nCalls = 0;
00058   void
00059   OaNlpOptim::generateCuts( const OsiSolverInterface & si, OsiCuts & cs,
00060       const CglTreeInfo info) const
00061   {
00062     if (nlp_ == NULL) {
00063       CoinError("Error in cut generator for outer approximation no ipopt NLP assigned", "generateCuts", "OaNlpOptim");
00064     }
00065 
00066     int numcols = nlp_->getNumCols();
00067 
00068     //Get the continuous solution
00069     //const double *colsol = si.getColSolution();
00070     //Check for integer feasibility
00071     nCalls++;
00072     double rand = CoinDrand48();
00073     if (info.level > maxDepth_ || info.pass > 0 || !info.inTree  ||
00074         pow(2.,-info.level)*solves_per_level_ <= rand)
00075       return;
00076     //Fix the variable which have to be fixed, after having saved the bounds
00077     double * saveColLb = new double[numcols];
00078     double * saveColUb = new double[numcols];
00079     CoinCopyN(nlp_->getColLower(), numcols , saveColLb);
00080     CoinCopyN(nlp_->getColUpper(), numcols , saveColUb);
00081     for (int i = 0; i < numcols ; i++) {
00082       if (nlp_->isInteger(i)) {
00083         nlp_->setColBounds(i,si.getColLower()[i],si.getColUpper()[i]);
00084       }
00085     }
00086 
00087 #if 0
00088 //Add tight cuts at LP optimum
00089     int numberCuts = si.getNumRows() - nlp_->getNumRows();
00090     const OsiRowCut ** cuts = new const OsiRowCut*[numberCuts];
00091     int begin = nlp_->getNumRows();
00092     numberCuts = 0;
00093     int end = si.getNumRows();
00094     const double * rowLower = si.getRowLower();
00095     const double * rowUpper = si.getRowUpper();
00096     const CoinPackedMatrix * mat = si.getMatrixByRow();
00097     const CoinBigIndex * starts = mat->getVectorStarts();
00098     const int * lengths = mat->getVectorLengths();
00099     const double * elements = mat->getElements();
00100     const int * indices = mat->getIndices();
00101 
00102     for (int i = begin ; i < end ; i++, numberCuts++) {
00103       bool nnzExists=false;
00104       for (int k = starts[i] ; k < starts[i]+lengths[i] ; k++) {
00105         if (indices[k] == nlp_->getNumCols()) {
00106           nnzExists = true;
00107           char sign = (elements[k]>0.)?'+':'-';
00108           char type='<';
00109           if (rowLower[i]>-1e20) type='>';
00110         }
00111       }
00112       if (nnzExists) {
00113         numberCuts--;
00114         continue;
00115       }
00116       int * indsCopy = CoinCopyOfArray(&indices[starts[i]], lengths[i]);
00117       double * elemsCopy = CoinCopyOfArray(&elements[starts[i]], lengths[i]);
00118       cuts[numberCuts] = new OsiRowCut(rowLower[i], rowUpper[i], lengths[i], lengths[i],
00119           indsCopy, elemsCopy);
00120     }
00121     nlp_->applyRowCuts(numberCuts,cuts);
00122 #endif
00123     //Now solve the NLP get the cuts, reset bounds and get out
00124 
00125     //  nlp_->turnOnIpoptOutput();
00126     nSolve_++;
00127     nlp_->resolve();
00128     const double * violatedPoint = (addOnlyViolated_)? si.getColSolution():
00129         NULL;
00130     nlp_->getOuterApproximation(cs, 1, violatedPoint,global_);
00131     if (nlp_->isProvenOptimal()) {
00132       handler_->message(LP_ERROR,messages_)
00133       <<nlp_->getObjValue()-si.getObjValue()<<CoinMessageEol;
00134       bool feasible = 1;
00135       const double * colsol2 = nlp_->getColSolution();
00136       for (int i = 0 ; i < numcols && feasible; i++) {
00137         if (nlp_->isInteger(i)) {
00138           if (fabs(colsol2[i] - floor(colsol2[i] + 0.5) ) > 1e-07)
00139             feasible = 0;
00140         }
00141       }
00142       if (feasible ) {
00143 #if 1
00144         // Also store into solver
00145         OsiAuxInfo * auxInfo = si.getAuxiliaryInfo();
00146         OsiBabSolver * auxiliaryInfo = dynamic_cast<OsiBabSolver *> (auxInfo);
00147         if (auxiliaryInfo) {
00148           double * lpSolution = new double[numcols + 1];
00149           CoinCopyN(colsol2, numcols, lpSolution);
00150           lpSolution[numcols] = nlp_->getObjValue();
00151           auxiliaryInfo->setSolution(lpSolution, numcols + 1, lpSolution[numcols]);
00152           delete [] lpSolution;
00153         }
00154         else
00155           printf("No auxiliary info in nlp solve!\n");
00156 #endif
00157 
00158       }
00159     }
00160     else if (nlp_->isAbandoned() || nlp_->isIterationLimitReached()) {
00161       throw CoinError("Unsolved NLP ... exit", "generateCuts", "OaNlpOptim");
00162     }
00163     else {
00164       //       //Add an infeasibility local constraint
00165       //       CoinPackedVector v;
00166       //       double rhs = 1.;
00167       //       for(int i = 0; i < numcols ; i++)
00168       //        {
00169       //          if(nlp_->isInteger(i) && (si.getColUpper()[i] - si.getColLower()[i] < 0.9))
00170       //            {
00171       //              double value = floor(colsol[i] + 0.5);
00172       //              assert(fabs(colsol[i]-value)<1e-8 && value >= -1e-08 && value <= 1+ 1e08);
00173       //              v.insert(i, -(2*value - 1));
00174       //              rhs -= value;
00175       //            }
00176       //        }
00177       //       OsiRowCut cut;
00178       //       cut.setRow(v);
00179       //       cut.setLb(rhs);
00180       //       cut.setUb(1e300);
00181       //       cut.setGloballyValid();
00182       //       cs.insert(cut);
00183     }
00184     for (int i = 0; i < numcols ; i++) {
00185       if (nlp_->isInteger(i)) {
00186         nlp_->setColBounds(i,saveColLb[i],saveColUb[i]);
00187       }
00188     }
00189 #if 0
00190     nlp_->deleteLastRows(numberCuts);
00191 #endif
00192     delete [] saveColLb;
00193     delete [] saveColUb;
00194   }
00195 
00196   void
00197   OaNlpOptim::registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions)
00198   {
00199     roptions->SetRegisteringCategory("Nlp solve options in B-Hyb", RegisteredOptions::BonminCategory);
00200     roptions->AddLowerBoundedIntegerOption("nlp_solve_frequency",
00201         "Specify the frequency (in terms of nodes) at which NLP relaxations are solved in B-Hyb.",
00202         0,10,
00203         "A frequency of 0 amounts to to never solve the NLP relaxation.");
00204     roptions->setOptionExtraInfo("nlp_solve_frequency",1);
00205     roptions->AddLowerBoundedIntegerOption("nlp_solve_max_depth",
00206         "Set maximum depth in the tree at which NLP relaxations are solved in B-Hyb.",
00207         0,10,
00208         "A depth of 0 amounts to to never solve the NLP relaxation.");
00209     roptions->setOptionExtraInfo("nlp_solve_max_depth",1);
00210     roptions->AddLowerBoundedNumberOption("nlp_solves_per_depth",
00211         "Set average number of nodes in the tree at which NLP relaxations are solved in B-Hyb for each depth.",
00212         0.,false,1e30);
00213     roptions->setOptionExtraInfo("nlp_solves_per_depth",1);
00214   }
00215 
00216 
00217 }/* End namespace Bonmin. */

Generated on Mon Aug 3 03:02:18 2009 by  doxygen 1.4.7