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 { status &= ~15;status |= value;}
00045 inline void setCurrentStatus(unsigned char &status,int value)
00046 { status &= ~(15<<4);status |= (value<<4);}
00047 inline void setInitialStatus(unsigned char &status)
00048 { status = CLP_FEASIBLE | (CLP_SAME<<4);}
00049 inline void setSameStatus(unsigned char &status)
00050 { status &= ~(15<<4);status |= (CLP_SAME<<4);}
00051
00052
00053 #ifndef FAST_CLPNON
00054 #define CLP_METHOD1 ((method_&1)!=0)
00055 #define CLP_METHOD2 ((method_&2)!=0)
00056 #else
00057 #define CLP_METHOD1 (false)
00058 #define CLP_METHOD2 (true)
00059 #endif
00060 class ClpNonLinearCost {
00061
00062 public:
00063
00064 public:
00065
00068
00069 ClpNonLinearCost();
00074 ClpNonLinearCost(ClpSimplex * model,int method=1);
00080 ClpNonLinearCost(ClpSimplex * model,const int * starts,
00081 const double * lower, const double * cost);
00083 ~ClpNonLinearCost();
00084
00085 ClpNonLinearCost(const ClpNonLinearCost&);
00086
00087 ClpNonLinearCost& operator=(const ClpNonLinearCost&);
00089
00090
00097 void checkInfeasibilities(double oldTolerance=0.0);
00101 void checkInfeasibilities(int numberInArray, const int * index);
00108 void checkChanged(int numberInArray, CoinIndexedVector * update);
00115 void goThru(int numberInArray, double multiplier,
00116 const int * index, const double * work,
00117 double * rhs);
00120 void goBack(int numberInArray, const int * index,
00121 double * rhs);
00127 void goBackAll(const CoinIndexedVector * update);
00129 void zapCosts();
00131 void refreshCosts(const double * columnCosts);
00133 void feasibleBounds();
00137 double setOne(int sequence, double solutionValue);
00140 void setOne(int sequence, double solutionValue, double lowerValue, double upperValue,
00141 double costValue=0.0);
00145 int setOneOutgoing(int sequence, double &solutionValue);
00147 double nearest(int sequence, double solutionValue);
00151 inline double changeInCost(int sequence, double alpha) const
00152 {
00153 double returnValue=0.0;
00154 if (CLP_METHOD1) {
00155 int iRange = whichRange_[sequence]+offset_[sequence];
00156 if (alpha>0.0)
00157 returnValue = cost_[iRange]-cost_[iRange-1];
00158 else
00159 returnValue = cost_[iRange]-cost_[iRange+1];
00160 }
00161 if (CLP_METHOD2) {
00162 returnValue = (alpha>0.0) ? infeasibilityWeight_ : -infeasibilityWeight_;
00163 }
00164 return returnValue;
00165 }
00166 inline double changeUpInCost(int sequence) const
00167 {
00168 double returnValue=0.0;
00169 if (CLP_METHOD1) {
00170 int iRange = whichRange_[sequence]+offset_[sequence];
00171 if (iRange+1!=start_[sequence+1]&&!infeasible(iRange+1))
00172 returnValue = cost_[iRange]-cost_[iRange+1];
00173 else
00174 returnValue = -1.0e100;
00175 }
00176 if (CLP_METHOD2) {
00177 returnValue = -infeasibilityWeight_;
00178 }
00179 return returnValue;
00180 }
00181 inline double changeDownInCost(int sequence) const
00182 {
00183 double returnValue=0.0;
00184 if (CLP_METHOD1) {
00185 int iRange = whichRange_[sequence]+offset_[sequence];
00186 if (iRange!=start_[sequence]&&!infeasible(iRange-1))
00187 returnValue = cost_[iRange]-cost_[iRange-1];
00188 else
00189 returnValue = 1.0e100;
00190 }
00191 if (CLP_METHOD2) {
00192 returnValue = infeasibilityWeight_;
00193 }
00194 return returnValue;
00195 }
00197 inline double changeInCost(int sequence, double alpha, double &rhs)
00198 {
00199 double returnValue=0.0;
00200 #ifdef NONLIN_DEBUG
00201 double saveRhs = rhs;
00202 #endif
00203 if (CLP_METHOD1) {
00204 int iRange = whichRange_[sequence]+offset_[sequence];
00205 if (alpha>0.0) {
00206 assert(iRange-1>=start_[sequence]);
00207 offset_[sequence]--;
00208 rhs += lower_[iRange]-lower_[iRange-1];
00209 returnValue = alpha*(cost_[iRange]-cost_[iRange-1]);
00210 } else {
00211 assert(iRange+1<start_[sequence+1]-1);
00212 offset_[sequence]++;
00213 rhs += lower_[iRange+2]-lower_[iRange+1];
00214 returnValue = alpha*(cost_[iRange]-cost_[iRange+1]);
00215 }
00216 }
00217 if (CLP_METHOD2) {
00218 #ifdef NONLIN_DEBUG
00219 double saveRhs1=rhs;
00220 rhs = saveRhs;
00221 #endif
00222 int iStatus = status_[sequence];
00223 int iWhere = currentStatus(iStatus);
00224 if (iWhere==CLP_SAME)
00225 iWhere = originalStatus(iStatus);
00226
00227 if (iWhere==CLP_FEASIBLE) {
00228 if (alpha>0.0) {
00229
00230 iWhere=CLP_BELOW_LOWER;
00231 rhs = COIN_DBL_MAX;
00232 } else {
00233
00234 iWhere=CLP_ABOVE_UPPER;
00235 rhs = COIN_DBL_MAX;
00236 }
00237 } else if(iWhere==CLP_BELOW_LOWER) {
00238 assert (alpha<0);
00239
00240 iWhere=CLP_FEASIBLE;
00241 rhs += bound_[sequence] - model_->upperRegion()[sequence];
00242 } else {
00243 assert (iWhere==CLP_ABOVE_UPPER);
00244
00245 iWhere=CLP_FEASIBLE;
00246 rhs += model_->lowerRegion()[sequence]-bound_[sequence];
00247 }
00248 setCurrentStatus(status_[sequence],iWhere);
00249 #ifdef NONLIN_DEBUG
00250 assert(saveRhs1==rhs);
00251 #endif
00252 returnValue = fabs(alpha)*infeasibilityWeight_;
00253 }
00254 return returnValue;
00255 }
00257 inline double lower(int sequence) const
00258 { return lower_[whichRange_[sequence]+offset_[sequence]];}
00260 inline double upper(int sequence) const
00261 { return lower_[whichRange_[sequence]+offset_[sequence]+1];}
00263 inline double cost(int sequence) const
00264 { return cost_[whichRange_[sequence]+offset_[sequence]];}
00266
00267
00270
00271 inline int numberInfeasibilities() const
00272 {return numberInfeasibilities_;}
00274 inline double changeInCost() const
00275 {return changeCost_;}
00277 inline double feasibleCost() const
00278 {return feasibleCost_;}
00280 double feasibleReportCost() const;
00282 inline double sumInfeasibilities() const
00283 {return sumInfeasibilities_;}
00285 inline double largestInfeasibility() const
00286 {return largestInfeasibility_;}
00288 inline double averageTheta() const
00289 {return averageTheta_;}
00290 inline void setAverageTheta(double value)
00291 {averageTheta_=value;}
00292 inline void setChangeInCost(double value)
00293 {changeCost_ = value;}
00294 inline void setMethod(int value)
00295 {method_ = value;}
00297 inline bool lookBothWays() const
00298 { return bothWays_;}
00300
00301 inline bool infeasible(int i) const {
00302 return ((infeasible_[i>>5]>>(i&31))&1)!=0;
00303 }
00304 inline void setInfeasible(int i,bool trueFalse) {
00305 unsigned int & value = infeasible_[i>>5];
00306 int bit = i&31;
00307 if (trueFalse)
00308 value |= (1<<bit);
00309 else
00310 value &= ~(1<<bit);
00311 }
00312 inline unsigned char * statusArray() const
00313 { return status_;}
00315 void validate();
00317
00318 private:
00321
00322 double changeCost_;
00324 double feasibleCost_;
00326 double infeasibilityWeight_;
00328 double largestInfeasibility_;
00330 double sumInfeasibilities_;
00332 double averageTheta_;
00334 int numberRows_;
00336 int numberColumns_;
00338 int * start_;
00340 int * whichRange_;
00342 int * offset_;
00346 double * lower_;
00348 double * cost_;
00350 ClpSimplex * model_;
00351
00352 unsigned int * infeasible_;
00354 int numberInfeasibilities_;
00355
00357 unsigned char * status_;
00359 double * bound_;
00361 double * cost2_;
00363 int method_;
00365 bool convex_;
00367 bool bothWays_;
00369 };
00370
00371 #endif