00001
00002
00003
00004
00005
00006 #ifndef ClpNonLinearCost_H
00007 #define ClpNonLinearCost_H
00008
00009
00010 #include "CoinPragma.hpp"
00011
00012 class ClpSimplex;
00013 class CoinIndexedVector;
00014
00032
00033
00034
00035
00036
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
00070
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
00103 ClpNonLinearCost(const ClpNonLinearCost&);
00104
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();
00153 void refresh();
00157 double setOne(int sequence, double solutionValue);
00160 void setOne(int sequence, double solutionValue, double lowerValue, double upperValue,
00161 double costValue = 0.0);
00165 int setOneOutgoing(int sequence, double &solutionValue);
00167 double nearest(int sequence, double solutionValue);
00171 inline double changeInCost(int sequence, double alpha) const {
00172 double returnValue = 0.0;
00173 if (CLP_METHOD1) {
00174 int iRange = whichRange_[sequence] + offset_[sequence];
00175 if (alpha > 0.0)
00176 returnValue = cost_[iRange] - cost_[iRange-1];
00177 else
00178 returnValue = cost_[iRange] - cost_[iRange+1];
00179 }
00180 if (CLP_METHOD2) {
00181 returnValue = (alpha > 0.0) ? infeasibilityWeight_ : -infeasibilityWeight_;
00182 }
00183 return returnValue;
00184 }
00185 inline double changeUpInCost(int sequence) const {
00186 double returnValue = 0.0;
00187 if (CLP_METHOD1) {
00188 int iRange = whichRange_[sequence] + offset_[sequence];
00189 if (iRange + 1 != start_[sequence+1] && !infeasible(iRange + 1))
00190 returnValue = cost_[iRange] - cost_[iRange+1];
00191 else
00192 returnValue = -1.0e100;
00193 }
00194 if (CLP_METHOD2) {
00195 returnValue = -infeasibilityWeight_;
00196 }
00197 return returnValue;
00198 }
00199 inline double changeDownInCost(int sequence) const {
00200 double returnValue = 0.0;
00201 if (CLP_METHOD1) {
00202 int iRange = whichRange_[sequence] + offset_[sequence];
00203 if (iRange != start_[sequence] && !infeasible(iRange - 1))
00204 returnValue = cost_[iRange] - cost_[iRange-1];
00205 else
00206 returnValue = 1.0e100;
00207 }
00208 if (CLP_METHOD2) {
00209 returnValue = infeasibilityWeight_;
00210 }
00211 return returnValue;
00212 }
00214 inline double changeInCost(int sequence, double alpha, double &rhs) {
00215 double returnValue = 0.0;
00216 #ifdef NONLIN_DEBUG
00217 double saveRhs = rhs;
00218 #endif
00219 if (CLP_METHOD1) {
00220 int iRange = whichRange_[sequence] + offset_[sequence];
00221 if (alpha > 0.0) {
00222 assert(iRange - 1 >= start_[sequence]);
00223 offset_[sequence]--;
00224 rhs += lower_[iRange] - lower_[iRange-1];
00225 returnValue = alpha * (cost_[iRange] - cost_[iRange-1]);
00226 } else {
00227 assert(iRange + 1 < start_[sequence+1] - 1);
00228 offset_[sequence]++;
00229 rhs += lower_[iRange+2] - lower_[iRange+1];
00230 returnValue = alpha * (cost_[iRange] - cost_[iRange+1]);
00231 }
00232 }
00233 if (CLP_METHOD2) {
00234 #ifdef NONLIN_DEBUG
00235 double saveRhs1 = rhs;
00236 rhs = saveRhs;
00237 #endif
00238 unsigned char iStatus = status_[sequence];
00239 int iWhere = currentStatus(iStatus);
00240 if (iWhere == CLP_SAME)
00241 iWhere = originalStatus(iStatus);
00242
00243 if (iWhere == CLP_FEASIBLE) {
00244 if (alpha > 0.0) {
00245
00246 iWhere = CLP_BELOW_LOWER;
00247 rhs = COIN_DBL_MAX;
00248 } else {
00249
00250 iWhere = CLP_ABOVE_UPPER;
00251 rhs = COIN_DBL_MAX;
00252 }
00253 } else if (iWhere == CLP_BELOW_LOWER) {
00254 assert (alpha < 0);
00255
00256 iWhere = CLP_FEASIBLE;
00257 rhs += bound_[sequence] - model_->upperRegion()[sequence];
00258 } else {
00259 assert (iWhere == CLP_ABOVE_UPPER);
00260
00261 iWhere = CLP_FEASIBLE;
00262 rhs += model_->lowerRegion()[sequence] - bound_[sequence];
00263 }
00264 setCurrentStatus(status_[sequence], iWhere);
00265 #ifdef NONLIN_DEBUG
00266 assert(saveRhs1 == rhs);
00267 #endif
00268 returnValue = fabs(alpha) * infeasibilityWeight_;
00269 }
00270 return returnValue;
00271 }
00273 inline double lower(int sequence) const {
00274 return lower_[whichRange_[sequence] + offset_[sequence]];
00275 }
00277 inline double upper(int sequence) const {
00278 return lower_[whichRange_[sequence] + offset_[sequence] + 1];
00279 }
00281 inline double cost(int sequence) const {
00282 return cost_[whichRange_[sequence] + offset_[sequence]];
00283 }
00285
00286
00289
00290 inline int numberInfeasibilities() const {
00291 return numberInfeasibilities_;
00292 }
00294 inline double changeInCost() const {
00295 return changeCost_;
00296 }
00298 inline double feasibleCost() const {
00299 return feasibleCost_;
00300 }
00302 double feasibleReportCost() const;
00304 inline double sumInfeasibilities() const {
00305 return sumInfeasibilities_;
00306 }
00308 inline double largestInfeasibility() const {
00309 return largestInfeasibility_;
00310 }
00312 inline double averageTheta() const {
00313 return averageTheta_;
00314 }
00315 inline void setAverageTheta(double value) {
00316 averageTheta_ = value;
00317 }
00318 inline void setChangeInCost(double value) {
00319 changeCost_ = value;
00320 }
00321 inline void setMethod(int value) {
00322 method_ = value;
00323 }
00325 inline bool lookBothWays() const {
00326 return bothWays_;
00327 }
00329
00330 inline bool infeasible(int i) const {
00331 return ((infeasible_[i>>5] >> (i & 31)) & 1) != 0;
00332 }
00333 inline void setInfeasible(int i, bool trueFalse) {
00334 unsigned int & value = infeasible_[i>>5];
00335 int bit = i & 31;
00336 if (trueFalse)
00337 value |= (1 << bit);
00338 else
00339 value &= ~(1 << bit);
00340 }
00341 inline unsigned char * statusArray() const {
00342 return status_;
00343 }
00345 void validate();
00347
00348 private:
00351
00352 double changeCost_;
00354 double feasibleCost_;
00356 double infeasibilityWeight_;
00358 double largestInfeasibility_;
00360 double sumInfeasibilities_;
00362 double averageTheta_;
00364 int numberRows_;
00366 int numberColumns_;
00368 int * start_;
00370 int * whichRange_;
00372 int * offset_;
00376 double * lower_;
00378 double * cost_;
00380 ClpSimplex * model_;
00381
00382 unsigned int * infeasible_;
00384 int numberInfeasibilities_;
00385
00387 unsigned char * status_;
00389 double * bound_;
00391 double * cost2_;
00393 int method_;
00395 bool convex_;
00397 bool bothWays_;
00399 };
00400
00401 #endif