RMOL Logo Get Revenue Management Optimisation Library at SourceForge.net. Fast, secure and Free Open Source software downloads
BucketHolder.cpp
Go to the documentation of this file.
00001 // //////////////////////////////////////////////////////////////////////
00002 // Import section
00003 // //////////////////////////////////////////////////////////////////////
00004 // C
00005 #include <assert.h>
00006 // STL
00007 #include <iostream>
00008 #include <iomanip>
00009 // RMOL
00010 #include <rmol/bom/Bucket.hpp>
00011 #include <rmol/bom/BucketHolder.hpp>
00012 
00013 namespace RMOL {
00014 
00015   // //////////////////////////////////////////////////////////////////////
00016   BucketHolder::BucketHolder () :
00017     _cabinCapacity (100.0), _totalMeanDemand (0.0), _demandFactor (0.0),
00018     _optimalRevenue (0.0) {
00019   }
00020 
00021   // //////////////////////////////////////////////////////////////////////
00022   BucketHolder::BucketHolder (const double iCabinCapacity) :
00023     _cabinCapacity (iCabinCapacity), _totalMeanDemand (0.0), 
00024     _demandFactor (0.0), _optimalRevenue (0.0) {
00025   }
00026 
00027   // //////////////////////////////////////////////////////////////////////
00028   BucketHolder::~BucketHolder() {
00029     _bucketList.clear ();
00030   }
00031 
00032   // //////////////////////////////////////////////////////////////////////
00033   const short BucketHolder::getSize () const {
00034     return _bucketList.size();
00035   }
00036 
00037   // //////////////////////////////////////////////////////////////////////
00038   const std::string BucketHolder::describeShortKey() const {
00039     std::ostringstream oStr;
00040     oStr << _cabinCapacity;
00041     return oStr.str();
00042   }
00043   
00044   // //////////////////////////////////////////////////////////////////////
00045   const std::string BucketHolder::describeKey() const {
00046     return describeShortKey();
00047   }
00048 
00049   // //////////////////////////////////////////////////////////////////////
00050   std::string BucketHolder::toString() const {
00051     std::ostringstream oStr;
00052     oStr << describeShortKey()
00053          << ", " << _totalMeanDemand
00054          << ", " << _demandFactor  
00055          << ", " << _optimalRevenue
00056          << std::endl;
00057     
00058     return oStr.str();
00059   }   
00060 
00061   // //////////////////////////////////////////////////////////////////////
00062   void BucketHolder::toStream (std::ostream& ioOut) const {
00063     ioOut << toString();
00064   }
00065   
00066   // //////////////////////////////////////////////////////////////////////
00067   void BucketHolder::fromStream (std::istream& ioIn) {
00068   }
00069   
00070   // //////////////////////////////////////////////////////////////////////
00071   const std::string BucketHolder::shortDisplay() const {
00072     std::ostringstream oStr;
00073     oStr << describeKey();
00074     return oStr.str();
00075   }
00076   
00077   // //////////////////////////////////////////////////////////////////////
00078   const std::string BucketHolder::display() const {
00079     std::ostringstream oStr;
00080     oStr << shortDisplay();
00081     // Generate a CSV (Comma Separated Values) output
00082     oStr << "Class; Price; Mean; Std Dev; Protection; Cum. Protection; Cum. Bkg Limit; "
00083           << std::endl;
00084 
00085     BucketList_T::const_iterator itBucket = _bucketList.begin();
00086     for (short j=1; itBucket != _bucketList.end(); itBucket++, j++) {
00087       const Bucket* currentBucket_ptr = *itBucket;
00088       assert (currentBucket_ptr != NULL);
00089       
00090       oStr << j << "; " << currentBucket_ptr->display();
00091     }
00092 
00093     oStr << "Cabin Capacity = " << _cabinCapacity
00094          << "; Total Mean Demand = " << _totalMeanDemand
00095          << "; Demand Factor = " << _demandFactor
00096          << "; Optimal Revenue = " << _optimalRevenue 
00097          << std::endl;
00098     return oStr.str();
00099   }
00100 
00101   // //////////////////////////////////////////////////////////////////////
00102   Bucket& BucketHolder::getCurrentBucket () const {
00103     Bucket* resultBucket_ptr = *_itCurrentBucket;
00104     assert (resultBucket_ptr != NULL);
00105     
00106     return (*resultBucket_ptr);
00107   }
00108 
00109   // //////////////////////////////////////////////////////////////////////
00110   Bucket& BucketHolder::getNextBucket () const {
00111     Bucket* resultBucket_ptr = *_itNextBucket;
00112     assert (resultBucket_ptr != NULL);
00113     
00114     return (*resultBucket_ptr);
00115   }
00116 
00117   // //////////////////////////////////////////////////////////////////////
00118   Bucket& BucketHolder::getTaggedBucket () const {
00119     Bucket* resultBucket_ptr = *_itTaggedBucket;
00120     assert (resultBucket_ptr != NULL);
00121     
00122     return (*resultBucket_ptr);
00123   }
00124 
00125   // //////////////////////////////////////////////////////////////////////
00126   void BucketHolder::begin () {
00127     _itCurrentBucket = _bucketList.begin();
00128     _itNextBucket = _bucketList.begin();
00129     if (_itNextBucket != _bucketList.end()) {
00130       _itNextBucket++;
00131     }
00132   }
00133 
00134   // //////////////////////////////////////////////////////////////////////
00135   void BucketHolder::tag () {
00136       _itTaggedBucket = _itCurrentBucket;
00137   }
00138 
00139   // //////////////////////////////////////////////////////////////////////
00140   bool BucketHolder::hasNotReachedEnd () const {
00141     bool result = (_itCurrentBucket != _bucketList.end());
00142     return result;
00143   }
00144 
00145   // //////////////////////////////////////////////////////////////////////
00146   void BucketHolder::iterate () {
00147     if (_itCurrentBucket != _bucketList.end()) {
00148       _itCurrentBucket++;
00149     }
00150     if (_itNextBucket != _bucketList.end()) {
00151       _itNextBucket++;
00152     }
00153   }
00154 
00155   // //////////////////////////////////////////////////////////////////////
00156   const double BucketHolder::getPreviousCumulatedProtection () const {
00157     // Get the cumulated protection of the previous bucket. If the
00158     // current bucket is the first one, the function returns 0.0
00159     if (_itCurrentBucket == _bucketList.begin()) {
00160       return 0.0;
00161     } else {
00162       BucketList_T::iterator itPreviousBucket = _itCurrentBucket;
00163       --itPreviousBucket;
00164       Bucket* lPreviousBucket_ptr = *itPreviousBucket;
00165       const double oPreviousCumulatedProtection =
00166         lPreviousBucket_ptr->getCumulatedProtection();
00167       return oPreviousCumulatedProtection;
00168     }
00169   }
00170 
00171   // //////////////////////////////////////////////////////////////////////
00172   void BucketHolder::calculateMeanDemandAndOptimalRevenue () {
00173     _totalMeanDemand = 0.0;
00174     _optimalRevenue = 0.0;
00175 
00176     for (BucketList_T::const_iterator itBucket = _bucketList.begin();
00177          itBucket != _bucketList.end(); itBucket++) {
00178       const Bucket* currentBucket_ptr = *itBucket;
00179       assert (currentBucket_ptr != NULL);
00180 
00181       // Mean Demand
00182       const double currentMeanDemand = currentBucket_ptr->getMean();
00183       _totalMeanDemand += currentMeanDemand;
00184 
00185       // Optimal Revenue
00186       const double currentPrice = currentBucket_ptr->getAverageYield();
00187       const double currentProtection = currentBucket_ptr->getProtection();
00188       const double bucketOptimalRevenue = currentPrice * currentProtection;
00189       _optimalRevenue += bucketOptimalRevenue;
00190     }
00191 
00192     if (_cabinCapacity != 0.0) {
00193       _demandFactor = _totalMeanDemand / _cabinCapacity;
00194     }
00195   }
00196   
00197   // //////////////////////////////////////////////////////////////////////
00198   void BucketHolder::calculateProtectionAndBookingLimits () {
00199     // Number of classes/buckets: n
00200     const short nbOfClasses = getSize();
00201 
00207     begin();
00208     Bucket& firstBucket = getCurrentBucket();
00209 
00210     // Set the cumulated booking limit of Bucket(1) to be equal to the capacity
00211     firstBucket.setCumulatedBookingLimit (_cabinCapacity);
00212 
00215     firstBucket.setProtection (firstBucket.getCumulatedProtection());
00216 
00217     for (short j=1 ; j <= nbOfClasses - 1; j++, iterate()) {
00219       Bucket& currentBucket = getCurrentBucket();
00220       Bucket& nextBucket = getNextBucket();
00221 
00226       const double yjm1 = currentBucket.getCumulatedProtection();
00227       nextBucket.setCumulatedBookingLimit (_cabinCapacity - yjm1);
00228 
00231       const double yj = nextBucket.getCumulatedProtection();
00232       nextBucket.setProtection (yj - yjm1);
00233     }
00234   }
00235 
00236   // //////////////////////////////////////////////////////////////////////
00237   const double BucketHolder::getLowestAverageYield () {
00238     double oLowestAvgYield = 0.0;
00239 
00240     const short nbOfBuckets = getSize();
00241     assert (nbOfBuckets != 0);
00242 
00243     begin();
00244     Bucket& lFirstBucket = getCurrentBucket();
00245     oLowestAvgYield = lFirstBucket.getAverageYield();
00246 
00247     for (short j = 1; j < nbOfBuckets; ++j, iterate()) {
00248       Bucket& lNextBucket = getNextBucket();
00249       double lNextBucketAvgYield = lNextBucket.getAverageYield();
00250       if (lNextBucketAvgYield < oLowestAvgYield){
00251         oLowestAvgYield = lNextBucketAvgYield;
00252       }
00253     }
00254     return oLowestAvgYield;
00255   }
00256 
00257   // //////////////////////////////////////////////////////////////////////
00258   void BucketHolder::recalculate () {
00259     // Re-calculate the booking limits
00260     calculateProtectionAndBookingLimits();
00261     
00262     // Re-calculate the Optimal Revenue
00263     calculateMeanDemandAndOptimalRevenue();
00264   }
00265 
00266   // //////////////////////////////////////////////////////////////////////
00267   void BucketHolder::
00268   fillup (BookingLimitVector_T& ioBookingLimitVector) const {
00269     BucketList_T::const_iterator itBucket = _bucketList.begin();
00270     for (short j=1; itBucket != _bucketList.end(); itBucket++, j++) {
00271       const Bucket* currentBucket_ptr = *itBucket;
00272       assert (currentBucket_ptr != NULL);
00273       
00274       const double lCumulatedBookingLimit =
00275         currentBucket_ptr->getCumulatedBookingLimit();
00276       ioBookingLimitVector.push_back(lCumulatedBookingLimit);
00277     }
00278 
00279   }
00280 
00281 }