Go to the documentation of this file.00001
00002
00003
00004 #ifndef ClpNonLinearCost_H
00005 #define ClpNonLinearCost_H
00006
00007
00008 #include "CoinPragma.hpp"
00009
00010 class ClpSimplex;
00011 class CoinIndexedVector;
00012
00030
00031
00032
00033
00034
00035
00036 #define CLP_BELOW_LOWER 0
00037 #define CLP_FEASIBLE 1
00038 #define CLP_ABOVE_UPPER 2
00039 #define CLP_SAME 4
00040 inline int originalStatus(unsigned char status)
00041 {
00042 return (status & 15);
00043 }
00044 inline int currentStatus(unsigned char status)
00045 {
00046 return (status >> 4);
00047 }
00048 inline void setOriginalStatus(unsigned char & status, int value)
00049 {
00050 status = static_cast<unsigned char>(status & ~15);
00051 status = static_cast<unsigned char>(status | value);
00052 }
00053 inline void setCurrentStatus(unsigned char &status, int value)
00054 {
00055 status = static_cast<unsigned char>(status & ~(15 << 4));
00056 status = static_cast<unsigned char>(status | (value << 4));
00057 }
00058 inline void setInitialStatus(unsigned char &status)
00059 {
00060 status = static_cast<unsigned char>(CLP_FEASIBLE | (CLP_SAME << 4));
00061 }
00062 inline void setSameStatus(unsigned char &status)
00063 {
00064 status = static_cast<unsigned char>(status & ~(15 << 4));
00065 status = static_cast<unsigned char>(status | (CLP_SAME << 4));
00066 }
00067
00068
00069 #ifndef FAST_CLPNON
00070 #define CLP_METHOD1 ((method_&1)!=0)
00071 #define CLP_METHOD2 ((method_&2)!=0)
00072 #else
00073 #define CLP_METHOD1 (false)
00074 #define CLP_METHOD2 (true)
00075 #endif
00076 class ClpNonLinearCost {
00077
00078 public:
00079
00080 public:
00081
00084
00085 ClpNonLinearCost();
00090 ClpNonLinearCost(ClpSimplex * model, int method = 1);
00096 ClpNonLinearCost(ClpSimplex * model, const int * starts,
00097 const double * lower, const double * cost);
00099 ~ClpNonLinearCost();
00100
00101 ClpNonLinearCost(const ClpNonLinearCost&);
00102
00103 ClpNonLinearCost& operator=(const ClpNonLinearCost&);
00105
00106
00113 void checkInfeasibilities(double oldTolerance = 0.0);
00117 void checkInfeasibilities(int numberInArray, const int * index);
00124 void checkChanged(int numberInArray, CoinIndexedVector * update);
00131 void goThru(int numberInArray, double multiplier,
00132 const int * index, const double * work,
00133 double * rhs);
00136 void goBack(int numberInArray, const int * index,
00137 double * rhs);
00143 void goBackAll(const CoinIndexedVector * update);
00145 void zapCosts();
00147 void refreshCosts(const double * columnCosts);
00149 void feasibleBounds();
00153 double setOne(int sequence, double solutionValue);
00156 void setOne(int sequence, double solutionValue, double lowerValue, double upperValue,
00157 double costValue = 0.0);
00161 int setOneOutgoing(int sequence, double &solutionValue);
00163 double nearest(int sequence, double solutionValue);
00167 inline double changeInCost(int sequence, double alpha) const {
00168 double returnValue = 0.0;
00169 if (CLP_METHOD1) {
00170 int iRange = whichRange_[sequence] + offset_[sequence];
00171 if (alpha > 0.0)
00172 returnValue = cost_[iRange] - cost_[iRange-1];
00173 else
00174 returnValue = cost_[iRange] - cost_[iRange+1];
00175 }
00176 if (CLP_METHOD2) {
00177 returnValue = (alpha > 0.0) ? infeasibilityWeight_ : -infeasibilityWeight_;
00178 }
00179 return returnValue;
00180 }
00181 inline double changeUpInCost(int sequence) const {
00182 double returnValue = 0.0;
00183 if (CLP_METHOD1) {
00184 int iRange = whichRange_[sequence] + offset_[sequence];
00185 if (iRange + 1 != start_[sequence+1] && !infeasible(iRange + 1))
00186 returnValue = cost_[iRange] - cost_[iRange+1];
00187 else
00188 returnValue = -1.0e100;
00189 }
00190 if (CLP_METHOD2) {
00191 returnValue = -infeasibilityWeight_;
00192 }
00193 return returnValue;
00194 }
00195 inline double changeDownInCost(int sequence) const {
00196 double returnValue = 0.0;
00197 if (CLP_METHOD1) {
00198 int iRange = whichRange_[sequence] + offset_[sequence];
00199 if (iRange != start_[sequence] && !infeasible(iRange - 1))
00200 returnValue = cost_[iRange] - cost_[iRange-1];
00201 else
00202 returnValue = 1.0e100;
00203 }
00204 if (CLP_METHOD2) {
00205 returnValue = infeasibilityWeight_;
00206 }
00207 return returnValue;
00208 }
00210 inline double changeInCost(int sequence, double alpha, double &rhs) {
00211 double returnValue = 0.0;
00212 #ifdef NONLIN_DEBUG
00213 double saveRhs = rhs;
00214 #endif
00215 if (CLP_METHOD1) {
00216 int iRange = whichRange_[sequence] + offset_[sequence];
00217 if (alpha > 0.0) {
00218 assert(iRange - 1 >= start_[sequence]);
00219 offset_[sequence]--;
00220 rhs += lower_[iRange] - lower_[iRange-1];
00221 returnValue = alpha * (cost_[iRange] - cost_[iRange-1]);
00222 } else {
00223 assert(iRange + 1 < start_[sequence+1] - 1);
00224 offset_[sequence]++;
00225 rhs += lower_[iRange+2] - lower_[iRange+1];
00226 returnValue = alpha * (cost_[iRange] - cost_[iRange+1]);
00227 }
00228 }
00229 if (CLP_METHOD2) {
00230 #ifdef NONLIN_DEBUG
00231 double saveRhs1 = rhs;
00232 rhs = saveRhs;
00233 #endif
00234 unsigned char iStatus = status_[sequence];
00235 int iWhere = currentStatus(iStatus);
00236 if (iWhere == CLP_SAME)
00237 iWhere = originalStatus(iStatus);
00238
00239 if (iWhere == CLP_FEASIBLE) {
00240 if (alpha > 0.0) {
00241
00242 iWhere = CLP_BELOW_LOWER;
00243 rhs = COIN_DBL_MAX;
00244 } else {
00245
00246 iWhere = CLP_ABOVE_UPPER;
00247 rhs = COIN_DBL_MAX;
00248 }
00249 } else if (iWhere == CLP_BELOW_LOWER) {
00250 assert (alpha < 0);
00251
00252 iWhere = CLP_FEASIBLE;
00253 rhs += bound_[sequence] - model_->upperRegion()[sequence];
00254 } else {
00255 assert (iWhere == CLP_ABOVE_UPPER);
00256
00257 iWhere = CLP_FEASIBLE;
00258 rhs += model_->lowerRegion()[sequence] - bound_[sequence];
00259 }
00260 setCurrentStatus(status_[sequence], iWhere);
00261 #ifdef NONLIN_DEBUG
00262 assert(saveRhs1 == rhs);
00263 #endif
00264 returnValue = fabs(alpha) * infeasibilityWeight_;
00265 }
00266 return returnValue;
00267 }
00269 inline double lower(int sequence) const {
00270 return lower_[whichRange_[sequence] + offset_[sequence]];
00271 }
00273 inline double upper(int sequence) const {
00274 return lower_[whichRange_[sequence] + offset_[sequence] + 1];
00275 }
00277 inline double cost(int sequence) const {
00278 return cost_[whichRange_[sequence] + offset_[sequence]];
00279 }
00281
00282
00285
00286 inline int numberInfeasibilities() const {
00287 return numberInfeasibilities_;
00288 }
00290 inline double changeInCost() const {
00291 return changeCost_;
00292 }
00294 inline double feasibleCost() const {
00295 return feasibleCost_;
00296 }
00298 double feasibleReportCost() const;
00300 inline double sumInfeasibilities() const {
00301 return sumInfeasibilities_;
00302 }
00304 inline double largestInfeasibility() const {
00305 return largestInfeasibility_;
00306 }
00308 inline double averageTheta() const {
00309 return averageTheta_;
00310 }
00311 inline void setAverageTheta(double value) {
00312 averageTheta_ = value;
00313 }
00314 inline void setChangeInCost(double value) {
00315 changeCost_ = value;
00316 }
00317 inline void setMethod(int value) {
00318 method_ = value;
00319 }
00321 inline bool lookBothWays() const {
00322 return bothWays_;
00323 }
00325
00326 inline bool infeasible(int i) const {
00327 return ((infeasible_[i>>5] >> (i & 31)) & 1) != 0;
00328 }
00329 inline void setInfeasible(int i, bool trueFalse) {
00330 unsigned int & value = infeasible_[i>>5];
00331 int bit = i & 31;
00332 if (trueFalse)
00333 value |= (1 << bit);
00334 else
00335 value &= ~(1 << bit);
00336 }
00337 inline unsigned char * statusArray() const {
00338 return status_;
00339 }
00341 void validate();
00343
00344 private:
00347
00348 double changeCost_;
00350 double feasibleCost_;
00352 double infeasibilityWeight_;
00354 double largestInfeasibility_;
00356 double sumInfeasibilities_;
00358 double averageTheta_;
00360 int numberRows_;
00362 int numberColumns_;
00364 int * start_;
00366 int * whichRange_;
00368 int * offset_;
00372 double * lower_;
00374 double * cost_;
00376 ClpSimplex * model_;
00377
00378 unsigned int * infeasible_;
00380 int numberInfeasibilities_;
00381
00383 unsigned char * status_;
00385 double * bound_;
00387 double * cost2_;
00389 int method_;
00391 bool convex_;
00393 bool bothWays_;
00395 };
00396
00397 #endif