00001
00002
00003
00004
00005
00006
00007
00008
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
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;
00085
00086
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
00114 if(pos) value = tiny;
00115 else
00116 value = - tiny;
00117 return 1;
00118 }
00119
00120 }
00121
00122 #endif
00123