00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "BonOaFeasChecker.hpp"
00012 #include "BonminConfig.h"
00013
00014 #include "OsiAuxInfo.hpp"
00015
00016
00017
00018 namespace Bonmin
00019 {
00020
00021
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
00054 double milpBound = -COIN_DBL_MAX;
00055 int numberPasses = 0;
00056 double * nlpSol = NULL;
00057 while (isInteger && feasible ) {
00058 numberPasses++;
00059
00060
00061 int numberCutsBefore = cs2.sizeRowCuts();
00062
00063
00064 double * colsol = const_cast<double *>(lp->getColSolution());
00065 info.solution_ = colsol;
00066 nlpManip.fixIntegers(info);
00067
00068
00069
00070
00071 if (solveNlp(babInfo, cutoff)) {
00072
00073
00074 cutoff = nlp_->getObjValue() *(1 - parameters_.cbcCutoffIncrement_);
00075
00076 lp->setDblParam(OsiDualObjectiveLimit, cutoff);
00077 }
00078
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
00093 feasible = (lp->isProvenOptimal() &&
00094 !lp->isDualObjectiveLimitReached() && (objvalue<cutoff)) ;
00095
00096 bool changed = true;
00097 isInteger = 0;
00098
00099
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
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
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
00137 lp->resolve();
00138 delete basis;
00139 }
00140 #ifdef OA_DEBUG
00141
00142 std::cout<<"milpBound found: "<<milpBound<<std::endl;
00143 #endif
00144 return milpBound;
00145 }
00146
00147 }