Bonmin
1.7
|
00001 // (C) Copyright International Business Machines Corporation 2007 00002 // All Rights Reserved. 00003 // This code is published under the Common Public License. 00004 // 00005 // Authors : 00006 // Pierre Bonami, International Business Machines Corporation 00007 // 00008 // Date : 10/16/2007 00009 #ifndef BonminOuterApprox_H 00010 #define BonminOuterApprox_H 00011 00012 #include <cmath> 00013 00014 namespace Bonmin{ 00015 class OsiTMINLPInterface; 00016 class BabSetupBase; 00017 } 00018 class OsiSolverInterface; 00019 namespace Bonmin { 00021 class OuterApprox{ 00022 00023 public: 00024 00026 OuterApprox(): 00027 tiny_(-0.), 00028 veryTiny_(-0.) 00029 {} 00030 00032 OuterApprox(const OuterApprox & other): 00033 tiny_(other.tiny_), 00034 veryTiny_(other.veryTiny_){ 00035 } 00036 00037 00039 OuterApprox & operator=(const OuterApprox& rhs){ 00040 if(this != & rhs){ 00041 tiny_ = rhs.tiny_; 00042 veryTiny_ = rhs.veryTiny_;} 00043 return (*this); 00044 } 00045 00047 ~OuterApprox(){} 00048 00050 void initialize(Bonmin::BabSetupBase &b); 00051 00053 void extractLinearRelaxation(Bonmin::OsiTMINLPInterface &minlp, 00054 OsiSolverInterface *si, 00055 const double * x, bool getObj); 00057 void operator()(Bonmin::OsiTMINLPInterface &minlp, 00058 OsiSolverInterface *si, 00059 const double * x, bool getObj){ 00060 extractLinearRelaxation(minlp, si, x, getObj);} 00061 00062 private: 00064 inline bool cleanNnz(double &value, double colLower, double colUpper, 00065 double rowLower, double rowUpper, double colsol, 00066 double & lb, double &ub, double tiny, double veryTiny); 00068 double tiny_; 00070 double veryTiny_; 00072 static int nTimesCalled; 00073 }; 00074 00075 //A procedure to try to remove small coefficients in OA cuts (or make it non small 00076 inline 00077 bool 00078 OuterApprox::cleanNnz(double &value, double colLower, double colUpper, 00079 double rowLower, double rowUpper, double colsol, 00080 double & lb, double &ub, double tiny, double veryTiny) 00081 { 00082 if(fabs(value)>= tiny) return 1; 00083 00084 if(fabs(value)<veryTiny) return 0;//Take the risk? 00085 00086 //try and remove 00087 double infty = 1e20; 00088 bool colUpBounded = colUpper < 10000; 00089 bool colLoBounded = colLower > -10000; 00090 bool rowNotLoBounded = rowLower <= - infty; 00091 bool rowNotUpBounded = rowUpper >= infty; 00092 bool pos = value > 0; 00093 00094 if(colLoBounded && pos && rowNotUpBounded) { 00095 lb += value * (colsol - colLower); 00096 return 0; 00097 } 00098 else 00099 if(colLoBounded && !pos && rowNotLoBounded) { 00100 ub += value * (colsol - colLower); 00101 return 0; 00102 } 00103 else 00104 if(colUpBounded && !pos && rowNotUpBounded) { 00105 lb += value * (colsol - colUpper); 00106 return 0; 00107 } 00108 else 00109 if(colUpBounded && pos && rowNotLoBounded) { 00110 ub += value * (colsol - colUpper); 00111 return 0; 00112 } 00113 //can not remove coefficient increase it to smallest non zero 00114 if(pos) value = tiny; 00115 else 00116 value = - tiny; 00117 return 1; 00118 } 00119 00120 } 00121 00122 #endif 00123