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
|