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
22A 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*/
29class OsiRowCut : public OsiCut {
30 friend void OsiRowCutUnitTest(const OsiSolverInterface * baseSiP,
31 const std::string & mpsDir);
32
33public:
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
186private:
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//-------------------------------------------------------------------
205double OsiRowCut::lb() const { return lb_; }
206void OsiRowCut::setLb(double lb) { lb_ = lb; }
207double OsiRowCut::ub() const { return ub_; }
208void OsiRowCut::setUb(double ub) { ub_ = ub; }
209
210//-------------------------------------------------------------------
211// Set row elements
212//-------------------------------------------------------------------
213void OsiRowCut::setRow(int size,
214 const int * colIndices, const double * elements)
215{
216 row_.setVector(size,colIndices,elements);
217}
218void OsiRowCut::setRow( const CoinPackedVector & v )
219{
220 row_ = v;
221}
222
223//-------------------------------------------------------------------
224// Get the row
225//-------------------------------------------------------------------
226const CoinPackedVector & OsiRowCut::row() const
227{
228 return row_;
229}
230
231//-------------------------------------------------------------------
232// Get the row so we can change
233//-------------------------------------------------------------------
234CoinPackedVector & OsiRowCut::mutableRow()
235{
236 return row_;
237}
238
239//----------------------------------------------------------------
240// == operator
241//-------------------------------------------------------------------
242bool
243OsiRowCut::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}
251bool
252OsiRowCut::operator!=(const OsiRowCut& rhs) const
253{
254 return !( (*this)==rhs );
255}
256
257
258//----------------------------------------------------------------
259// consistent & infeasible
260//-------------------------------------------------------------------
261bool 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}
268bool 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}
275bool 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*/
290class OsiRowCut2 : public OsiRowCut {
291
292public:
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
322private:
323
324
325 /**@name Private member data */
326 //@{
327 /// Which row
328 int whichRow_;
329 //@}
330};
331#endif
332