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 OsiSolverInterface * lp = lpManip.si();
00051 OsiBranchingInformation info(lp,false);
00052
00053 double milpBound = -COIN_DBL_MAX;
00054 int numberPasses = 0;
00055 double * nlpSol = NULL;
00056 while (isInteger && feasible ) {
00057 numberPasses++;
00058
00059
00060 int numberCutsBefore = cs.sizeRowCuts();
00061
00062
00063 double * colsol = const_cast<double *>(lp->getColSolution());
00064 info.solution_ = colsol;
00065 nlpManip.fixIntegers(info);
00066
00067
00068
00069
00070 if (solveNlp(babInfo, cutoff)) {
00071
00072
00073 cutoff = nlp_->getObjValue() *(1 - parameters_.cbcCutoffIncrement_);
00074
00075 lp->setDblParam(OsiDualObjectiveLimit, cutoff);
00076 }
00077
00078
00079 nlpSol = const_cast<double *>(nlp_->getColSolution());
00080
00081 const double * toCut = (parameter().addOnlyViolated_)?
00082 colsol:NULL;
00083 nlp_->getOuterApproximation(cs, nlpSol, 1, toCut,
00084 parameter().global_);
00085 int numberCuts = cs.sizeRowCuts() - numberCutsBefore;
00086 if (numberCuts > 0)
00087 lpManip.installCuts(cs, numberCuts);
00088
00089 lp->resolve();
00090 double objvalue = lp->getObjValue();
00091
00092 feasible = (lp->isProvenOptimal() &&
00093 !lp->isDualObjectiveLimitReached() && (objvalue<cutoff)) ;
00094
00095 bool changed = true;
00096 isInteger = 0;
00097
00098
00099 if (feasible) {
00100 changed = nlpManip.isDifferentOnIntegers(lp->getColSolution());
00101 }
00102 if (changed) {
00103 info.solution_ = lp->getColSolution();
00104 isInteger = lpManip.integerFeasible(info);
00105 }
00106 else {
00107 isInteger = 0;
00108
00109 milpBound = 1e200;
00110 }
00111 #ifdef OA_DEBUG
00112 printf("Obj value after cuts %g %d rows\n",lp->getObjValue(),
00113 numberCuts) ;
00114 #endif
00115 }
00116 #ifdef OA_DEBUG
00117
00118 std::cout<<"milpBound found: "<<milpBound<<std::endl;
00119 #endif
00120 return milpBound;
00121 }
00122
00123 }