00001
00002
00003
00004
00005 #ifndef OsiColCut_H
00006 #define OsiColCut_H
00007
00008 #include <string>
00009
00010 #include "CoinPackedVector.hpp"
00011
00012 #include "OsiCollections.hpp"
00013 #include "OsiCut.hpp"
00014
00023 class OsiColCut : public OsiCut {
00024 friend void OsiColCutUnitTest(const OsiSolverInterface * baseSiP,
00025 const std::string & mpsDir);
00026
00027 public:
00028
00029
00030
00033
00034 inline void setLbs(
00035 int nElements,
00036 const int * colIndices,
00037 const double * lbElements );
00038
00040 inline void setLbs( const CoinPackedVector & lbs );
00041
00043 inline void setUbs(
00044 int nElements,
00045 const int * colIndices,
00046 const double * ubElements );
00047
00049 inline void setUbs( const CoinPackedVector & ubs );
00051
00052
00053
00056
00057 inline const CoinPackedVector & lbs() const;
00059 inline const CoinPackedVector & ubs() const;
00061
00064 #if __GNUC__ != 2
00065 using OsiCut::operator== ;
00066 #endif
00067
00070 inline virtual bool operator==(const OsiColCut& rhs) const;
00071
00072 #if __GNUC__ != 2
00073 using OsiCut::operator!= ;
00074 #endif
00076 inline virtual bool operator!=(const OsiColCut& rhs) const;
00077
00078
00079
00080
00081
00091 inline virtual bool consistent() const;
00092
00100 inline virtual bool consistent(const OsiSolverInterface& im) const;
00101
00110 inline virtual bool infeasible(const OsiSolverInterface &im) const;
00115 virtual double violated(const double * solution) const;
00117
00118
00119
00122
00123 OsiColCut & operator=( const OsiColCut& rhs);
00124
00126 OsiColCut ( const OsiColCut &);
00127
00129 OsiColCut ();
00130
00132 virtual OsiColCut * clone() const;
00133
00135 virtual ~OsiColCut ();
00137
00140
00141 virtual void print() const;
00143
00144 private:
00145
00148
00149 CoinPackedVector lbs_;
00151 CoinPackedVector ubs_;
00153
00154 };
00155
00156
00157
00158
00159
00160
00161 void OsiColCut::setLbs(
00162 int size,
00163 const int * colIndices,
00164 const double * lbElements )
00165 {
00166 lbs_.setVector(size,colIndices,lbElements);
00167 }
00168
00169 void OsiColCut::setUbs(
00170 int size,
00171 const int * colIndices,
00172 const double * ubElements )
00173 {
00174 ubs_.setVector(size,colIndices,ubElements);
00175 }
00176
00177 void OsiColCut::setLbs( const CoinPackedVector & lbs )
00178 {
00179 lbs_ = lbs;
00180 }
00181
00182 void OsiColCut::setUbs( const CoinPackedVector & ubs )
00183 {
00184 ubs_ = ubs;
00185 }
00186
00187
00188
00189
00190 const CoinPackedVector & OsiColCut::lbs() const
00191 {
00192 return lbs_;
00193 }
00194
00195 const CoinPackedVector & OsiColCut::ubs() const
00196 {
00197 return ubs_;
00198 }
00199
00200
00201
00202
00203 bool
00204 OsiColCut::operator==(
00205 const OsiColCut& rhs) const
00206 {
00207 if ( this->OsiCut::operator!=(rhs) )
00208 return false;
00209 if ( lbs() != rhs.lbs() )
00210 return false;
00211 if ( ubs() != rhs.ubs() )
00212 return false;
00213 return true;
00214 }
00215
00216 bool
00217 OsiColCut::operator!=(
00218 const OsiColCut& rhs) const
00219 {
00220 return !( (*this)==rhs );
00221 }
00222
00223
00224
00225
00226 bool OsiColCut::consistent() const
00227 {
00228 const CoinPackedVector & lb = lbs();
00229 const CoinPackedVector & ub = ubs();
00230
00231
00232 lb.duplicateIndex("consistent", "OsiColCut");
00233 ub.duplicateIndex("consistent", "OsiColCut");
00234 if ( lb.getMinIndex() < 0 ) return false;
00235 if ( ub.getMinIndex() < 0 ) return false;
00236 return true;
00237 }
00238
00239 bool OsiColCut::consistent(const OsiSolverInterface& im) const
00240 {
00241 const CoinPackedVector & lb = lbs();
00242 const CoinPackedVector & ub = ubs();
00243
00244
00245 if ( lb.getMaxIndex() >= im.getNumCols() ) return false;
00246 if ( ub.getMaxIndex() >= im.getNumCols() ) return false;
00247
00248 return true;
00249 }
00250
00251 #if 0
00252 bool OsiColCut::feasible(const OsiSolverInterface &im) const
00253 {
00254 const double * oldColLb = im.getColLower();
00255 const double * oldColUb = im.getColUpper();
00256 const CoinPackedVector & cutLbs = lbs();
00257 const CoinPackedVector & cutUbs = ubs();
00258 int i;
00259
00260 for ( i=0; i<cutLbs.size(); i++ ) {
00261 int colIndx = cutLbs.indices()[i];
00262 double newLb;
00263 if ( cutLbs.elements()[i] > oldColLb[colIndx] )
00264 newLb = cutLbs.elements()[i];
00265 else
00266 newLb = oldColLb[colIndx];
00267
00268 double newUb = oldColUb[colIndx];
00269 if ( cutUbs.indexExists(colIndx) )
00270 if ( cutUbs[colIndx] < newUb ) newUb = cutUbs[colIndx];
00271 if ( newLb > newUb )
00272 return false;
00273 }
00274
00275 for ( i=0; i<cutUbs.size(); i++ ) {
00276 int colIndx = cutUbs.indices()[i];
00277 double newUb = cutUbs.elements()[i] < oldColUb[colIndx] ? cutUbs.elements()[i] : oldColUb[colIndx];
00278 double newLb = oldColLb[colIndx];
00279 if ( cutLbs.indexExists(colIndx) )
00280 if ( cutLbs[colIndx] > newLb ) newLb = cutLbs[colIndx];
00281 if ( newUb < newLb )
00282 return false;
00283 }
00284
00285 return true;
00286 }
00287 #endif
00288
00289
00290 bool OsiColCut::infeasible(const OsiSolverInterface &im) const
00291 {
00292 const double * oldColLb = im.getColLower();
00293 const double * oldColUb = im.getColUpper();
00294 const CoinPackedVector & cutLbs = lbs();
00295 const CoinPackedVector & cutUbs = ubs();
00296 int i;
00297
00298 for ( i=0; i<cutLbs.getNumElements(); i++ ) {
00299 int colIndx = cutLbs.getIndices()[i];
00300 double newLb= cutLbs.getElements()[i] > oldColLb[colIndx] ?
00301 cutLbs.getElements()[i] : oldColLb[colIndx];
00302
00303 double newUb = oldColUb[colIndx];
00304 if ( cutUbs.isExistingIndex(colIndx) )
00305 if ( cutUbs[colIndx] < newUb ) newUb = cutUbs[colIndx];
00306 if ( newLb > newUb )
00307 return true;
00308 }
00309
00310 for ( i=0; i<cutUbs.getNumElements(); i++ ) {
00311 int colIndx = cutUbs.getIndices()[i];
00312 double newUb = cutUbs.getElements()[i] < oldColUb[colIndx] ?
00313 cutUbs.getElements()[i] : oldColUb[colIndx];
00314 double newLb = oldColLb[colIndx];
00315 if ( cutLbs.isExistingIndex(colIndx) )
00316 if ( cutLbs[colIndx] > newLb ) newLb = cutLbs[colIndx];
00317 if ( newUb < newLb )
00318 return true;
00319 }
00320
00321 return false;
00322 }
00323
00324 #endif