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 OsiRowCut_H |
6 | #define OsiRowCut_H |
7 | |
8 | #include "CoinPackedVector.hpp" |
9 | |
10 | #include "OsiCollections.hpp" |
11 | #include "OsiCut.hpp" |
12 | |
13 | //#define OSI_INLINE_ROWCUT_METHODS |
14 | #ifdef OSI_INLINE_ROWCUT_METHODS |
15 | #define OsiRowCut_inline inline |
16 | #else |
17 | #define OsiRowCut_inline |
18 | #endif |
19 | |
20 | /** Row Cut Class |
21 | |
22 | A row cut has: |
23 | <ul> |
24 | <li>a lower bound<br> |
25 | <li>an upper bound<br> |
26 | <li>a vector of row elements |
27 | </ul> |
28 | */ |
29 | class OsiRowCut : public OsiCut { |
30 | friend void OsiRowCutUnitTest(const OsiSolverInterface * baseSiP, |
31 | const std::string & mpsDir); |
32 | |
33 | public: |
34 | |
35 | /**@name Row bounds */ |
36 | //@{ |
37 | /// Get lower bound |
38 | OsiRowCut_inline double lb() const; |
39 | /// Set lower bound |
40 | OsiRowCut_inline void setLb(double lb); |
41 | /// Get upper bound |
42 | OsiRowCut_inline double ub() const; |
43 | /// Set upper bound |
44 | OsiRowCut_inline void setUb(double ub); |
45 | //@} |
46 | |
47 | /**@name Row rhs, sense, range */ |
48 | //@{ |
49 | /// Get sense ('E', 'G', 'L', 'N', 'R') |
50 | char sense() const; |
51 | /// Get right-hand side |
52 | double rhs() const; |
53 | /// Get range (ub - lb for 'R' rows, 0 otherwise) |
54 | double range() const; |
55 | //@} |
56 | |
57 | //------------------------------------------------------------------- |
58 | /**@name Row elements */ |
59 | //@{ |
60 | /// Set row elements |
61 | OsiRowCut_inline void setRow( |
62 | int size, |
63 | const int * colIndices, |
64 | const double * elements, |
65 | bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); |
66 | /// Set row elements from a packed vector |
67 | OsiRowCut_inline void setRow( const CoinPackedVector & v ); |
68 | /// Get row elements |
69 | OsiRowCut_inline const CoinPackedVector & row() const; |
70 | /// Get row elements for changing |
71 | OsiRowCut_inline CoinPackedVector & mutableRow() ; |
72 | //@} |
73 | |
74 | /**@name Comparison operators */ |
75 | //@{ |
76 | #if __GNUC__ != 2 |
77 | using OsiCut::operator== ; |
78 | #endif |
79 | /** equal - true if lower bound, upper bound, row elements, |
80 | and OsiCut are equal. |
81 | */ |
82 | OsiRowCut_inline bool operator==(const OsiRowCut& rhs) const; |
83 | |
84 | #if __GNUC__ != 2 |
85 | using OsiCut::operator!= ; |
86 | #endif |
87 | /// not equal |
88 | OsiRowCut_inline bool operator!=(const OsiRowCut& rhs) const; |
89 | //@} |
90 | |
91 | |
92 | //---------------------------------------------------------------- |
93 | /**@name Sanity checks on cut */ |
94 | //@{ |
95 | /** Returns true if the cut is consistent. |
96 | This checks to ensure that: |
97 | <ul> |
98 | <li>The row element vector does not have duplicate indices |
99 | <li>The row element vector indices are >= 0 |
100 | </ul> |
101 | */ |
102 | OsiRowCut_inline bool consistent() const override; |
103 | |
104 | /** Returns true if cut is consistent with respect to the solver |
105 | interface's model. |
106 | This checks to ensure that |
107 | <ul> |
108 | <li>The row element vector indices are < the number of columns |
109 | in the model |
110 | </ul> |
111 | */ |
112 | OsiRowCut_inline bool consistent(const OsiSolverInterface& im) const override; |
113 | |
114 | /** Returns true if the row cut itself is infeasible and cannot be satisfied. |
115 | This checks whether |
116 | <ul> |
117 | <li>the lower bound is strictly greater than the |
118 | upper bound. |
119 | </ul> |
120 | */ |
121 | OsiRowCut_inline bool infeasible(const OsiSolverInterface &im) const override; |
122 | /** Returns infeasibility of the cut with respect to solution |
123 | passed in i.e. is positive if cuts off that solution. |
124 | solution is getNumCols() long.. |
125 | */ |
126 | virtual double violated(const double * solution) const override; |
127 | //@} |
128 | |
129 | /**@name Arithmetic operators. Apply CoinPackedVector methods to the vector */ |
130 | //@{ |
131 | /// add <code>value</code> to every vector entry |
132 | void operator+=(double value) |
133 | { row_ += value; } |
134 | |
135 | /// subtract <code>value</code> from every vector entry |
136 | void operator-=(double value) |
137 | { row_ -= value; } |
138 | |
139 | /// multiply every vector entry by <code>value</code> |
140 | void operator*=(double value) |
141 | { row_ *= value; } |
142 | |
143 | /// divide every vector entry by <code>value</code> |
144 | void operator/=(double value) |
145 | { row_ /= value; } |
146 | //@} |
147 | |
148 | /// Allow access row sorting function |
149 | void sortIncrIndex() |
150 | {row_.sortIncrIndex();} |
151 | |
152 | /**@name Constructors and destructors */ |
153 | //@{ |
154 | /// Assignment operator |
155 | OsiRowCut & operator=( const OsiRowCut& rhs); |
156 | |
157 | /// Copy constructor |
158 | OsiRowCut ( const OsiRowCut &); |
159 | |
160 | /// Clone |
161 | virtual OsiRowCut * clone() const; |
162 | |
163 | /// Default Constructor |
164 | OsiRowCut (); |
165 | |
166 | /** \brief Ownership Constructor |
167 | |
168 | This constructor assumes ownership of the vectors passed as parameters |
169 | for indices and elements. \p colIndices and \p elements will be NULL |
170 | on return. |
171 | */ |
172 | OsiRowCut(double cutlb, double cutub, |
173 | int capacity, int size, |
174 | int *&colIndices, double *&elements); |
175 | |
176 | /// Destructor |
177 | virtual ~OsiRowCut (); |
178 | //@} |
179 | |
180 | /**@name Debug stuff */ |
181 | //@{ |
182 | /// Print cuts in collection |
183 | virtual void print() const override ; |
184 | //@} |
185 | |
186 | private: |
187 | |
188 | |
189 | /**@name Private member data */ |
190 | //@{ |
191 | /// Row elements |
192 | CoinPackedVector row_; |
193 | /// Row lower bound |
194 | double lb_; |
195 | /// Row upper bound |
196 | double ub_; |
197 | //@} |
198 | }; |
199 | |
200 | #ifdef OSI_INLINE_ROWCUT_METHODS |
201 | |
202 | //------------------------------------------------------------------- |
203 | // Set/Get lower & upper bounds |
204 | //------------------------------------------------------------------- |
205 | double OsiRowCut::lb() const { return lb_; } |
206 | void OsiRowCut::setLb(double lb) { lb_ = lb; } |
207 | double OsiRowCut::ub() const { return ub_; } |
208 | void OsiRowCut::setUb(double ub) { ub_ = ub; } |
209 | |
210 | //------------------------------------------------------------------- |
211 | // Set row elements |
212 | //------------------------------------------------------------------- |
213 | void OsiRowCut::setRow(int size, |
214 | const int * colIndices, const double * elements) |
215 | { |
216 | row_.setVector(size,colIndices,elements); |
217 | } |
218 | void OsiRowCut::setRow( const CoinPackedVector & v ) |
219 | { |
220 | row_ = v; |
221 | } |
222 | |
223 | //------------------------------------------------------------------- |
224 | // Get the row |
225 | //------------------------------------------------------------------- |
226 | const CoinPackedVector & OsiRowCut::row() const |
227 | { |
228 | return row_; |
229 | } |
230 | |
231 | //------------------------------------------------------------------- |
232 | // Get the row so we can change |
233 | //------------------------------------------------------------------- |
234 | CoinPackedVector & OsiRowCut::mutableRow() |
235 | { |
236 | return row_; |
237 | } |
238 | |
239 | //---------------------------------------------------------------- |
240 | // == operator |
241 | //------------------------------------------------------------------- |
242 | bool |
243 | OsiRowCut::operator==(const OsiRowCut& rhs) const |
244 | { |
245 | if ( this->OsiCut::operator!=(rhs) ) return false; |
246 | if ( row() != rhs.row() ) return false; |
247 | if ( lb() != rhs.lb() ) return false; |
248 | if ( ub() != rhs.ub() ) return false; |
249 | return true; |
250 | } |
251 | bool |
252 | OsiRowCut::operator!=(const OsiRowCut& rhs) const |
253 | { |
254 | return !( (*this)==rhs ); |
255 | } |
256 | |
257 | |
258 | //---------------------------------------------------------------- |
259 | // consistent & infeasible |
260 | //------------------------------------------------------------------- |
261 | bool OsiRowCut::consistent() const |
262 | { |
263 | const CoinPackedVector & r=row(); |
264 | r.duplicateIndex("consistent" , "OsiRowCut" ); |
265 | if ( r.getMinIndex() < 0 ) return false; |
266 | return true; |
267 | } |
268 | bool OsiRowCut::consistent(const OsiSolverInterface& im) const |
269 | { |
270 | const CoinPackedVector & r=row(); |
271 | if ( r.getMaxIndex() >= im.getNumCols() ) return false; |
272 | |
273 | return true; |
274 | } |
275 | bool OsiRowCut::infeasible(const OsiSolverInterface &im) const |
276 | { |
277 | if ( lb() > ub() ) return true; |
278 | |
279 | return false; |
280 | } |
281 | |
282 | #endif |
283 | |
284 | /** Row Cut Class which refers back to row which created it. |
285 | It may be useful to strengthen a row rather than add a cut. To do this |
286 | we need to know which row is strengthened. This trivial extension |
287 | to OsiRowCut does that. |
288 | |
289 | */ |
290 | class OsiRowCut2 : public OsiRowCut { |
291 | |
292 | public: |
293 | |
294 | /**@name Which row */ |
295 | //@{ |
296 | /// Get row |
297 | inline int whichRow() const |
298 | { return whichRow_;} |
299 | /// Set row |
300 | inline void setWhichRow(int row) |
301 | { whichRow_=row;} |
302 | //@} |
303 | |
304 | /**@name Constructors and destructors */ |
305 | //@{ |
306 | /// Assignment operator |
307 | OsiRowCut2 & operator=( const OsiRowCut2& rhs); |
308 | |
309 | /// Copy constructor |
310 | OsiRowCut2 ( const OsiRowCut2 &); |
311 | |
312 | /// Clone |
313 | virtual OsiRowCut * clone() const override; |
314 | |
315 | /// Default Constructor |
316 | OsiRowCut2 (int row=-1); |
317 | |
318 | /// Destructor |
319 | virtual ~OsiRowCut2 (); |
320 | //@} |
321 | |
322 | private: |
323 | |
324 | |
325 | /**@name Private member data */ |
326 | //@{ |
327 | /// Which row |
328 | int whichRow_; |
329 | //@} |
330 | }; |
331 | #endif |
332 | |