00001
00002 #include "BonLinearCutsGenerator.hpp"
00003 #include "BonTMINLP2Quad.hpp"
00004 #include "OsiClpSolverInterface.hpp"
00005
00006
00007 #include "CglGomory.hpp"
00008 #include "CglProbing.hpp"
00009 #include "CglKnapsackCover.hpp"
00010 #include "CglOddHole.hpp"
00011 #include "CglClique.hpp"
00012 #include "CglFlowCover.hpp"
00013 #include "CglMixedIntegerRounding2.hpp"
00014 #include "CglTwomir.hpp"
00015 #include "CglPreProcess.hpp"
00016 #include "CglLandP.hpp"
00017 #include "CglRedSplit.hpp"
00018
00019 namespace Bonmin {
00020
00021 void LinearCutsGenerator::initialize(BabSetupBase & s){
00022 assert(dynamic_cast<TMINLP2TNLPQuadCuts *> (s.nonlinearSolver()->problem()));
00023 int freq;
00024 s.options()->GetIntegerValue("Gomory_cuts", freq,"bonmin.");
00025 if (freq) {
00026 Coin::SmartPtr<CuttingMethod> cg = new CuttingMethod;
00027 cg->frequency = freq;
00028 CglGomory * gom = new CglGomory;
00029 cg->cgl = gom;
00030 gom->setLimitAtRoot(512);
00031 gom->setLimit(50);
00032 cg->id = "Mixed Integer Gomory";
00033 methods_.push_back(cg);
00034 }
00035
00036 s.options()->GetIntegerValue("mir_cuts",freq,"bonmin.");
00037 if (freq) {
00038 Coin::SmartPtr<CuttingMethod> cg = new CuttingMethod;
00039 cg->frequency = freq;
00040 CglMixedIntegerRounding2 * mir = new CglMixedIntegerRounding2;
00041 cg->cgl = mir;
00042 cg->id = "Mixed Integer Rounding";
00043 methods_.push_back(cg);
00044
00045
00046 }
00047 s.options()->GetIntegerValue("2mir_cuts",freq,"bonmin.");
00048 if (freq) {
00049 Coin::SmartPtr<CuttingMethod> cg = new CuttingMethod;
00050 cg->frequency = freq;
00051 CglTwomir * mir2 = new CglTwomir;
00052 cg->cgl = mir2;
00053 cg->id = "2-MIR";
00054 methods_.push_back(cg);
00055 }
00056 s.options()->GetIntegerValue("cover_cuts",freq,"bonmin.");
00057 if (freq) {
00058 Coin::SmartPtr<CuttingMethod> cg = new CuttingMethod;
00059 cg->frequency = freq;
00060 CglKnapsackCover * cover = new CglKnapsackCover;
00061 cg->cgl = cover;
00062 cg->id = "Cover";
00063 methods_.push_back(cg);
00064 }
00065
00066 s.options()->GetIntegerValue("clique_cuts",freq,"bonmin.");
00067 if (freq) {
00068 Coin::SmartPtr<CuttingMethod> cg = new CuttingMethod;
00069 cg->frequency = freq;
00070 CglClique * clique = new CglClique;
00071 clique->setStarCliqueReport(false);
00072 clique->setRowCliqueReport(false);
00073 clique->setMinViolation(0.1);
00074
00075 cg->cgl = clique;
00076 cg->id = "Clique";
00077 methods_.push_back(cg);
00078 }
00079 s.options()->GetIntegerValue("flow_cover_cuts",freq,"bonmin.");
00080 if (freq) {
00081 Coin::SmartPtr<CuttingMethod> cg = new CuttingMethod;
00082 cg->frequency = freq;
00083 CglFlowCover * flow = new CglFlowCover;
00084 cg->cgl = flow;
00085 cg->id = "Flow Covers";
00086 methods_.push_back(cg);
00087 }
00088 s.options()->GetIntegerValue("lift_and_project_cuts",freq,"bonmin.");
00089 if (freq) {
00090 Coin::SmartPtr<CuttingMethod> cg = new CuttingMethod;
00091 cg->frequency = freq;
00092 CglLandP * landp = new CglLandP;
00093 cg->cgl = landp;
00094 cg->id = "Lift-and-Project";
00095 methods_.push_back(cg);
00096 }
00097 s.options()->GetIntegerValue("reduce_and_split_cuts",freq,"bonmin.");
00098 if (freq) {
00099 Coin::SmartPtr<CuttingMethod> cg = new CuttingMethod;
00100 cg->frequency = freq;
00101 CglRedSplit * rands = new CglRedSplit;
00102 cg->cgl = rands;
00103 cg->id = "Reduce-and-Split";
00104 methods_.push_back(cg);
00105 }
00106 }
00107
00108 void
00109 LinearCutsGenerator::generateCuts(const OsiSolverInterface &solver, OsiCuts &cs,
00110 const CglTreeInfo info) const {
00111
00112
00113 OsiTMINLPInterface * nlp = dynamic_cast<OsiTMINLPInterface *>(solver.clone());
00114 assert(nlp);
00115 OuterApprox oa;
00116
00117 int numberRows = nlp->getNumRows();
00118 for(int i = 0 ; i < 5 ; i++){
00119 nlp->resolve();
00120 OsiClpSolverInterface si;
00121 oa(*nlp, &si, solver.getColSolution(), true);
00122 si.resolve();
00123 OsiCuts cuts;
00124 for(std::list<Coin::SmartPtr<CuttingMethod> >::const_iterator i = methods_.begin() ;
00125 i != methods_.end() ; i++){
00126 (*i)->cgl->generateCuts(si, cuts, info);
00127 }
00128 std::vector<OsiRowCut *> mycuts(cuts.sizeRowCuts());
00129 for(int i = 0 ; i < cuts.sizeRowCuts() ; i++){
00130 mycuts[i] = cuts.rowCutPtr(i);
00131 cs.insert(*mycuts[i]);
00132 }
00133 nlp->applyRowCuts(mycuts.size(), const_cast<const OsiRowCut **> (&mycuts[0]));
00134 }
00135
00136
00137 std::vector<int> kept;
00138 int numberRowsNow = nlp->getNumRows();
00139 int * del = new int [numberRowsNow-numberRows];
00140 nlp->resolve();
00141
00142 const double * activity = nlp->getRowActivity();
00143 const double * lb = nlp->getRowLower();
00144 const double * ub = nlp->getRowUpper();
00145 CoinRelFltEq eq(1e-06);
00146
00147 for (int i=numberRowsNow -1;i>=numberRows;i--) {
00148 if ( !(eq(activity[i], lb[i]) || eq(activity[i], ub[i])) )
00149 cs.eraseRowCut(i - numberRows);
00150 }
00151 delete [] del;
00152 delete nlp;
00153 }
00154 }