Clp trunk
|
00001 /* $Id$ */ 00002 // Copyright (C) 2002, International Business Machines 00003 // Corporation and others. All Rights Reserved. 00004 // This code is licensed under the terms of the Eclipse Public License (EPL). 00005 00006 #ifndef ClpNonLinearCost_H 00007 #define ClpNonLinearCost_H 00008 00009 00010 #include "CoinPragma.hpp" 00011 00012 class ClpSimplex; 00013 class CoinIndexedVector; 00014 00032 /* status has original status and current status 00033 0 - below lower so stored is upper 00034 1 - in range 00035 2 - above upper so stored is lower 00036 4 - (for current) - same as original 00037 */ 00038 #define CLP_BELOW_LOWER 0 00039 #define CLP_FEASIBLE 1 00040 #define CLP_ABOVE_UPPER 2 00041 #define CLP_SAME 4 00042 inline int originalStatus(unsigned char status) 00043 { 00044 return (status & 15); 00045 } 00046 inline int currentStatus(unsigned char status) 00047 { 00048 return (status >> 4); 00049 } 00050 inline void setOriginalStatus(unsigned char & status, int value) 00051 { 00052 status = static_cast<unsigned char>(status & ~15); 00053 status = static_cast<unsigned char>(status | value); 00054 } 00055 inline void setCurrentStatus(unsigned char &status, int value) 00056 { 00057 status = static_cast<unsigned char>(status & ~(15 << 4)); 00058 status = static_cast<unsigned char>(status | (value << 4)); 00059 } 00060 inline void setInitialStatus(unsigned char &status) 00061 { 00062 status = static_cast<unsigned char>(CLP_FEASIBLE | (CLP_SAME << 4)); 00063 } 00064 inline void setSameStatus(unsigned char &status) 00065 { 00066 status = static_cast<unsigned char>(status & ~(15 << 4)); 00067 status = static_cast<unsigned char>(status | (CLP_SAME << 4)); 00068 } 00069 // Use second version to get more speed 00070 //#define FAST_CLPNON 00071 #ifndef FAST_CLPNON 00072 #define CLP_METHOD1 ((method_&1)!=0) 00073 #define CLP_METHOD2 ((method_&2)!=0) 00074 #else 00075 #define CLP_METHOD1 (false) 00076 #define CLP_METHOD2 (true) 00077 #endif 00078 class ClpNonLinearCost { 00079 00080 public: 00081 00082 public: 00083 00086 00087 ClpNonLinearCost(); 00092 ClpNonLinearCost(ClpSimplex * model, int method = 1); 00098 ClpNonLinearCost(ClpSimplex * model, const int * starts, 00099 const double * lower, const double * cost); 00101 ~ClpNonLinearCost(); 00102 // Copy 00103 ClpNonLinearCost(const ClpNonLinearCost&); 00104 // Assignment 00105 ClpNonLinearCost& operator=(const ClpNonLinearCost&); 00107 00108 00115 void checkInfeasibilities(double oldTolerance = 0.0); 00119 void checkInfeasibilities(int numberInArray, const int * index); 00126 void checkChanged(int numberInArray, CoinIndexedVector * update); 00133 void goThru(int numberInArray, double multiplier, 00134 const int * index, const double * work, 00135 double * rhs); 00138 void goBack(int numberInArray, const int * index, 00139 double * rhs); 00145 void goBackAll(const CoinIndexedVector * update); 00147 void zapCosts(); 00149 void refreshCosts(const double * columnCosts); 00151 void feasibleBounds(); 00155 double setOne(int sequence, double solutionValue); 00158 void setOne(int sequence, double solutionValue, double lowerValue, double upperValue, 00159 double costValue = 0.0); 00163 int setOneOutgoing(int sequence, double &solutionValue); 00165 double nearest(int sequence, double solutionValue); 00169 inline double changeInCost(int sequence, double alpha) const { 00170 double returnValue = 0.0; 00171 if (CLP_METHOD1) { 00172 int iRange = whichRange_[sequence] + offset_[sequence]; 00173 if (alpha > 0.0) 00174 returnValue = cost_[iRange] - cost_[iRange-1]; 00175 else 00176 returnValue = cost_[iRange] - cost_[iRange+1]; 00177 } 00178 if (CLP_METHOD2) { 00179 returnValue = (alpha > 0.0) ? infeasibilityWeight_ : -infeasibilityWeight_; 00180 } 00181 return returnValue; 00182 } 00183 inline double changeUpInCost(int sequence) const { 00184 double returnValue = 0.0; 00185 if (CLP_METHOD1) { 00186 int iRange = whichRange_[sequence] + offset_[sequence]; 00187 if (iRange + 1 != start_[sequence+1] && !infeasible(iRange + 1)) 00188 returnValue = cost_[iRange] - cost_[iRange+1]; 00189 else 00190 returnValue = -1.0e100; 00191 } 00192 if (CLP_METHOD2) { 00193 returnValue = -infeasibilityWeight_; 00194 } 00195 return returnValue; 00196 } 00197 inline double changeDownInCost(int sequence) const { 00198 double returnValue = 0.0; 00199 if (CLP_METHOD1) { 00200 int iRange = whichRange_[sequence] + offset_[sequence]; 00201 if (iRange != start_[sequence] && !infeasible(iRange - 1)) 00202 returnValue = cost_[iRange] - cost_[iRange-1]; 00203 else 00204 returnValue = 1.0e100; 00205 } 00206 if (CLP_METHOD2) { 00207 returnValue = infeasibilityWeight_; 00208 } 00209 return returnValue; 00210 } 00212 inline double changeInCost(int sequence, double alpha, double &rhs) { 00213 double returnValue = 0.0; 00214 #ifdef NONLIN_DEBUG 00215 double saveRhs = rhs; 00216 #endif 00217 if (CLP_METHOD1) { 00218 int iRange = whichRange_[sequence] + offset_[sequence]; 00219 if (alpha > 0.0) { 00220 assert(iRange - 1 >= start_[sequence]); 00221 offset_[sequence]--; 00222 rhs += lower_[iRange] - lower_[iRange-1]; 00223 returnValue = alpha * (cost_[iRange] - cost_[iRange-1]); 00224 } else { 00225 assert(iRange + 1 < start_[sequence+1] - 1); 00226 offset_[sequence]++; 00227 rhs += lower_[iRange+2] - lower_[iRange+1]; 00228 returnValue = alpha * (cost_[iRange] - cost_[iRange+1]); 00229 } 00230 } 00231 if (CLP_METHOD2) { 00232 #ifdef NONLIN_DEBUG 00233 double saveRhs1 = rhs; 00234 rhs = saveRhs; 00235 #endif 00236 unsigned char iStatus = status_[sequence]; 00237 int iWhere = currentStatus(iStatus); 00238 if (iWhere == CLP_SAME) 00239 iWhere = originalStatus(iStatus); 00240 // rhs always increases 00241 if (iWhere == CLP_FEASIBLE) { 00242 if (alpha > 0.0) { 00243 // going below 00244 iWhere = CLP_BELOW_LOWER; 00245 rhs = COIN_DBL_MAX; 00246 } else { 00247 // going above 00248 iWhere = CLP_ABOVE_UPPER; 00249 rhs = COIN_DBL_MAX; 00250 } 00251 } else if (iWhere == CLP_BELOW_LOWER) { 00252 assert (alpha < 0); 00253 // going feasible 00254 iWhere = CLP_FEASIBLE; 00255 rhs += bound_[sequence] - model_->upperRegion()[sequence]; 00256 } else { 00257 assert (iWhere == CLP_ABOVE_UPPER); 00258 // going feasible 00259 iWhere = CLP_FEASIBLE; 00260 rhs += model_->lowerRegion()[sequence] - bound_[sequence]; 00261 } 00262 setCurrentStatus(status_[sequence], iWhere); 00263 #ifdef NONLIN_DEBUG 00264 assert(saveRhs1 == rhs); 00265 #endif 00266 returnValue = fabs(alpha) * infeasibilityWeight_; 00267 } 00268 return returnValue; 00269 } 00271 inline double lower(int sequence) const { 00272 return lower_[whichRange_[sequence] + offset_[sequence]]; 00273 } 00275 inline double upper(int sequence) const { 00276 return lower_[whichRange_[sequence] + offset_[sequence] + 1]; 00277 } 00279 inline double cost(int sequence) const { 00280 return cost_[whichRange_[sequence] + offset_[sequence]]; 00281 } 00283 00284 00287 00288 inline int numberInfeasibilities() const { 00289 return numberInfeasibilities_; 00290 } 00292 inline double changeInCost() const { 00293 return changeCost_; 00294 } 00296 inline double feasibleCost() const { 00297 return feasibleCost_; 00298 } 00300 double feasibleReportCost() const; 00302 inline double sumInfeasibilities() const { 00303 return sumInfeasibilities_; 00304 } 00306 inline double largestInfeasibility() const { 00307 return largestInfeasibility_; 00308 } 00310 inline double averageTheta() const { 00311 return averageTheta_; 00312 } 00313 inline void setAverageTheta(double value) { 00314 averageTheta_ = value; 00315 } 00316 inline void setChangeInCost(double value) { 00317 changeCost_ = value; 00318 } 00319 inline void setMethod(int value) { 00320 method_ = value; 00321 } 00323 inline bool lookBothWays() const { 00324 return bothWays_; 00325 } 00327 00328 inline bool infeasible(int i) const { 00329 return ((infeasible_[i>>5] >> (i & 31)) & 1) != 0; 00330 } 00331 inline void setInfeasible(int i, bool trueFalse) { 00332 unsigned int & value = infeasible_[i>>5]; 00333 int bit = i & 31; 00334 if (trueFalse) 00335 value |= (1 << bit); 00336 else 00337 value &= ~(1 << bit); 00338 } 00339 inline unsigned char * statusArray() const { 00340 return status_; 00341 } 00343 void validate(); 00345 00346 private: 00349 00350 double changeCost_; 00352 double feasibleCost_; 00354 double infeasibilityWeight_; 00356 double largestInfeasibility_; 00358 double sumInfeasibilities_; 00360 double averageTheta_; 00362 int numberRows_; 00364 int numberColumns_; 00366 int * start_; 00368 int * whichRange_; 00370 int * offset_; 00374 double * lower_; 00376 double * cost_; 00378 ClpSimplex * model_; 00379 // Array to say which regions are infeasible 00380 unsigned int * infeasible_; 00382 int numberInfeasibilities_; 00383 // new stuff 00385 unsigned char * status_; 00387 double * bound_; 00389 double * cost2_; 00391 int method_; 00393 bool convex_; 00395 bool bothWays_; 00397 }; 00398 00399 #endif