| 1 | /* $Id: ClpGubMatrix.hpp 1665 2011-01-04 17:55:54Z lou $ */ |
| 2 | // Copyright (C) 2003, International Business Machines |
| 3 | // Corporation and others. All Rights Reserved. |
| 4 | // This code is licensed under the terms of the Eclipse Public License (EPL). |
| 5 | |
| 6 | #ifndef ClpGubMatrix_H |
| 7 | #define ClpGubMatrix_H |
| 8 | |
| 9 | |
| 10 | #include "CoinPragma.hpp" |
| 11 | |
| 12 | #include "ClpPackedMatrix.hpp" |
| 13 | class ClpSimplex; |
| 14 | /** This implements Gub rows plus a ClpPackedMatrix. |
| 15 | |
| 16 | There will be a version using ClpPlusMinusOne matrix but |
| 17 | there is no point doing one with ClpNetworkMatrix (although |
| 18 | an embedded network is attractive). |
| 19 | |
| 20 | */ |
| 21 | |
| 22 | class ClpGubMatrix : public ClpPackedMatrix { |
| 23 | |
| 24 | public: |
| 25 | /**@name Main functions provided */ |
| 26 | //@{ |
| 27 | /** Returns a new matrix in reverse order without gaps (GUB wants NULL) */ |
| 28 | virtual ClpMatrixBase * reverseOrderedCopy() const; |
| 29 | /// Returns number of elements in column part of basis |
| 30 | virtual CoinBigIndex countBasis(const int * whichColumn, |
| 31 | int & numberColumnBasic); |
| 32 | /// Fills in column part of basis |
| 33 | virtual void fillBasis(ClpSimplex * model, |
| 34 | const int * whichColumn, |
| 35 | int & numberColumnBasic, |
| 36 | int * row, int * start, |
| 37 | int * rowCount, int * columnCount, |
| 38 | CoinFactorizationDouble * element); |
| 39 | /** Unpacks a column into an CoinIndexedvector |
| 40 | */ |
| 41 | virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, |
| 42 | int column) const ; |
| 43 | /** Unpacks a column into an CoinIndexedvector |
| 44 | ** in packed foramt |
| 45 | Note that model is NOT const. Bounds and objective could |
| 46 | be modified if doing column generation (just for this variable) */ |
| 47 | virtual void unpackPacked(ClpSimplex * model, |
| 48 | CoinIndexedVector * rowArray, |
| 49 | int column) const; |
| 50 | /** Adds multiple of a column into an CoinIndexedvector |
| 51 | You can use quickAdd to add to vector */ |
| 52 | virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, |
| 53 | int column, double multiplier) const ; |
| 54 | /** Adds multiple of a column into an array */ |
| 55 | virtual void add(const ClpSimplex * model, double * array, |
| 56 | int column, double multiplier) const; |
| 57 | /// Partial pricing |
| 58 | virtual void partialPricing(ClpSimplex * model, double start, double end, |
| 59 | int & bestSequence, int & numberWanted); |
| 60 | /// Returns number of hidden rows e.g. gub |
| 61 | virtual int hiddenRows() const; |
| 62 | //@} |
| 63 | |
| 64 | /**@name Matrix times vector methods */ |
| 65 | //@{ |
| 66 | |
| 67 | using ClpPackedMatrix::transposeTimes ; |
| 68 | /** Return <code>x * scalar * A + y</code> in <code>z</code>. |
| 69 | Can use y as temporary array (will be empty at end) |
| 70 | Note - If x packed mode - then z packed mode |
| 71 | Squashes small elements and knows about ClpSimplex */ |
| 72 | virtual void transposeTimes(const ClpSimplex * model, double scalar, |
| 73 | const CoinIndexedVector * x, |
| 74 | CoinIndexedVector * y, |
| 75 | CoinIndexedVector * z) const; |
| 76 | /** Return <code>x * scalar * A + y</code> in <code>z</code>. |
| 77 | Can use y as temporary array (will be empty at end) |
| 78 | Note - If x packed mode - then z packed mode |
| 79 | Squashes small elements and knows about ClpSimplex. |
| 80 | This version uses row copy*/ |
| 81 | virtual void transposeTimesByRow(const ClpSimplex * model, double scalar, |
| 82 | const CoinIndexedVector * x, |
| 83 | CoinIndexedVector * y, |
| 84 | CoinIndexedVector * z) const; |
| 85 | /** Return <code>x *A</code> in <code>z</code> but |
| 86 | just for indices in y. |
| 87 | Note - z always packed mode */ |
| 88 | virtual void subsetTransposeTimes(const ClpSimplex * model, |
| 89 | const CoinIndexedVector * x, |
| 90 | const CoinIndexedVector * y, |
| 91 | CoinIndexedVector * z) const; |
| 92 | /** expands an updated column to allow for extra rows which the main |
| 93 | solver does not know about and returns number added if mode 0. |
| 94 | If mode 1 deletes extra entries |
| 95 | |
| 96 | This active in Gub |
| 97 | */ |
| 98 | virtual int extendUpdated(ClpSimplex * model, CoinIndexedVector * update, int mode); |
| 99 | /** |
| 100 | mode=0 - Set up before "update" and "times" for primal solution using extended rows |
| 101 | mode=1 - Cleanup primal solution after "times" using extended rows. |
| 102 | mode=2 - Check (or report on) primal infeasibilities |
| 103 | */ |
| 104 | virtual void primalExpanded(ClpSimplex * model, int mode); |
| 105 | /** |
| 106 | mode=0 - Set up before "updateTranspose" and "transposeTimes" for duals using extended |
| 107 | updates array (and may use other if dual values pass) |
| 108 | mode=1 - Update dual solution after "transposeTimes" using extended rows. |
| 109 | mode=2 - Compute all djs and compute key dual infeasibilities |
| 110 | mode=3 - Report on key dual infeasibilities |
| 111 | mode=4 - Modify before updateTranspose in partial pricing |
| 112 | */ |
| 113 | virtual void dualExpanded(ClpSimplex * model, CoinIndexedVector * array, |
| 114 | double * other, int mode); |
| 115 | /** |
| 116 | mode=0 - Create list of non-key basics in pivotVariable_ using |
| 117 | number as numberBasic in and out |
| 118 | mode=1 - Set all key variables as basic |
| 119 | mode=2 - return number extra rows needed, number gives maximum number basic |
| 120 | mode=3 - before replaceColumn |
| 121 | mode=4 - return 1 if can do primal, 2 if dual, 3 if both |
| 122 | mode=5 - save any status stuff (when in good state) |
| 123 | mode=6 - restore status stuff |
| 124 | mode=7 - flag given variable (normally sequenceIn) |
| 125 | mode=8 - unflag all variables |
| 126 | mode=9 - synchronize costs |
| 127 | mode=10 - return 1 if there may be changing bounds on variable (column generation) |
| 128 | mode=11 - make sure set is clean (used when a variable rejected - but not flagged) |
| 129 | mode=12 - after factorize but before permute stuff |
| 130 | mode=13 - at end of simplex to delete stuff |
| 131 | */ |
| 132 | virtual int generalExpanded(ClpSimplex * model, int mode, int & number); |
| 133 | /** |
| 134 | update information for a pivot (and effective rhs) |
| 135 | */ |
| 136 | virtual int updatePivot(ClpSimplex * model, double oldInValue, double oldOutValue); |
| 137 | /// Sets up an effective RHS and does gub crash if needed |
| 138 | virtual void useEffectiveRhs(ClpSimplex * model, bool cheapest = true); |
| 139 | /** Returns effective RHS offset if it is being used. This is used for long problems |
| 140 | or big gub or anywhere where going through full columns is |
| 141 | expensive. This may re-compute */ |
| 142 | virtual double * rhsOffset(ClpSimplex * model, bool forceRefresh = false, |
| 143 | bool check = false); |
| 144 | /** This is local to Gub to allow synchronization: |
| 145 | mode=0 when status of basis is good |
| 146 | mode=1 when variable is flagged |
| 147 | mode=2 when all variables unflagged (returns number flagged) |
| 148 | mode=3 just reset costs (primal) |
| 149 | mode=4 correct number of dual infeasibilities |
| 150 | mode=5 return 4 if time to re-factorize |
| 151 | mode=6 - return 1 if there may be changing bounds on variable (column generation) |
| 152 | mode=7 - do extra restores for column generation |
| 153 | mode=8 - make sure set is clean |
| 154 | mode=9 - adjust lower, upper on set by incoming |
| 155 | */ |
| 156 | virtual int synchronize(ClpSimplex * model, int mode); |
| 157 | /// Correct sequence in and out to give true value |
| 158 | virtual void correctSequence(const ClpSimplex * model, int & sequenceIn, int & sequenceOut) ; |
| 159 | //@} |
| 160 | |
| 161 | |
| 162 | |
| 163 | /**@name Constructors, destructor */ |
| 164 | //@{ |
| 165 | /** Default constructor. */ |
| 166 | ClpGubMatrix(); |
| 167 | /** Destructor */ |
| 168 | virtual ~ClpGubMatrix(); |
| 169 | //@} |
| 170 | |
| 171 | /**@name Copy method */ |
| 172 | //@{ |
| 173 | /** The copy constructor. */ |
| 174 | ClpGubMatrix(const ClpGubMatrix&); |
| 175 | /** The copy constructor from an CoinPackedMatrix. */ |
| 176 | ClpGubMatrix(const CoinPackedMatrix&); |
| 177 | /** Subset constructor (without gaps). Duplicates are allowed |
| 178 | and order is as given */ |
| 179 | ClpGubMatrix (const ClpGubMatrix & wholeModel, |
| 180 | int numberRows, const int * whichRows, |
| 181 | int numberColumns, const int * whichColumns); |
| 182 | ClpGubMatrix (const CoinPackedMatrix & wholeModel, |
| 183 | int numberRows, const int * whichRows, |
| 184 | int numberColumns, const int * whichColumns); |
| 185 | |
| 186 | /** This takes over ownership (for space reasons) */ |
| 187 | ClpGubMatrix(CoinPackedMatrix * matrix); |
| 188 | |
| 189 | /** This takes over ownership (for space reasons) and is the |
| 190 | real constructor*/ |
| 191 | ClpGubMatrix(ClpPackedMatrix * matrix, int numberSets, |
| 192 | const int * start, const int * end, |
| 193 | const double * lower, const double * upper, |
| 194 | const unsigned char * status = NULL); |
| 195 | |
| 196 | ClpGubMatrix& operator=(const ClpGubMatrix&); |
| 197 | /// Clone |
| 198 | virtual ClpMatrixBase * clone() const ; |
| 199 | /** Subset clone (without gaps). Duplicates are allowed |
| 200 | and order is as given */ |
| 201 | virtual ClpMatrixBase * subsetClone ( |
| 202 | int numberRows, const int * whichRows, |
| 203 | int numberColumns, const int * whichColumns) const ; |
| 204 | /** redoes next_ for a set. */ |
| 205 | void redoSet(ClpSimplex * model, int newKey, int oldKey, int iSet); |
| 206 | //@} |
| 207 | /**@name gets and sets */ |
| 208 | //@{ |
| 209 | /// Status |
| 210 | inline ClpSimplex::Status getStatus(int sequence) const { |
| 211 | return static_cast<ClpSimplex::Status> (status_[sequence] & 7); |
| 212 | } |
| 213 | inline void setStatus(int sequence, ClpSimplex::Status status) { |
| 214 | unsigned char & st_byte = status_[sequence]; |
| 215 | st_byte = static_cast<unsigned char>(st_byte & ~7); |
| 216 | st_byte = static_cast<unsigned char>(st_byte | status); |
| 217 | } |
| 218 | /// To flag a variable |
| 219 | inline void setFlagged( int sequence) { |
| 220 | status_[sequence] = static_cast<unsigned char>(status_[sequence] | 64); |
| 221 | } |
| 222 | inline void clearFlagged( int sequence) { |
| 223 | status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~64); |
| 224 | } |
| 225 | inline bool flagged(int sequence) const { |
| 226 | return ((status_[sequence] & 64) != 0); |
| 227 | } |
| 228 | /// To say key is above ub |
| 229 | inline void setAbove( int sequence) { |
| 230 | unsigned char iStat = status_[sequence]; |
| 231 | iStat = static_cast<unsigned char>(iStat & ~24); |
| 232 | status_[sequence] = static_cast<unsigned char>(iStat | 16); |
| 233 | } |
| 234 | /// To say key is feasible |
| 235 | inline void setFeasible( int sequence) { |
| 236 | unsigned char iStat = status_[sequence]; |
| 237 | iStat = static_cast<unsigned char>(iStat & ~24); |
| 238 | status_[sequence] = static_cast<unsigned char>(iStat | 8); |
| 239 | } |
| 240 | /// To say key is below lb |
| 241 | inline void setBelow( int sequence) { |
| 242 | unsigned char iStat = status_[sequence]; |
| 243 | iStat = static_cast<unsigned char>(iStat & ~24); |
| 244 | status_[sequence] = iStat; |
| 245 | } |
| 246 | inline double weight( int sequence) const { |
| 247 | int iStat = status_[sequence] & 31; |
| 248 | iStat = iStat >> 3; |
| 249 | return static_cast<double> (iStat - 1); |
| 250 | } |
| 251 | /// Starts |
| 252 | inline int * start() const { |
| 253 | return start_; |
| 254 | } |
| 255 | /// End |
| 256 | inline int * end() const { |
| 257 | return end_; |
| 258 | } |
| 259 | /// Lower bounds on sets |
| 260 | inline double * lower() const { |
| 261 | return lower_; |
| 262 | } |
| 263 | /// Upper bounds on sets |
| 264 | inline double * upper() const { |
| 265 | return upper_; |
| 266 | } |
| 267 | /// Key variable of set |
| 268 | inline int * keyVariable() const { |
| 269 | return keyVariable_; |
| 270 | } |
| 271 | /// Backward pointer to set number |
| 272 | inline int * backward() const { |
| 273 | return backward_; |
| 274 | } |
| 275 | /// Number of sets (gub rows) |
| 276 | inline int numberSets() const { |
| 277 | return numberSets_; |
| 278 | } |
| 279 | /// Switches off dj checking each factorization (for BIG models) |
| 280 | void switchOffCheck(); |
| 281 | //@} |
| 282 | |
| 283 | |
| 284 | protected: |
| 285 | /**@name Data members |
| 286 | The data members are protected to allow access for derived classes. */ |
| 287 | //@{ |
| 288 | /// Sum of dual infeasibilities |
| 289 | double sumDualInfeasibilities_; |
| 290 | /// Sum of primal infeasibilities |
| 291 | double sumPrimalInfeasibilities_; |
| 292 | /// Sum of Dual infeasibilities using tolerance based on error in duals |
| 293 | double sumOfRelaxedDualInfeasibilities_; |
| 294 | /// Sum of Primal infeasibilities using tolerance based on error in primals |
| 295 | double sumOfRelaxedPrimalInfeasibilities_; |
| 296 | /// Infeasibility weight when last full pass done |
| 297 | double infeasibilityWeight_; |
| 298 | /// Starts |
| 299 | int * start_; |
| 300 | /// End |
| 301 | int * end_; |
| 302 | /// Lower bounds on sets |
| 303 | double * lower_; |
| 304 | /// Upper bounds on sets |
| 305 | double * upper_; |
| 306 | /// Status of slacks |
| 307 | mutable unsigned char * status_; |
| 308 | /// Saved status of slacks |
| 309 | unsigned char * saveStatus_; |
| 310 | /// Saved key variables |
| 311 | int * savedKeyVariable_; |
| 312 | /// Backward pointer to set number |
| 313 | int * backward_; |
| 314 | /// Backward pointer to pivot row !!! |
| 315 | int * backToPivotRow_; |
| 316 | /// Change in costs for keys |
| 317 | double * changeCost_; |
| 318 | /// Key variable of set |
| 319 | mutable int * keyVariable_; |
| 320 | /** Next basic variable in set - starts at key and end with -(set+1). |
| 321 | Now changes to -(nonbasic+1). |
| 322 | next_ has extra space for 2* longest set */ |
| 323 | mutable int * next_; |
| 324 | /// Backward pointer to index in CoinIndexedVector |
| 325 | int * toIndex_; |
| 326 | // Reverse pointer from index to set |
| 327 | int * fromIndex_; |
| 328 | /// Pointer back to model |
| 329 | ClpSimplex * model_; |
| 330 | /// Number of dual infeasibilities |
| 331 | int numberDualInfeasibilities_; |
| 332 | /// Number of primal infeasibilities |
| 333 | int numberPrimalInfeasibilities_; |
| 334 | /** If pricing will declare victory (i.e. no check every factorization). |
| 335 | -1 - always check |
| 336 | 0 - don't check |
| 337 | 1 - in don't check mode but looks optimal |
| 338 | */ |
| 339 | int noCheck_; |
| 340 | /// Number of sets (gub rows) |
| 341 | int numberSets_; |
| 342 | /// Number in vector without gub extension |
| 343 | int saveNumber_; |
| 344 | /// Pivot row of possible next key |
| 345 | int possiblePivotKey_; |
| 346 | /// Gub slack in (set number or -1) |
| 347 | int gubSlackIn_; |
| 348 | /// First gub variables (same as start_[0] at present) |
| 349 | int firstGub_; |
| 350 | /// last gub variable (same as end_[numberSets_-1] at present) |
| 351 | int lastGub_; |
| 352 | /** type of gub - 0 not contiguous, 1 contiguous |
| 353 | add 8 bit to say no ubs on individual variables */ |
| 354 | int gubType_; |
| 355 | //@} |
| 356 | }; |
| 357 | |
| 358 | #endif |
| 359 | |