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 { return (status&15);}
00042 inline int currentStatus(unsigned char status)
00043 { return (status>>4);}
00044 inline void setOriginalStatus(unsigned char & status,int value)
00045 {
00046 status = static_cast<unsigned char>(status & ~15);
00047 status = static_cast<unsigned char>(status | value);
00048 }
00049 inline void setCurrentStatus(unsigned char &status,int value)
00050 {
00051 status = static_cast<unsigned char>(status & ~(15<<4));
00052 status = static_cast<unsigned char>(status | (value<<4));
00053 }
00054 inline void setInitialStatus(unsigned char &status)
00055 { status = static_cast<unsigned char>(CLP_FEASIBLE | (CLP_SAME<<4)); }
00056 inline void setSameStatus(unsigned char &status)
00057 {
00058 status = static_cast<unsigned char>(status & ~(15<<4));
00059 status = static_cast<unsigned char>(status | (CLP_SAME<<4));
00060 }
00061
00062
00063 #ifndef FAST_CLPNON
00064 #define CLP_METHOD1 ((method_&1)!=0)
00065 #define CLP_METHOD2 ((method_&2)!=0)
00066 #else
00067 #define CLP_METHOD1 (false)
00068 #define CLP_METHOD2 (true)
00069 #endif
00070 class ClpNonLinearCost {
00071
00072 public:
00073
00074 public:
00075
00078
00079 ClpNonLinearCost();
00084 ClpNonLinearCost(ClpSimplex * model,int method=1);
00090 ClpNonLinearCost(ClpSimplex * model,const int * starts,
00091 const double * lower, const double * cost);
00093 ~ClpNonLinearCost();
00094
00095 ClpNonLinearCost(const ClpNonLinearCost&);
00096
00097 ClpNonLinearCost& operator=(const ClpNonLinearCost&);
00099
00100
00107 void checkInfeasibilities(double oldTolerance=0.0);
00111 void checkInfeasibilities(int numberInArray, const int * index);
00118 void checkChanged(int numberInArray, CoinIndexedVector * update);
00125 void goThru(int numberInArray, double multiplier,
00126 const int * index, const double * work,
00127 double * rhs);
00130 void goBack(int numberInArray, const int * index,
00131 double * rhs);
00137 void goBackAll(const CoinIndexedVector * update);
00139 void zapCosts();
00141 void refreshCosts(const double * columnCosts);
00143 void feasibleBounds();
00147 double setOne(int sequence, double solutionValue);
00150 void setOne(int sequence, double solutionValue, double lowerValue, double upperValue,
00151 double costValue=0.0);
00155 int setOneOutgoing(int sequence, double &solutionValue);
00157 double nearest(int sequence, double solutionValue);
00161 inline double changeInCost(int sequence, double alpha) const
00162 {
00163 double returnValue=0.0;
00164 if (CLP_METHOD1) {
00165 int iRange = whichRange_[sequence]+offset_[sequence];
00166 if (alpha>0.0)
00167 returnValue = cost_[iRange]-cost_[iRange-1];
00168 else
00169 returnValue = cost_[iRange]-cost_[iRange+1];
00170 }
00171 if (CLP_METHOD2) {
00172 returnValue = (alpha>0.0) ? infeasibilityWeight_ : -infeasibilityWeight_;
00173 }
00174 return returnValue;
00175 }
00176 inline double changeUpInCost(int sequence) const
00177 {
00178 double returnValue=0.0;
00179 if (CLP_METHOD1) {
00180 int iRange = whichRange_[sequence]+offset_[sequence];
00181 if (iRange+1!=start_[sequence+1]&&!infeasible(iRange+1))
00182 returnValue = cost_[iRange]-cost_[iRange+1];
00183 else
00184 returnValue = -1.0e100;
00185 }
00186 if (CLP_METHOD2) {
00187 returnValue = -infeasibilityWeight_;
00188 }
00189 return returnValue;
00190 }
00191 inline double changeDownInCost(int sequence) const
00192 {
00193 double returnValue=0.0;
00194 if (CLP_METHOD1) {
00195 int iRange = whichRange_[sequence]+offset_[sequence];
00196 if (iRange!=start_[sequence]&&!infeasible(iRange-1))
00197 returnValue = cost_[iRange]-cost_[iRange-1];
00198 else
00199 returnValue = 1.0e100;
00200 }
00201 if (CLP_METHOD2) {
00202 returnValue = infeasibilityWeight_;
00203 }
00204 return returnValue;
00205 }
00207 inline double changeInCost(int sequence, double alpha, double &rhs)
00208 {
00209 double returnValue=0.0;
00210 #ifdef NONLIN_DEBUG
00211 double saveRhs = rhs;
00212 #endif
00213 if (CLP_METHOD1) {
00214 int iRange = whichRange_[sequence]+offset_[sequence];
00215 if (alpha>0.0) {
00216 assert(iRange-1>=start_[sequence]);
00217 offset_[sequence]--;
00218 rhs += lower_[iRange]-lower_[iRange-1];
00219 returnValue = alpha*(cost_[iRange]-cost_[iRange-1]);
00220 } else {
00221 assert(iRange+1<start_[sequence+1]-1);
00222 offset_[sequence]++;
00223 rhs += lower_[iRange+2]-lower_[iRange+1];
00224 returnValue = alpha*(cost_[iRange]-cost_[iRange+1]);
00225 }
00226 }
00227 if (CLP_METHOD2) {
00228 #ifdef NONLIN_DEBUG
00229 double saveRhs1=rhs;
00230 rhs = saveRhs;
00231 #endif
00232 unsigned char iStatus = status_[sequence];
00233 int iWhere = currentStatus(iStatus);
00234 if (iWhere==CLP_SAME)
00235 iWhere = originalStatus(iStatus);
00236
00237 if (iWhere==CLP_FEASIBLE) {
00238 if (alpha>0.0) {
00239
00240 iWhere=CLP_BELOW_LOWER;
00241 rhs = COIN_DBL_MAX;
00242 } else {
00243
00244 iWhere=CLP_ABOVE_UPPER;
00245 rhs = COIN_DBL_MAX;
00246 }
00247 } else if(iWhere==CLP_BELOW_LOWER) {
00248 assert (alpha<0);
00249
00250 iWhere=CLP_FEASIBLE;
00251 rhs += bound_[sequence] - model_->upperRegion()[sequence];
00252 } else {
00253 assert (iWhere==CLP_ABOVE_UPPER);
00254
00255 iWhere=CLP_FEASIBLE;
00256 rhs += model_->lowerRegion()[sequence]-bound_[sequence];
00257 }
00258 setCurrentStatus(status_[sequence],iWhere);
00259 #ifdef NONLIN_DEBUG
00260 assert(saveRhs1==rhs);
00261 #endif
00262 returnValue = fabs(alpha)*infeasibilityWeight_;
00263 }
00264 return returnValue;
00265 }
00267 inline double lower(int sequence) const
00268 { return lower_[whichRange_[sequence]+offset_[sequence]];}
00270 inline double upper(int sequence) const
00271 { return lower_[whichRange_[sequence]+offset_[sequence]+1];}
00273 inline double cost(int sequence) const
00274 { return cost_[whichRange_[sequence]+offset_[sequence]];}
00276
00277
00280
00281 inline int numberInfeasibilities() const
00282 {return numberInfeasibilities_;}
00284 inline double changeInCost() const
00285 {return changeCost_;}
00287 inline double feasibleCost() const
00288 {return feasibleCost_;}
00290 double feasibleReportCost() const;
00292 inline double sumInfeasibilities() const
00293 {return sumInfeasibilities_;}
00295 inline double largestInfeasibility() const
00296 {return largestInfeasibility_;}
00298 inline double averageTheta() const
00299 {return averageTheta_;}
00300 inline void setAverageTheta(double value)
00301 {averageTheta_=value;}
00302 inline void setChangeInCost(double value)
00303 {changeCost_ = value;}
00304 inline void setMethod(int value)
00305 {method_ = value;}
00307 inline bool lookBothWays() const
00308 { return bothWays_;}
00310
00311 inline bool infeasible(int i) const {
00312 return ((infeasible_[i>>5]>>(i&31))&1)!=0;
00313 }
00314 inline void setInfeasible(int i,bool trueFalse) {
00315 unsigned int & value = infeasible_[i>>5];
00316 int bit = i&31;
00317 if (trueFalse)
00318 value |= (1<<bit);
00319 else
00320 value &= ~(1<<bit);
00321 }
00322 inline unsigned char * statusArray() const
00323 { return status_;}
00325 void validate();
00327
00328 private:
00331
00332 double changeCost_;
00334 double feasibleCost_;
00336 double infeasibilityWeight_;
00338 double largestInfeasibility_;
00340 double sumInfeasibilities_;
00342 double averageTheta_;
00344 int numberRows_;
00346 int numberColumns_;
00348 int * start_;
00350 int * whichRange_;
00352 int * offset_;
00356 double * lower_;
00358 double * cost_;
00360 ClpSimplex * model_;
00361
00362 unsigned int * infeasible_;
00364 int numberInfeasibilities_;
00365
00367 unsigned char * status_;
00369 double * bound_;
00371 double * cost2_;
00373 int method_;
00375 bool convex_;
00377 bool bothWays_;
00379 };
00380
00381 #endif