00001
00002
00003 #ifndef ClpNonLinearCost_H
00004 #define ClpNonLinearCost_H
00005
00006
00007 #include "CoinPragma.hpp"
00008
00009 class ClpSimplex;
00010 class CoinIndexedVector;
00011
00029
00030
00031
00032
00033
00034
00035 #define CLP_BELOW_LOWER 0
00036 #define CLP_FEASIBLE 1
00037 #define CLP_ABOVE_UPPER 2
00038 #define CLP_SAME 4
00039 inline int originalStatus(unsigned char status)
00040 { return (status&15);}
00041 inline int currentStatus(unsigned char status)
00042 { return (status>>4);}
00043 inline void setOriginalStatus(unsigned char & status,int value)
00044 {
00045 status = static_cast<unsigned char>(status & ~15);
00046 status = static_cast<unsigned char>(status | value);
00047 }
00048 inline void setCurrentStatus(unsigned char &status,int value)
00049 {
00050 status = static_cast<unsigned char>(status & ~(15<<4));
00051 status = static_cast<unsigned char>(status | (value<<4));
00052 }
00053 inline void setInitialStatus(unsigned char &status)
00054 { status = static_cast<unsigned char>(CLP_FEASIBLE | (CLP_SAME<<4)); }
00055 inline void setSameStatus(unsigned char &status)
00056 {
00057 status = static_cast<unsigned char>(status & ~(15<<4));
00058 status = static_cast<unsigned char>(status | (CLP_SAME<<4));
00059 }
00060
00061
00062 #ifndef FAST_CLPNON
00063 #define CLP_METHOD1 ((method_&1)!=0)
00064 #define CLP_METHOD2 ((method_&2)!=0)
00065 #else
00066 #define CLP_METHOD1 (false)
00067 #define CLP_METHOD2 (true)
00068 #endif
00069 class ClpNonLinearCost {
00070
00071 public:
00072
00073 public:
00074
00077
00078 ClpNonLinearCost();
00083 ClpNonLinearCost(ClpSimplex * model,int method=1);
00089 ClpNonLinearCost(ClpSimplex * model,const int * starts,
00090 const double * lower, const double * cost);
00092 ~ClpNonLinearCost();
00093
00094 ClpNonLinearCost(const ClpNonLinearCost&);
00095
00096 ClpNonLinearCost& operator=(const ClpNonLinearCost&);
00098
00099
00106 void checkInfeasibilities(double oldTolerance=0.0);
00110 void checkInfeasibilities(int numberInArray, const int * index);
00117 void checkChanged(int numberInArray, CoinIndexedVector * update);
00124 void goThru(int numberInArray, double multiplier,
00125 const int * index, const double * work,
00126 double * rhs);
00129 void goBack(int numberInArray, const int * index,
00130 double * rhs);
00136 void goBackAll(const CoinIndexedVector * update);
00138 void zapCosts();
00140 void refreshCosts(const double * columnCosts);
00142 void feasibleBounds();
00146 double setOne(int sequence, double solutionValue);
00149 void setOne(int sequence, double solutionValue, double lowerValue, double upperValue,
00150 double costValue=0.0);
00154 int setOneOutgoing(int sequence, double &solutionValue);
00156 double nearest(int sequence, double solutionValue);
00160 inline double changeInCost(int sequence, double alpha) const
00161 {
00162 double returnValue=0.0;
00163 if (CLP_METHOD1) {
00164 int iRange = whichRange_[sequence]+offset_[sequence];
00165 if (alpha>0.0)
00166 returnValue = cost_[iRange]-cost_[iRange-1];
00167 else
00168 returnValue = cost_[iRange]-cost_[iRange+1];
00169 }
00170 if (CLP_METHOD2) {
00171 returnValue = (alpha>0.0) ? infeasibilityWeight_ : -infeasibilityWeight_;
00172 }
00173 return returnValue;
00174 }
00175 inline double changeUpInCost(int sequence) const
00176 {
00177 double returnValue=0.0;
00178 if (CLP_METHOD1) {
00179 int iRange = whichRange_[sequence]+offset_[sequence];
00180 if (iRange+1!=start_[sequence+1]&&!infeasible(iRange+1))
00181 returnValue = cost_[iRange]-cost_[iRange+1];
00182 else
00183 returnValue = -1.0e100;
00184 }
00185 if (CLP_METHOD2) {
00186 returnValue = -infeasibilityWeight_;
00187 }
00188 return returnValue;
00189 }
00190 inline double changeDownInCost(int sequence) const
00191 {
00192 double returnValue=0.0;
00193 if (CLP_METHOD1) {
00194 int iRange = whichRange_[sequence]+offset_[sequence];
00195 if (iRange!=start_[sequence]&&!infeasible(iRange-1))
00196 returnValue = cost_[iRange]-cost_[iRange-1];
00197 else
00198 returnValue = 1.0e100;
00199 }
00200 if (CLP_METHOD2) {
00201 returnValue = infeasibilityWeight_;
00202 }
00203 return returnValue;
00204 }
00206 inline double changeInCost(int sequence, double alpha, double &rhs)
00207 {
00208 double returnValue=0.0;
00209 #ifdef NONLIN_DEBUG
00210 double saveRhs = rhs;
00211 #endif
00212 if (CLP_METHOD1) {
00213 int iRange = whichRange_[sequence]+offset_[sequence];
00214 if (alpha>0.0) {
00215 assert(iRange-1>=start_[sequence]);
00216 offset_[sequence]--;
00217 rhs += lower_[iRange]-lower_[iRange-1];
00218 returnValue = alpha*(cost_[iRange]-cost_[iRange-1]);
00219 } else {
00220 assert(iRange+1<start_[sequence+1]-1);
00221 offset_[sequence]++;
00222 rhs += lower_[iRange+2]-lower_[iRange+1];
00223 returnValue = alpha*(cost_[iRange]-cost_[iRange+1]);
00224 }
00225 }
00226 if (CLP_METHOD2) {
00227 #ifdef NONLIN_DEBUG
00228 double saveRhs1=rhs;
00229 rhs = saveRhs;
00230 #endif
00231 unsigned char iStatus = status_[sequence];
00232 int iWhere = currentStatus(iStatus);
00233 if (iWhere==CLP_SAME)
00234 iWhere = originalStatus(iStatus);
00235
00236 if (iWhere==CLP_FEASIBLE) {
00237 if (alpha>0.0) {
00238
00239 iWhere=CLP_BELOW_LOWER;
00240 rhs = COIN_DBL_MAX;
00241 } else {
00242
00243 iWhere=CLP_ABOVE_UPPER;
00244 rhs = COIN_DBL_MAX;
00245 }
00246 } else if(iWhere==CLP_BELOW_LOWER) {
00247 assert (alpha<0);
00248
00249 iWhere=CLP_FEASIBLE;
00250 rhs += bound_[sequence] - model_->upperRegion()[sequence];
00251 } else {
00252 assert (iWhere==CLP_ABOVE_UPPER);
00253
00254 iWhere=CLP_FEASIBLE;
00255 rhs += model_->lowerRegion()[sequence]-bound_[sequence];
00256 }
00257 setCurrentStatus(status_[sequence],iWhere);
00258 #ifdef NONLIN_DEBUG
00259 assert(saveRhs1==rhs);
00260 #endif
00261 returnValue = fabs(alpha)*infeasibilityWeight_;
00262 }
00263 return returnValue;
00264 }
00266 inline double lower(int sequence) const
00267 { return lower_[whichRange_[sequence]+offset_[sequence]];}
00269 inline double upper(int sequence) const
00270 { return lower_[whichRange_[sequence]+offset_[sequence]+1];}
00272 inline double cost(int sequence) const
00273 { return cost_[whichRange_[sequence]+offset_[sequence]];}
00275
00276
00279
00280 inline int numberInfeasibilities() const
00281 {return numberInfeasibilities_;}
00283 inline double changeInCost() const
00284 {return changeCost_;}
00286 inline double feasibleCost() const
00287 {return feasibleCost_;}
00289 double feasibleReportCost() const;
00291 inline double sumInfeasibilities() const
00292 {return sumInfeasibilities_;}
00294 inline double largestInfeasibility() const
00295 {return largestInfeasibility_;}
00297 inline double averageTheta() const
00298 {return averageTheta_;}
00299 inline void setAverageTheta(double value)
00300 {averageTheta_=value;}
00301 inline void setChangeInCost(double value)
00302 {changeCost_ = value;}
00303 inline void setMethod(int value)
00304 {method_ = value;}
00306 inline bool lookBothWays() const
00307 { return bothWays_;}
00309
00310 inline bool infeasible(int i) const {
00311 return ((infeasible_[i>>5]>>(i&31))&1)!=0;
00312 }
00313 inline void setInfeasible(int i,bool trueFalse) {
00314 unsigned int & value = infeasible_[i>>5];
00315 int bit = i&31;
00316 if (trueFalse)
00317 value |= (1<<bit);
00318 else
00319 value &= ~(1<<bit);
00320 }
00321 inline unsigned char * statusArray() const
00322 { return status_;}
00324 void validate();
00326
00327 private:
00330
00331 double changeCost_;
00333 double feasibleCost_;
00335 double infeasibilityWeight_;
00337 double largestInfeasibility_;
00339 double sumInfeasibilities_;
00341 double averageTheta_;
00343 int numberRows_;
00345 int numberColumns_;
00347 int * start_;
00349 int * whichRange_;
00351 int * offset_;
00355 double * lower_;
00357 double * cost_;
00359 ClpSimplex * model_;
00360
00361 unsigned int * infeasible_;
00363 int numberInfeasibilities_;
00364
00366 unsigned char * status_;
00368 double * bound_;
00370 double * cost2_;
00372 int method_;
00374 bool convex_;
00376 bool bothWays_;
00378 };
00379
00380 #endif