1 | // Copyright (C) 2000, International Business Machines |
2 | // Corporation and others. All Rights Reserved. |
3 | // This code is licensed under the terms of the Eclipse Public License (EPL). |
4 | |
5 | #ifndef OsiCut_H |
6 | #define OsiCut_H |
7 | |
8 | #include "OsiCollections.hpp" |
9 | #include "OsiSolverInterface.hpp" |
10 | |
11 | /** Base Class for cut. |
12 | |
13 | The Base cut class contains: |
14 | <ul> |
15 | <li>a measure of the cut's effectivness |
16 | </ul> |
17 | */ |
18 | |
19 | /* |
20 | COIN_NOTEST_DUPLICATE is rooted in CoinUtils. Check there before you |
21 | meddle here. |
22 | */ |
23 | #ifdef COIN_FAST_CODE |
24 | #ifndef COIN_NOTEST_DUPLICATE |
25 | #define COIN_NOTEST_DUPLICATE |
26 | #endif |
27 | #endif |
28 | |
29 | #ifndef COIN_NOTEST_DUPLICATE |
30 | #define COIN_DEFAULT_VALUE_FOR_DUPLICATE true |
31 | #else |
32 | #define COIN_DEFAULT_VALUE_FOR_DUPLICATE false |
33 | #endif |
34 | |
35 | |
36 | class OsiCut { |
37 | |
38 | public: |
39 | |
40 | //------------------------------------------------------------------- |
41 | /**@name Effectiveness */ |
42 | //@{ |
43 | /// Set effectiveness |
44 | inline void setEffectiveness( double e ); |
45 | /// Get effectiveness |
46 | inline double effectiveness() const; |
47 | //@} |
48 | |
49 | /**@name GloballyValid */ |
50 | //@{ |
51 | /// Set globallyValid (nonzero true) |
52 | inline void setGloballyValid( bool trueFalse ) |
53 | { globallyValid_=trueFalse ? 1 : 0;} |
54 | inline void setGloballyValid( ) |
55 | { globallyValid_=1;} |
56 | inline void setNotGloballyValid( ) |
57 | { globallyValid_=0;} |
58 | /// Get globallyValid |
59 | inline bool globallyValid() const |
60 | { return globallyValid_!=0;} |
61 | /// Set globallyValid as integer (nonzero true) |
62 | inline void setGloballyValidAsInteger( int trueFalse ) |
63 | { globallyValid_=trueFalse;} |
64 | /// Get globallyValid |
65 | inline int globallyValidAsInteger() const |
66 | { return globallyValid_;} |
67 | //@} |
68 | |
69 | /**@name Debug stuff */ |
70 | //@{ |
71 | /// Print cuts in collection |
72 | virtual void print() const {} |
73 | //@} |
74 | |
75 | #if 0 |
76 | / **@name Times used */ |
77 | / /@{ |
78 | / // Set times used |
79 | inline void setTimesUsed( int t ); |
80 | / // Increment times used |
81 | inline void incrementTimesUsed(); |
82 | / // Get times used |
83 | inline int timesUsed() const; |
84 | / /@} |
85 | |
86 | / **@name Times tested */ |
87 | / /@{ |
88 | / // Set times tested |
89 | inline void setTimesTested( int t ); |
90 | / // Increment times tested |
91 | inline void incrementTimesTested(); |
92 | / // Get times tested |
93 | inline int timesTested() const; |
94 | / /@} |
95 | #endif |
96 | |
97 | //---------------------------------------------------------------- |
98 | |
99 | /**@name Comparison operators */ |
100 | //@{ |
101 | ///equal. 2 cuts are equal if there effectiveness are equal |
102 | inline virtual bool operator==(const OsiCut& rhs) const; |
103 | /// not equal |
104 | inline virtual bool operator!=(const OsiCut& rhs) const; |
105 | /// less than. True if this.effectiveness < rhs.effectiveness |
106 | inline virtual bool operator< (const OsiCut& rhs) const; |
107 | /// less than. True if this.effectiveness > rhs.effectiveness |
108 | inline virtual bool operator> (const OsiCut& rhs) const; |
109 | //@} |
110 | |
111 | //---------------------------------------------------------------- |
112 | // consistent() - returns true if the cut is consistent with repect to itself. |
113 | // This might include checks to ensure that a packed vector |
114 | // itself does not have a negative index. |
115 | // consistent(const OsiSolverInterface& si) - returns true if cut is consistent with |
116 | // respect to the solver interface's model. This might include a check to |
117 | // make sure a column index is not greater than the number |
118 | // of columns in the problem. |
119 | // infeasible(const OsiSolverInterface& si) - returns true if the cut is infeasible |
120 | // "with respect to itself". This might include a check to ensure |
121 | // the lower bound is greater than the upper bound, or if the |
122 | // cut simply replaces bounds that the new bounds are feasible with |
123 | // respect to the old bounds. |
124 | //----------------------------------------------------------------- |
125 | /**@name Sanity checks on cut */ |
126 | //@{ |
127 | /** Returns true if the cut is consistent with respect to itself, |
128 | without considering any |
129 | data in the model. For example, it might check to ensure |
130 | that a column index is not negative. |
131 | */ |
132 | inline virtual bool consistent() const=0; |
133 | |
134 | /** Returns true if cut is consistent when considering the solver |
135 | interface's model. For example, it might check to ensure |
136 | that a column index is not greater than the number of columns |
137 | in the model. Assumes consistent() is true. |
138 | */ |
139 | inline virtual bool consistent(const OsiSolverInterface& si) const=0; |
140 | |
141 | /** Returns true if the cut is infeasible "with respect to itself" and |
142 | cannot be satisfied. This method does NOT check whether adding the |
143 | cut to the solver interface's model will make the -model- infeasble. |
144 | A cut which returns !infeasible(si) may very well make the model |
145 | infeasible. (Of course, adding a cut with returns infeasible(si) |
146 | will make the model infeasible.) |
147 | |
148 | The "with respect to itself" is in quotes becaues |
149 | in the case where the cut |
150 | simply replaces existing bounds, it may make |
151 | sense to test infeasibility with respect to the current bounds |
152 | held in the solver interface's model. For example, if the cut |
153 | has a single variable in it, it might check that the maximum |
154 | of new and existing lower bounds is greater than the minium of |
155 | the new and existing upper bounds. |
156 | |
157 | Assumes that consistent(si) is true.<br> |
158 | Infeasible cuts can be a useful mechanism for a cut generator to |
159 | inform the solver interface that its detected infeasibility of the |
160 | problem. |
161 | */ |
162 | inline virtual bool infeasible(const OsiSolverInterface &si) const=0; |
163 | |
164 | /** Returns infeasibility of the cut with respect to solution |
165 | passed in i.e. is positive if cuts off that solution. |
166 | solution is getNumCols() long.. |
167 | */ |
168 | virtual double violated(const double * solution) const=0; |
169 | //@} |
170 | |
171 | protected: |
172 | |
173 | /**@name Constructors and destructors */ |
174 | //@{ |
175 | /// Default Constructor |
176 | OsiCut (); |
177 | |
178 | /// Copy constructor |
179 | OsiCut ( const OsiCut &); |
180 | |
181 | /// Assignment operator |
182 | OsiCut & operator=( const OsiCut& rhs); |
183 | |
184 | /// Destructor |
185 | virtual ~OsiCut (); |
186 | //@} |
187 | |
188 | private: |
189 | |
190 | /**@name Private member data */ |
191 | //@{ |
192 | /// Effectiveness |
193 | double effectiveness_; |
194 | /// If cut has global validity i.e. can be used anywhere in tree |
195 | int globallyValid_; |
196 | #if 0 |
197 | /// Times used |
198 | int timesUsed_; |
199 | /// Times tested |
200 | int timesTested_; |
201 | #endif |
202 | //@} |
203 | }; |
204 | |
205 | |
206 | //------------------------------------------------------------------- |
207 | // Set/Get member data |
208 | //------------------------------------------------------------------- |
209 | void OsiCut::setEffectiveness(double e) { effectiveness_=e; } |
210 | double OsiCut::effectiveness() const { return effectiveness_; } |
211 | |
212 | #if 0 |
213 | void OsiCut::setTimesUsed( int t ) { timesUsed_=t; } |
214 | void OsiCut::incrementTimesUsed() { timesUsed_++; } |
215 | int OsiCut::timesUsed() const { return timesUsed_; } |
216 | |
217 | void OsiCut::setTimesTested( int t ) { timesTested_=t; } |
218 | void OsiCut::incrementTimesTested() { timesTested_++; } |
219 | int OsiCut::timesTested() const{ return timesTested_; } |
220 | #endif |
221 | |
222 | //---------------------------------------------------------------- |
223 | // == operator |
224 | //------------------------------------------------------------------- |
225 | bool |
226 | OsiCut::operator==(const OsiCut& rhs) const |
227 | { |
228 | return effectiveness()==rhs.effectiveness(); |
229 | } |
230 | bool |
231 | OsiCut::operator!=(const OsiCut& rhs) const |
232 | { |
233 | return !( (*this)==rhs ); |
234 | } |
235 | bool |
236 | OsiCut::operator< (const OsiCut& rhs) const |
237 | { |
238 | return effectiveness()<rhs.effectiveness(); |
239 | } |
240 | bool |
241 | OsiCut::operator> (const OsiCut& rhs) const |
242 | { |
243 | return effectiveness()>rhs.effectiveness(); |
244 | } |
245 | #endif |
246 | |