/home/coin/SVN-release/OS-2.0.1/Bonmin/src/Algorithms/OaGenerators/BonOaFeasChecker.cpp

Go to the documentation of this file.
00001 // (C) Copyright International Business Machines 2006
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 : 12/26/2006
00009 //#define OA_DEBUG
00010 
00011 #include "BonOaFeasChecker.hpp"
00012 #include "BonminConfig.h"
00013 
00014 #include "OsiAuxInfo.hpp"
00015 //#define OA_DEBUG
00016 
00017 
00018 namespace Bonmin
00019 {
00020 
00021 // Default constructor
00022   OaFeasibilityChecker ::OaFeasibilityChecker
00023   (OsiTMINLPInterface * nlp,
00024    OsiSolverInterface * si,
00025    double cbcCutoffIncrement,
00026    double cbcIntegerTolerance,
00027    bool leaveSiUnchanged
00028   )
00029       :
00030       OaDecompositionBase(nlp,si,
00031           NULL, cbcCutoffIncrement,
00032           cbcIntegerTolerance, leaveSiUnchanged)
00033   {}
00034 
00036   OaFeasibilityChecker::OaFeasibilityChecker(BabSetupBase &b):
00037       OaDecompositionBase(b, false, true)
00038   {}
00039   OaFeasibilityChecker ::~OaFeasibilityChecker ()
00040   {}
00041 
00043   double
00044   OaFeasibilityChecker::performOa(OsiCuts & cs, solverManip &nlpManip, solverManip &lpManip,
00045       SubMipSolver * &subMip, OsiBabSolver * babInfo, double &cutoff) const
00046   {
00047     bool isInteger = true;
00048     bool feasible = 1;
00049 
00050     OsiCuts cs2;
00051     OsiSolverInterface * lp = lpManip.si();
00052     OsiBranchingInformation info(lp,false);
00053     //int numcols = lp->getNumCols();
00054     double milpBound = -COIN_DBL_MAX;
00055     int numberPasses = 0;
00056     double * nlpSol =  NULL;
00057     while (isInteger && feasible ) {
00058       numberPasses++;
00059 
00060       //setup the nlp
00061       int numberCutsBefore = cs2.sizeRowCuts();
00062 
00063       //Fix the variable which have to be fixed, after having saved the bounds
00064       double * colsol = const_cast<double *>(lp->getColSolution());
00065       info.solution_ = colsol;
00066       nlpManip.fixIntegers(info);
00067 
00068 
00069       //Now solve the NLP get the cuts, and intall them in the local LP
00070 
00071       if (solveNlp(babInfo, cutoff)) {
00072         //nlp solved and feasible
00073         // Update the cutoff
00074         cutoff = nlp_->getObjValue() *(1 - parameters_.cbcCutoffIncrement_);
00075         // Update the lp solver cutoff
00076         lp->setDblParam(OsiDualObjectiveLimit, cutoff);
00077       }
00078       // Get the cuts outer approximation at the current point
00079 
00080       nlpSol = const_cast<double *>(nlp_->getColSolution());
00081 
00082       const double * toCut = (parameter().addOnlyViolated_)?
00083           colsol:NULL;
00084       nlp_->getOuterApproximation(cs2, nlpSol, 1, toCut,
00085           parameter().global_);
00086       int numberCuts = cs2.sizeRowCuts() - numberCutsBefore;
00087       if (numberCuts > 0)
00088         lpManip.installCuts(cs2, numberCuts);
00089 
00090       lp->resolve();
00091       double objvalue = lp->getObjValue();
00092       //milpBound = max(milpBound, lp->getObjValue());
00093       feasible = (lp->isProvenOptimal() &&
00094           !lp->isDualObjectiveLimitReached() && (objvalue<cutoff)) ;
00095       //if value of integers are unchanged then we have to get out
00096       bool changed = true;//if lp is infeasible we don't have to check anything
00097       isInteger = 0;
00098       //          if(!fixed)//fathom on bounds
00099       //           milpBound = 1e200;
00100       if (feasible) {
00101         changed = nlpManip.isDifferentOnIntegers(lp->getColSolution());
00102       }
00103       if (changed) {
00104         info.solution_ = lp->getColSolution();
00105         isInteger = lpManip.integerFeasible(info);
00106       }
00107       else {
00108         isInteger = 0;
00109         //        if(!fixed)//fathom on bounds
00110          milpBound = 1e200;
00111       }
00112 #ifdef OA_DEBUG
00113       printf("Obj value after cuts %g %d rows\n",lp->getObjValue(),
00114           numberCuts) ;
00115 #endif
00116     }
00117     int numberCuts = cs2.sizeRowCuts();
00118     //Remove non tight cuts
00119     if(numberCuts)
00120     {
00121        int num_rows_before = lp->getNumRows() - numberCuts;
00122        vector<int> toDelete;
00123        toDelete.reserve(numberCuts);
00124        CoinWarmStartBasis * basis = dynamic_cast<CoinWarmStartBasis *> (lp->getWarmStart());
00125        assert(basis);
00126        for(int i = 0 ; i < numberCuts ; i++){
00127           int idx = i + num_rows_before;
00128           if(basis->getArtifStatus(idx) == CoinWarmStartBasis::basic){
00129              toDelete.push_back(idx);
00130           }
00131           else {
00132             cs.insert(cs2.rowCut(i));
00133           }
00134        }
00135        lp->deleteRows(toDelete.size(), toDelete());
00136        //printf("Remove %i cuts\n", toDelete.size());
00137        lp->resolve();
00138        delete basis;
00139     } 
00140 #ifdef OA_DEBUG
00141     //debug_.printEndOfProcedureDebugMessage(cs, foundSolution, milpBound, isInteger, feasible, std::cout);
00142     std::cout<<"milpBound found: "<<milpBound<<std::endl;
00143 #endif
00144     return milpBound;
00145   }
00146 
00147 }/* End namespace Bonmin. */

Generated on Thu Oct 8 03:02:54 2009 by  doxygen 1.4.7