summaryrefslogtreecommitdiff
path: root/build/Bonmin/include/coin/BonOuterApprox.hpp
blob: 5f24f6161cb12a3fd1f4668c3d5695204df8a0af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// (C) Copyright International Business Machines Corporation 2007
// All Rights Reserved.
// This code is published under the Eclipse Public License.
//
// Authors :
// Pierre Bonami, International Business Machines Corporation
//
// Date : 10/16/2007
#ifndef BonminOuterApprox_H
#define BonminOuterApprox_H

#include <cmath>

namespace Bonmin{
   class OsiTMINLPInterface;
   class BabSetupBase;
}
class OsiSolverInterface;
namespace Bonmin {
  /** A class to build outer approximations.*/
  class OuterApprox{

  public:

   /** Default constructor.*/
   OuterApprox():
    tiny_(-0.),
    veryTiny_(-0.)
   {}

   /** Copy constructor.*/
   OuterApprox(const OuterApprox & other):
    tiny_(other.tiny_),
    veryTiny_(other.veryTiny_){
    }


   /** Assignment operator.*/
   OuterApprox & operator=(const OuterApprox& rhs){
    if(this != & rhs){
      tiny_ = rhs.tiny_;
      veryTiny_ = rhs.veryTiny_;}
    return (*this);
   }

   /** Destructor.*/
   ~OuterApprox(){}

   /** Initialize using options.*/
   void initialize(Bonmin::BabSetupBase &b);

   /** Build the Outer approximation in minlp and put it in si.*/
   void extractLinearRelaxation(Bonmin::OsiTMINLPInterface &minlp,
                                OsiSolverInterface *si, 
                                const double * x, bool getObj);
   /** Operator() calls extractLinearRelaxation*/
   void operator()(Bonmin::OsiTMINLPInterface &minlp,
                   OsiSolverInterface *si,
                   const double * x, bool getObj){
       extractLinearRelaxation(minlp, si, x, getObj);}

   private:
   /** Facilitator to clean up coefficient.*/
  inline bool cleanNnz(double &value, double colLower, double colUpper,
    double rowLower, double rowUpper, double colsol,
    double & lb, double &ub, double tiny, double veryTiny);
   /** If constraint coefficient is below this, we try to remove it.*/
   double tiny_;
   /** If constraint coefficient is below this, we neglect it.*/
   double veryTiny_;
   /** Count the number of linear outer approximations taken.*/
   static int nTimesCalled;
  };

//A procedure to try to remove small coefficients in OA cuts (or make it non small
inline
bool 
OuterApprox::cleanNnz(double &value, double colLower, double colUpper,
    double rowLower, double rowUpper, double colsol,
    double & lb, double &ub, double tiny, double veryTiny)
{
  if(fabs(value)>= tiny) return 1;

  if(fabs(value)<veryTiny) return 0;//Take the risk?

  //try and remove
  double infty = 1e20;
  bool colUpBounded = colUpper < 10000;
  bool colLoBounded = colLower > -10000;
  bool rowNotLoBounded =  rowLower <= - infty;
  bool rowNotUpBounded = rowUpper >= infty;
  bool pos =  value > 0;

  if(colLoBounded && pos && rowNotUpBounded) {
    lb += value * (colsol - colLower);
    return 0;
  }
  else
    if(colLoBounded && !pos && rowNotLoBounded) {
      ub += value * (colsol - colLower);
      return 0;
    }
    else
      if(colUpBounded && !pos && rowNotUpBounded) {
        lb += value * (colsol - colUpper);
        return 0;
      }
      else
        if(colUpBounded && pos && rowNotLoBounded) {
          ub += value * (colsol - colUpper);
          return 0;
        }
  //can not remove coefficient increase it to smallest non zero
  if(pos) value = tiny;
  else
    value = - tiny;
  return 1;
}

}

#endif