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();
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
00241 if (iWhere == CLP_FEASIBLE) {
00242 if (alpha > 0.0) {
00243
00244 iWhere = CLP_BELOW_LOWER;
00245 rhs = COIN_DBL_MAX;
00246 } else {
00247
00248 iWhere = CLP_ABOVE_UPPER;
00249 rhs = COIN_DBL_MAX;
00250 }
00251 } else if (iWhere == CLP_BELOW_LOWER) {
00252 assert (alpha < 0);
00253
00254 iWhere = CLP_FEASIBLE;
00255 rhs += bound_[sequence] - model_->upperRegion()[sequence];
00256 } else {
00257 assert (iWhere == CLP_ABOVE_UPPER);
00258
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
00380 unsigned int * infeasible_;
00382 int numberInfeasibilities_;
00383
00385 unsigned char * status_;
00387 double * bound_;
00389 double * cost2_;
00391 int method_;
00393 bool convex_;
00395 bool bothWays_;
00397 };
00398
00399 #endif