/build/buildd/clp-1.12.0/Clp/src/ClpNonLinearCost.hpp
Go to the documentation of this file.
00001 /* $Id: ClpNonLinearCost.hpp 1525 2010-02-26 17:27:59Z mjs $ */
00002 // Copyright (C) 2002, International Business Machines
00003 // Corporation and others.  All Rights Reserved.
00004 #ifndef ClpNonLinearCost_H
00005 #define ClpNonLinearCost_H
00006 
00007 
00008 #include "CoinPragma.hpp"
00009 
00010 class ClpSimplex;
00011 class CoinIndexedVector;
00012 
00030 /* status has original status and current status
00031    0 - below lower so stored is upper
00032    1 - in range
00033    2 - above upper so stored is lower
00034    4 - (for current) - same as original
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 {
00042      return (status & 15);
00043 }
00044 inline int currentStatus(unsigned char status)
00045 {
00046      return (status >> 4);
00047 }
00048 inline void setOriginalStatus(unsigned char & status, int value)
00049 {
00050      status = static_cast<unsigned char>(status & ~15);
00051      status = static_cast<unsigned char>(status | value);
00052 }
00053 inline void setCurrentStatus(unsigned char &status, int value)
00054 {
00055      status = static_cast<unsigned char>(status & ~(15 << 4));
00056      status = static_cast<unsigned char>(status | (value << 4));
00057 }
00058 inline void setInitialStatus(unsigned char &status)
00059 {
00060      status = static_cast<unsigned char>(CLP_FEASIBLE | (CLP_SAME << 4));
00061 }
00062 inline void setSameStatus(unsigned char &status)
00063 {
00064      status = static_cast<unsigned char>(status & ~(15 << 4));
00065      status = static_cast<unsigned char>(status | (CLP_SAME << 4));
00066 }
00067 // Use second version to get more speed
00068 //#define FAST_CLPNON
00069 #ifndef FAST_CLPNON
00070 #define CLP_METHOD1 ((method_&1)!=0)
00071 #define CLP_METHOD2 ((method_&2)!=0)
00072 #else
00073 #define CLP_METHOD1 (false)
00074 #define CLP_METHOD2 (true)
00075 #endif
00076 class ClpNonLinearCost  {
00077 
00078 public:
00079 
00080 public:
00081 
00084 
00085      ClpNonLinearCost();
00090      ClpNonLinearCost(ClpSimplex * model, int method = 1);
00096      ClpNonLinearCost(ClpSimplex * model, const int * starts,
00097                       const double * lower, const double * cost);
00099      ~ClpNonLinearCost();
00100      // Copy
00101      ClpNonLinearCost(const ClpNonLinearCost&);
00102      // Assignment
00103      ClpNonLinearCost& operator=(const ClpNonLinearCost&);
00105 
00106 
00113      void checkInfeasibilities(double oldTolerance = 0.0);
00117      void checkInfeasibilities(int numberInArray, const int * index);
00124      void checkChanged(int numberInArray, CoinIndexedVector * update);
00131      void goThru(int numberInArray, double multiplier,
00132                  const int * index, const double * work,
00133                  double * rhs);
00136      void goBack(int numberInArray, const int * index,
00137                  double * rhs);
00143      void goBackAll(const CoinIndexedVector * update);
00145      void zapCosts();
00147      void refreshCosts(const double * columnCosts);
00149      void feasibleBounds();
00153      double setOne(int sequence, double solutionValue);
00156      void setOne(int sequence, double solutionValue, double lowerValue, double upperValue,
00157                  double costValue = 0.0);
00161      int setOneOutgoing(int sequence, double &solutionValue);
00163      double nearest(int sequence, double solutionValue);
00167      inline double changeInCost(int sequence, double alpha) const {
00168           double returnValue = 0.0;
00169           if (CLP_METHOD1) {
00170                int iRange = whichRange_[sequence] + offset_[sequence];
00171                if (alpha > 0.0)
00172                     returnValue = cost_[iRange] - cost_[iRange-1];
00173                else
00174                     returnValue = cost_[iRange] - cost_[iRange+1];
00175           }
00176           if (CLP_METHOD2) {
00177                returnValue = (alpha > 0.0) ? infeasibilityWeight_ : -infeasibilityWeight_;
00178           }
00179           return returnValue;
00180      }
00181      inline double changeUpInCost(int sequence) const {
00182           double returnValue = 0.0;
00183           if (CLP_METHOD1) {
00184                int iRange = whichRange_[sequence] + offset_[sequence];
00185                if (iRange + 1 != start_[sequence+1] && !infeasible(iRange + 1))
00186                     returnValue = cost_[iRange] - cost_[iRange+1];
00187                else
00188                     returnValue = -1.0e100;
00189           }
00190           if (CLP_METHOD2) {
00191                returnValue = -infeasibilityWeight_;
00192           }
00193           return returnValue;
00194      }
00195      inline double changeDownInCost(int sequence) const {
00196           double returnValue = 0.0;
00197           if (CLP_METHOD1) {
00198                int iRange = whichRange_[sequence] + offset_[sequence];
00199                if (iRange != start_[sequence] && !infeasible(iRange - 1))
00200                     returnValue = cost_[iRange] - cost_[iRange-1];
00201                else
00202                     returnValue = 1.0e100;
00203           }
00204           if (CLP_METHOD2) {
00205                returnValue = infeasibilityWeight_;
00206           }
00207           return returnValue;
00208      }
00210      inline double changeInCost(int sequence, double alpha, double &rhs) {
00211           double returnValue = 0.0;
00212 #ifdef NONLIN_DEBUG
00213           double saveRhs = rhs;
00214 #endif
00215           if (CLP_METHOD1) {
00216                int iRange = whichRange_[sequence] + offset_[sequence];
00217                if (alpha > 0.0) {
00218                     assert(iRange - 1 >= start_[sequence]);
00219                     offset_[sequence]--;
00220                     rhs += lower_[iRange] - lower_[iRange-1];
00221                     returnValue = alpha * (cost_[iRange] - cost_[iRange-1]);
00222                } else {
00223                     assert(iRange + 1 < start_[sequence+1] - 1);
00224                     offset_[sequence]++;
00225                     rhs += lower_[iRange+2] - lower_[iRange+1];
00226                     returnValue = alpha * (cost_[iRange] - cost_[iRange+1]);
00227                }
00228           }
00229           if (CLP_METHOD2) {
00230 #ifdef NONLIN_DEBUG
00231                double saveRhs1 = rhs;
00232                rhs = saveRhs;
00233 #endif
00234                unsigned char iStatus = status_[sequence];
00235                int iWhere = currentStatus(iStatus);
00236                if (iWhere == CLP_SAME)
00237                     iWhere = originalStatus(iStatus);
00238                // rhs always increases
00239                if (iWhere == CLP_FEASIBLE) {
00240                     if (alpha > 0.0) {
00241                          // going below
00242                          iWhere = CLP_BELOW_LOWER;
00243                          rhs = COIN_DBL_MAX;
00244                     } else {
00245                          // going above
00246                          iWhere = CLP_ABOVE_UPPER;
00247                          rhs = COIN_DBL_MAX;
00248                     }
00249                } else if (iWhere == CLP_BELOW_LOWER) {
00250                     assert (alpha < 0);
00251                     // going feasible
00252                     iWhere = CLP_FEASIBLE;
00253                     rhs += bound_[sequence] - model_->upperRegion()[sequence];
00254                } else {
00255                     assert (iWhere == CLP_ABOVE_UPPER);
00256                     // going feasible
00257                     iWhere = CLP_FEASIBLE;
00258                     rhs += model_->lowerRegion()[sequence] - bound_[sequence];
00259                }
00260                setCurrentStatus(status_[sequence], iWhere);
00261 #ifdef NONLIN_DEBUG
00262                assert(saveRhs1 == rhs);
00263 #endif
00264                returnValue = fabs(alpha) * infeasibilityWeight_;
00265           }
00266           return returnValue;
00267      }
00269      inline double lower(int sequence) const {
00270           return lower_[whichRange_[sequence] + offset_[sequence]];
00271      }
00273      inline double upper(int sequence) const {
00274           return lower_[whichRange_[sequence] + offset_[sequence] + 1];
00275      }
00277      inline double cost(int sequence) const {
00278           return cost_[whichRange_[sequence] + offset_[sequence]];
00279      }
00281 
00282 
00285 
00286      inline int numberInfeasibilities() const {
00287           return numberInfeasibilities_;
00288      }
00290      inline double changeInCost() const {
00291           return changeCost_;
00292      }
00294      inline double feasibleCost() const {
00295           return feasibleCost_;
00296      }
00298      double feasibleReportCost() const;
00300      inline double sumInfeasibilities() const {
00301           return sumInfeasibilities_;
00302      }
00304      inline double largestInfeasibility() const {
00305           return largestInfeasibility_;
00306      }
00308      inline double averageTheta() const {
00309           return averageTheta_;
00310      }
00311      inline void setAverageTheta(double value) {
00312           averageTheta_ = value;
00313      }
00314      inline void setChangeInCost(double value) {
00315           changeCost_ = value;
00316      }
00317      inline void setMethod(int value) {
00318           method_ = value;
00319      }
00321      inline bool lookBothWays() const {
00322           return bothWays_;
00323      }
00325 
00326      inline bool infeasible(int i) const {
00327           return ((infeasible_[i>>5] >> (i & 31)) & 1) != 0;
00328      }
00329      inline void setInfeasible(int i, bool trueFalse) {
00330           unsigned int & value = infeasible_[i>>5];
00331           int bit = i & 31;
00332           if (trueFalse)
00333                value |= (1 << bit);
00334           else
00335                value &= ~(1 << bit);
00336      }
00337      inline unsigned char * statusArray() const {
00338           return status_;
00339      }
00341      void validate();
00343 
00344 private:
00347 
00348      double changeCost_;
00350      double feasibleCost_;
00352      double infeasibilityWeight_;
00354      double largestInfeasibility_;
00356      double sumInfeasibilities_;
00358      double averageTheta_;
00360      int numberRows_;
00362      int numberColumns_;
00364      int * start_;
00366      int * whichRange_;
00368      int * offset_;
00372      double * lower_;
00374      double * cost_;
00376      ClpSimplex * model_;
00377      // Array to say which regions are infeasible
00378      unsigned int * infeasible_;
00380      int numberInfeasibilities_;
00381      // new stuff
00383      unsigned char * status_;
00385      double * bound_;
00387      double * cost2_;
00389      int method_;
00391      bool convex_;
00393      bool bothWays_;
00395 };
00396 
00397 #endif