RMOL Logo  0.25.3
C++ library of Revenue Management and Optimisation classes and functions
Detruncator.cpp
Go to the documentation of this file.
00001 // //////////////////////////////////////////////////////////////////////
00002 // Import section
00003 // //////////////////////////////////////////////////////////////////////
00004 // STL
00005 #include <cassert>
00006 // StdAir
00007 #include <stdair/basic/BasConst_Inventory.hpp>
00008 #include <stdair/bom/GuillotineBlock.hpp>
00009 #include <stdair/bom/BomManager.hpp>
00010 #include <stdair/bom/FlightDate.hpp>
00011 #include <stdair/bom/SegmentDate.hpp>
00012 #include <stdair/bom/SegmentCabin.hpp>
00013 #include <stdair/bom/BookingClass.hpp>
00014 #include <stdair/service/Logger.hpp>
00015 // RMOL
00016 #include <rmol/bom/GuillotineBlockHelper.hpp>
00017 #include <rmol/bom/HistoricalBookingHolder.hpp>
00018 #include <rmol/bom/HistoricalBooking.hpp>
00019 #include <rmol/bom/EMDetruncator.hpp>
00020 #include <rmol/command/Detruncator.hpp>
00021 
00022 namespace RMOL {
00023   // ////////////////////////////////////////////////////////////////////
00024   void Detruncator::
00025   unconstrainUsingAdditivePickUp (const stdair::SegmentCabin& iSegmentCabin,
00026                BookingClassUnconstrainedDemandVectorMap_T& ioBkgClassUncDemMap,
00027                UnconstrainedDemandVector_T& ioQEquivalentDemandVector,
00028                const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
00029                const stdair::Date_T& iCurrentDate) {
00030 
00031     // Retrieve the guillotine block.
00032     const stdair::GuillotineBlock& lGuillotineBlock =
00033       iSegmentCabin.getGuillotineBlock();
00034 
00035     // Build the historical booking holders for the product-oriented bookings
00036     // of the casses and the Q-equivalent (price-oriented) bookings of the cabin
00037     const stdair::NbOfSegments_T lNbOfUsableSegments = GuillotineBlockHelper::
00038       getNbOfSegmentAlreadyPassedThisDTD (lGuillotineBlock, iDCPEnd,
00039                                           iCurrentDate);
00040 
00041     // Parse the booking class list and unconstrain historical bookings.
00042     for (BookingClassUnconstrainedDemandVectorMap_T::iterator itBCUDV =
00043            ioBkgClassUncDemMap.begin(); itBCUDV != ioBkgClassUncDemMap.end();
00044          ++itBCUDV) {
00045       stdair::BookingClass* lBC_ptr = itBCUDV->first;
00046       assert (lBC_ptr != NULL);
00047       const stdair::MapKey_T& lBCKey = lBC_ptr->describeKey();
00048       const stdair::BlockIndex_T& lBlockIdx =
00049         lGuillotineBlock.getBlockIndex (lBCKey);
00050       UnconstrainedDemandVector_T& lUncDemVector = itBCUDV->second;
00051 
00052       STDAIR_LOG_DEBUG ("Unconstrain product-oriented bookings for " << lBCKey);
00053       // STDAIR_LOG_NOTIFICATION (lBCKey << ";" << iDCPBegin
00054       //                          << ";" << iDCPEnd);
00055       unconstrainUsingAdditivePickUp (lGuillotineBlock, lUncDemVector,
00056                                       iDCPBegin, iDCPEnd,
00057                                       lNbOfUsableSegments, lBlockIdx);
00058     }
00059 
00060     // Unconstrain the Q-equivalent bookings.
00061     // Retrieve the block index of the segment-cabin.
00062     std::ostringstream lSCMapKey;
00063     lSCMapKey << stdair::DEFAULT_SEGMENT_CABIN_VALUE_TYPE
00064               << iSegmentCabin.describeKey();    
00065     const stdair::BlockIndex_T& lCabinIdx =
00066       lGuillotineBlock.getBlockIndex (lSCMapKey.str());
00067 
00068     STDAIR_LOG_DEBUG ("Unconstrain price-oriented bookings");
00069     //STDAIR_LOG_NOTIFICATION (iDCPBegin << ";" << iDCPEnd);
00070     unconstrainUsingAdditivePickUp (lGuillotineBlock, ioQEquivalentDemandVector,
00071                                     iDCPBegin, iDCPEnd, lNbOfUsableSegments,
00072                                     lCabinIdx, iSegmentCabin, iCurrentDate);
00073   }
00074 
00075   // ////////////////////////////////////////////////////////////////////
00076   void Detruncator::unconstrainUsingAdditivePickUp
00077   (const stdair::GuillotineBlock& iGuillotineBlock,
00078    UnconstrainedDemandVector_T& ioUncDemVector,
00079    const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
00080    const stdair::NbOfSegments_T& iNbOfUsableSegments,
00081    const stdair::BlockIndex_T& iBlockIdx) {
00082     // TODO:
00083     stdair::NbOfSegments_T lSegBegin = 0;
00084     if (iNbOfUsableSegments > 52) lSegBegin = iNbOfUsableSegments - 52;
00085     // Retrieve the gross daily booking and availability snapshots.
00086     stdair::ConstSegmentCabinDTDRangeSnapshotView_T lBookingView =
00087       iGuillotineBlock.getConstSegmentCabinDTDRangeProductAndPriceOrientedBookingSnapshotView (lSegBegin, iNbOfUsableSegments -1, iDCPEnd, iDCPBegin);
00088     stdair::ConstSegmentCabinDTDRangeSnapshotView_T lAvlView =
00089       iGuillotineBlock.getConstSegmentCabinDTDRangeAvailabilitySnapshotView (lSegBegin, iNbOfUsableSegments -1, iDCPEnd, iDCPBegin);
00090     
00091     // Browse the list of segments and build the historical booking holder.
00092     const stdair::ValueTypeIndexMap_T& lVTIdxMap =
00093       iGuillotineBlock.getValueTypeIndexMap();
00094     const unsigned int lNbOfValueTypes = lVTIdxMap.size();
00095     HistoricalBookingHolder lHBHolder;
00096     for (short i = 0; i < iNbOfUsableSegments-lSegBegin; ++i) {
00097       stdair::Flag_T lCensorshipFlag = false;
00098       stdair::NbOfBookings_T lNbOfHistoricalBkgs = 0.0;
00099       const short lNbOfDTDs = iDCPBegin - iDCPEnd + 1;
00100       
00101       // Parse the DTDs during the period
00102       for (short j = 0; j < lNbOfDTDs; ++j) {
00103         // Check if the data has been censored during this day.
00104         // STDAIR_LOG_DEBUG ("i: " << i << ", NbOfValues: " << lNbOfValueTypes
00105         //                   << ", BlockIdx: " << iBlockIdx << ", j: " << j);
00106         if (lCensorshipFlag == false) {
00107           if (lAvlView[i*lNbOfValueTypes + iBlockIdx][j] < 1.0) {
00108             lCensorshipFlag = true;
00109           }
00110         }
00111         
00112         // Get the bookings of the day.
00113         //STDAIR_LOG_DEBUG ("Bookings of the day: " << lBookingView[i*lNbOfValueTypes + iBlockIdx][j]);
00114         lNbOfHistoricalBkgs += lBookingView[i*lNbOfValueTypes + iBlockIdx][j];
00115       }
00116       
00117       HistoricalBooking lHistoricalBkg (lNbOfHistoricalBkgs, lCensorshipFlag);
00118       lHBHolder.addHistoricalBooking (lHistoricalBkg);
00119 
00120       // DEBUG
00121       STDAIR_LOG_DEBUG ("Historical bkgs: " << lNbOfHistoricalBkgs
00122                         << ", censored: " << lCensorshipFlag);
00123       // STDAIR_LOG_NOTIFICATION (lNbOfHistoricalBkgs
00124       //                          << ";" << lCensorshipFlag);
00125     }
00126 
00127     // DEBUG
00128     STDAIR_LOG_DEBUG ("Unconstrain by EM");
00129     
00130     // Unconstrain the booking figures
00131     EMDetruncator::unconstrainUsingEMMethod (lHBHolder);
00132 
00133     // Add the unconstrained demand of the period to the unconstrained demand
00134     // vector.    
00135     short idx = 0;
00136     for (UnconstrainedDemandVector_T::iterator itUD = ioUncDemVector.begin();
00137          itUD != ioUncDemVector.end(); ++itUD, ++idx) {
00138       *itUD += lHBHolder.getUnconstrainedDemand (idx);
00139       //STDAIR_LOG_NOTIFICATION (lHBHolder.getUnconstrainedDemand (idx));
00140     }
00141   }
00142 
00143   // ////////////////////////////////////////////////////////////////////
00144   void Detruncator::unconstrainUsingAdditivePickUp
00145   (const stdair::GuillotineBlock& iGuillotineBlock,
00146    UnconstrainedDemandVector_T& ioUncDemVector,
00147    const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
00148    const stdair::NbOfSegments_T& iNbOfUsableSegments,
00149    const stdair::BlockIndex_T& iBlockIdx,
00150    const stdair::SegmentCabin& iSegmentCabin,
00151    const stdair::Date_T& iCurrentDate) {
00152     // TODO
00153     stdair::NbOfSegments_T lSegBegin = 0;
00154     if (iNbOfUsableSegments > 52) lSegBegin = iNbOfUsableSegments - 52;
00155     // Retrieve the gross daily booking and availability snapshots.
00156     stdair::ConstSegmentCabinDTDRangeSnapshotView_T lBookingView =
00157       iGuillotineBlock.getConstSegmentCabinDTDRangeProductAndPriceOrientedBookingSnapshotView (lSegBegin, iNbOfUsableSegments -1, iDCPEnd, iDCPBegin);
00158     stdair::ConstSegmentCabinDTDRangeSnapshotView_T lAvlView =
00159       iGuillotineBlock.getConstSegmentCabinDTDRangeAvailabilitySnapshotView (lSegBegin, iNbOfUsableSegments -1, iDCPEnd, iDCPBegin);
00160     
00161     // Browse the list of segments and build the historical booking holder.
00162     const stdair::ValueTypeIndexMap_T& lVTIdxMap =
00163       iGuillotineBlock.getValueTypeIndexMap();
00164     const unsigned int lNbOfValueTypes = lVTIdxMap.size();
00165     HistoricalBookingHolder lHBHolder;
00166     for (short i = 0; i < iNbOfUsableSegments-lSegBegin; ++i) {
00167       stdair::Flag_T lCensorshipFlag = false;
00168       stdair::NbOfBookings_T lNbOfHistoricalBkgs = 0.0;
00169       const short lNbOfDTDs = iDCPBegin - iDCPEnd + 1;
00170       
00171       // Parse the DTDs during the period
00172       for (short j = 0; j < lNbOfDTDs; ++j) {
00173         // Check if the data has been censored during this day.
00174         // STDAIR_LOG_DEBUG ("i: " << i << ", NbOfValues: " << lNbOfValueTypes
00175         //                   << ", BlockIdx: " << iBlockIdx << ", j: " << j);
00176         if (lCensorshipFlag == false) {
00177           if (lAvlView[i*lNbOfValueTypes + iBlockIdx][j] < 1.0) {
00178             lCensorshipFlag = true;
00179           }
00180         }
00181         
00182         // Get the bookings of the day.
00183         //STDAIR_LOG_DEBUG ("Bookings of the day: " << lBookingView[i*lNbOfValueTypes + iBlockIdx][j]);
00184         lNbOfHistoricalBkgs += lBookingView[i*lNbOfValueTypes + iBlockIdx][j];
00185       }
00186       
00187       HistoricalBooking lHistoricalBkg (lNbOfHistoricalBkgs, lCensorshipFlag);
00188       lHBHolder.addHistoricalBooking (lHistoricalBkg);
00189 
00190       // DEBUG
00191       STDAIR_LOG_DEBUG ("Historical bkgs: " << lNbOfHistoricalBkgs
00192                         << ", censored: " << lCensorshipFlag);
00193       // STDAIR_LOG_NOTIFICATION (lNbOfHistoricalBkgs
00194       //                          << ";" << lCensorshipFlag);
00195     }
00196 
00197     // DEBUG
00198     STDAIR_LOG_DEBUG ("Unconstrain by EM");
00199     
00200     // Unconstrain the booking figures
00201     EMDetruncator::unconstrainUsingEMMethod (lHBHolder);
00202 
00203     // Add the unconstrained demand of the period to the unconstrained demand
00204     // vector.
00205     // LOG
00206     const stdair::SegmentDate& lSegmentDate = stdair::BomManager::
00207       getParent<stdair::SegmentDate, stdair::SegmentCabin> (iSegmentCabin);
00208     const stdair::FlightDate& lFlightDate = stdair::BomManager::
00209       getParent<stdair::FlightDate, stdair::SegmentDate> (lSegmentDate);
00210     const stdair::Date_T& lDepDate = lFlightDate.getDepartureDate();
00211     const boost::gregorian::date_duration lDD = lDepDate - iCurrentDate;
00212     const long lDTD = lDD.days();
00213     stdair::Date_T lRefDate (2012, boost::gregorian::Jan, 01);
00214     
00215     short idx = 0;
00216     for (UnconstrainedDemandVector_T::iterator itUD = ioUncDemVector.begin();
00217          itUD != ioUncDemVector.end(); ++itUD, ++idx) {
00218       *itUD += lHBHolder.getUnconstrainedDemand (idx);
00219       if (lDepDate > lRefDate) {
00220         const stdair::DateOffset_T lDateOffset (7 *(52 - idx) + 420);
00221         const stdair::Date_T lHDate = lDepDate - lDateOffset;
00222         STDAIR_LOG_NOTIFICATION (boost::gregorian::to_iso_string(lDepDate)
00223                                  << ";" << lDTD << ";" << iDCPBegin << ";"
00224                                  << iDCPEnd << ";"
00225                                  << boost::gregorian::to_iso_string (lHDate)
00226                                  <<";"<<lHBHolder.getUnconstrainedDemand (idx));
00227         
00228         STDAIR_LOG_NOTIFICATION (boost::gregorian::to_iso_string(lDepDate)
00229                                  << ";" << lDTD << ";" << iDCPBegin << ";"
00230                                  << iDCPEnd << ";"
00231                                  << boost::gregorian::to_iso_string (lHDate)
00232                                  <<";"<<lHBHolder.getHistoricalBooking (idx));
00233       }
00234     }
00235   }
00236   
00237   // ////////////////////////////////////////////////////////////////////
00238   void Detruncator::retrieveUnconstrainedDemandForFirstDCP
00239   (const stdair::SegmentCabin& iSegmentCabin,
00240    BookingClassUnconstrainedDemandVectorMap_T& ioBkgClassUncDemVectorMap,
00241    UnconstrainedDemandVector_T& ioQEquivalentDemandVector,
00242    const stdair::DCP_T& iFirstDCP, const stdair::NbOfSegments_T& iNbOfSegments,
00243    const stdair::NbOfSegments_T& iNbOfUsedSegments){
00244 
00245     // Retrieve the guillotine block.
00246     const stdair::GuillotineBlock& lGuillotineBlock =
00247       iSegmentCabin.getGuillotineBlock();
00248 
00249     // Parse the booking class list and unconstrain historical bookings.
00250     for (BookingClassUnconstrainedDemandVectorMap_T::iterator itBCUDV =
00251            ioBkgClassUncDemVectorMap.begin();
00252          itBCUDV != ioBkgClassUncDemVectorMap.end(); ++itBCUDV) {
00253       stdair::BookingClass* lBC_ptr = itBCUDV->first;
00254       assert (lBC_ptr != NULL);
00255       const stdair::MapKey_T& lBCKey = lBC_ptr->describeKey();
00256       const stdair::BlockIndex_T& lBlockIdx =
00257         lGuillotineBlock.getBlockIndex (lBCKey);
00258       UnconstrainedDemandVector_T& lUncDemVector = itBCUDV->second;
00259 
00260       STDAIR_LOG_DEBUG("Retrieve the unconstrained product-oriented demand for "
00261                        << lBCKey);
00262       retrieveUnconstrainedDemandForFirstDCP (lGuillotineBlock, lUncDemVector,
00263                                               iFirstDCP, lBlockIdx,
00264                                               iNbOfSegments, iNbOfUsedSegments);
00265     }
00266 
00267     // Unconstrain the Q-equivalent bookings.
00268     // Retrieve the block index of the segment-cabin.
00269     std::ostringstream lSCMapKey;
00270     lSCMapKey << stdair::DEFAULT_SEGMENT_CABIN_VALUE_TYPE
00271               << iSegmentCabin.describeKey();    
00272     const stdair::BlockIndex_T& lCabinValueIdx =
00273       lGuillotineBlock.getBlockIndex (lSCMapKey.str());
00274     
00275     STDAIR_LOG_DEBUG ("Retrieve the unconstrained price-oriented demand");
00276     retrieveUnconstrainedDemandForFirstDCP (lGuillotineBlock,
00277                                             ioQEquivalentDemandVector,iFirstDCP,
00278                                             lCabinValueIdx, iNbOfSegments,
00279                                             iNbOfUsedSegments);
00280   }
00281   
00282   // ////////////////////////////////////////////////////////////////////
00283   void Detruncator::retrieveUnconstrainedDemandForFirstDCP
00284   (const stdair::GuillotineBlock& iGuillotineBlock,
00285    UnconstrainedDemandVector_T& ioUnconstrainedDemandVector,
00286    const stdair::DCP_T& iFirstDCP, const stdair::BlockIndex_T& iValueIdx,
00287    const stdair::NbOfSegments_T& iNbOfSegments,
00288    const stdair::NbOfSegments_T& iNbOfUsedSegments) {
00289 
00290     //TODO
00291     stdair::NbOfSegments_T lSegBegin = iNbOfSegments - iNbOfUsedSegments;
00292     
00293     // Retrieve the snapshots of the corresponding booking value from the
00294     // first DTD (usually 365) till the given iFirstDCP.
00295     stdair::ConstSegmentCabinDTDRangeSnapshotView_T lRangeBookingView =
00296       iGuillotineBlock.getConstSegmentCabinDTDRangeProductAndPriceOrientedBookingSnapshotView (lSegBegin, iNbOfSegments -1, iFirstDCP, stdair::DEFAULT_MAX_DTD);
00297     
00298     // Sum the bookings from the first day till the given iFirstDCP in order to
00299     // get the supposing unconstrained demand for this period.
00300     const stdair::ValueTypeIndexMap_T& lVTIdxMap =
00301       iGuillotineBlock.getValueTypeIndexMap();
00302     const unsigned int lNbOfValueTypes = lVTIdxMap.size();
00303     for (int itSegment = 0; itSegment < iNbOfSegments-lSegBegin; ++itSegment) {
00304       for (int i = iFirstDCP; i <= stdair::DEFAULT_MAX_DTD; ++i) {
00305         stdair::NbOfRequests_T& lUncDemand =
00306           ioUnconstrainedDemandVector.at(itSegment);
00307         lUncDemand +=
00308           lRangeBookingView[iValueIdx + itSegment*lNbOfValueTypes][i-iFirstDCP];
00309       }
00310       // STDAIR_LOG_NOTIFICATION (ioUnconstrainedDemandVector.at(itSegment)
00311       //                          << ";" << itSegment);
00312     }
00313   }
00314   
00315   // ////////////////////////////////////////////////////////////////////
00316   void Detruncator::unconstrainUsingMultiplicativePickUp
00317   (const stdair::SegmentCabin& iSegmentCabin,
00318    BookingClassUnconstrainedDemandVectorMap_T& ioBkgClassUncDemMap,
00319    UnconstrainedDemandVector_T& ioQEquivalentDemandVector,
00320    const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
00321    const stdair::Date_T& iCurrentDate,
00322    const stdair::NbOfSegments_T& iNbOfDepartedSegments) {
00323 
00324     // Retrieve the guillotine block.
00325     const stdair::GuillotineBlock& lGuillotineBlock =
00326       iSegmentCabin.getGuillotineBlock();
00327 
00328     // Build the historical booking holders for the product-oriented bookings
00329     // of the casses and the Q-equivalent (price-oriented) bookings of the cabin
00330     const stdair::NbOfSegments_T lNbOfUsableSegments = GuillotineBlockHelper::
00331       getNbOfSegmentAlreadyPassedThisDTD (lGuillotineBlock, iDCPEnd,
00332                                           iCurrentDate);
00333 
00334     // Parse the booking class list and unconstrain historical bookings.
00335     for (BookingClassUnconstrainedDemandVectorMap_T::iterator itBCUDV =
00336            ioBkgClassUncDemMap.begin(); itBCUDV != ioBkgClassUncDemMap.end();
00337          ++itBCUDV) {
00338       stdair::BookingClass* lBC_ptr = itBCUDV->first;
00339       assert (lBC_ptr != NULL);
00340       const stdair::MapKey_T& lBCKey = lBC_ptr->describeKey();
00341       const stdair::BlockIndex_T& lBlockIdx =
00342         lGuillotineBlock.getBlockIndex (lBCKey);
00343       UnconstrainedDemandVector_T& lUncDemVector = itBCUDV->second;
00344 
00345       STDAIR_LOG_DEBUG ("Unconstrain product-oriented bookings for " << lBCKey);
00346       unconstrainUsingMultiplicativePickUp (lGuillotineBlock, lUncDemVector,
00347                                             iDCPBegin, iDCPEnd,
00348                                             lNbOfUsableSegments, lBlockIdx,
00349                                             iNbOfDepartedSegments);
00350     }
00351 
00352     // Unconstrain the Q-equivalent bookings.
00353     // Retrieve the block index of the segment-cabin.
00354     std::ostringstream lSCMapKey;
00355     lSCMapKey << stdair::DEFAULT_SEGMENT_CABIN_VALUE_TYPE
00356               << iSegmentCabin.describeKey();    
00357     const stdair::BlockIndex_T& lCabinIdx =
00358       lGuillotineBlock.getBlockIndex (lSCMapKey.str());
00359 
00360     STDAIR_LOG_DEBUG ("Unconstrain price-oriented bookings");
00361     unconstrainUsingMultiplicativePickUp (lGuillotineBlock,
00362                                           ioQEquivalentDemandVector,
00363                                           iDCPBegin, iDCPEnd,
00364                                           lNbOfUsableSegments, lCabinIdx,
00365                                           iNbOfDepartedSegments,
00366                                           iSegmentCabin, iCurrentDate);
00367   }
00368 
00369   // ////////////////////////////////////////////////////////////////////
00370   void Detruncator::unconstrainUsingMultiplicativePickUp
00371   (const stdair::GuillotineBlock& iGuillotineBlock,
00372    UnconstrainedDemandVector_T& ioUncDemVector,
00373    const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
00374    const stdair::NbOfSegments_T& iNbOfUsableSegments,
00375    const stdair::BlockIndex_T& iBlockIdx,
00376    const stdair::NbOfSegments_T& iNbOfDepartedSegments) {
00377     // TODO:
00378     stdair::NbOfSegments_T lSegBegin = 0;
00379     if (iNbOfDepartedSegments > 52) {
00380       lSegBegin = iNbOfDepartedSegments - 52;
00381     }
00382     
00383     // Retrieve the gross daily booking and availability snapshots.
00384     stdair::ConstSegmentCabinDTDRangeSnapshotView_T lBookingView =
00385       iGuillotineBlock.getConstSegmentCabinDTDRangeProductAndPriceOrientedBookingSnapshotView (lSegBegin, iNbOfUsableSegments -1, iDCPEnd, iDCPBegin);
00386     stdair::ConstSegmentCabinDTDRangeSnapshotView_T lAvlView =
00387       iGuillotineBlock.getConstSegmentCabinDTDRangeAvailabilitySnapshotView (lSegBegin, iNbOfUsableSegments -1, iDCPEnd, iDCPBegin);
00388     
00389     // Browse the list of segments and build the historical booking holder.
00390     const stdair::ValueTypeIndexMap_T& lVTIdxMap =
00391       iGuillotineBlock.getValueTypeIndexMap();
00392     const unsigned int lNbOfValueTypes = lVTIdxMap.size();
00393     HistoricalBookingHolder lHBHolder;
00394     std::vector<short> lDataIndexList;
00395     for (short i = 0; i < iNbOfUsableSegments-lSegBegin; ++i) {
00396       stdair::Flag_T lCensorshipFlag = false;
00397       stdair::NbOfBookings_T lNbOfHistoricalBkgs = 0.0;
00398       const short lNbOfDTDs = iDCPBegin - iDCPEnd + 1;
00399       
00400       // Parse the DTDs during the period
00401       for (short j = 0; j < lNbOfDTDs; ++j) {
00402         // Check if the data has been censored during this day.
00403         // STDAIR_LOG_DEBUG ("i: " << i << ", NbOfValues: " << lNbOfValueTypes
00404         //                   << ", BlockIdx: " << iBlockIdx << ", j: " << j);
00405         if (lCensorshipFlag == false) {
00406           if (lAvlView[i*lNbOfValueTypes + iBlockIdx][j] < 1.0) {
00407             lCensorshipFlag = true;
00408           }
00409         }
00410         
00411         // Get the bookings of the day.
00412         //STDAIR_LOG_DEBUG ("Bookings of the day: " << lBookingView[i*lNbOfValueTypes + iBlockIdx][j]);
00413         lNbOfHistoricalBkgs += lBookingView[i*lNbOfValueTypes + iBlockIdx][j];
00414       }
00415 
00416       // If there is no booking till now for this class and for this segment,
00417       // there will be no unconstraining process.
00418       stdair::NbOfRequests_T& lUncDemand = ioUncDemVector.at (i);
00419       if (lUncDemand < 1.0) {
00420         lUncDemand += lNbOfHistoricalBkgs;
00421       } else {
00422         double lBkgDemandFactor = lNbOfHistoricalBkgs / lUncDemand;
00423         HistoricalBooking lHistoricalBkg (lBkgDemandFactor, lCensorshipFlag);
00424         lHBHolder.addHistoricalBooking (lHistoricalBkg);
00425         lDataIndexList.push_back (i);
00426       }
00427       
00428       // DEBUG
00429       STDAIR_LOG_DEBUG ("Historical bkgs: " << lNbOfHistoricalBkgs
00430                         << ", censored: " << lCensorshipFlag);
00431     }
00432 
00433     // DEBUG
00434     STDAIR_LOG_DEBUG ("Unconstrain by multiplicative pick-up using EM");
00435     
00436     // Unconstrain the booking figures
00437     unconstrainUsingMultiplicativePickUp (lHBHolder);
00438 
00439     // Update the unconstrained demand vector.
00440     short i = 0;
00441     for (std::vector<short>::iterator itIdx = lDataIndexList.begin();
00442          itIdx != lDataIndexList.end(); ++itIdx, ++i) {
00443       short lIdx = *itIdx;
00444       stdair::NbOfRequests_T& lPastDemand = ioUncDemVector.at (lIdx);
00445       const stdair::NbOfRequests_T& lUncDemandFactorOfThisPeriod =
00446         lHBHolder.getUnconstrainedDemand (i);
00447       lPastDemand *= (1+lUncDemandFactorOfThisPeriod);
00448     }
00449   }  
00450 
00451   // ////////////////////////////////////////////////////////////////////
00452   void Detruncator::unconstrainUsingMultiplicativePickUp
00453   (const stdair::GuillotineBlock& iGuillotineBlock,
00454    UnconstrainedDemandVector_T& ioUncDemVector,
00455    const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
00456    const stdair::NbOfSegments_T& iNbOfUsableSegments,
00457    const stdair::BlockIndex_T& iBlockIdx,
00458    const stdair::NbOfSegments_T& iNbOfDepartedSegments,
00459    const stdair::SegmentCabin& iSegmentCabin,
00460    const stdair::Date_T& iCurrentDate) {
00461     // TODO:
00462     stdair::NbOfSegments_T lSegBegin = 0;
00463     if (iNbOfDepartedSegments > 52) {
00464       lSegBegin = iNbOfDepartedSegments - 52;
00465     }
00466     
00467     // Retrieve the gross daily booking and availability snapshots.
00468     stdair::ConstSegmentCabinDTDRangeSnapshotView_T lBookingView =
00469       iGuillotineBlock.getConstSegmentCabinDTDRangeProductAndPriceOrientedBookingSnapshotView (lSegBegin, iNbOfUsableSegments -1, iDCPEnd, iDCPBegin);
00470     stdair::ConstSegmentCabinDTDRangeSnapshotView_T lAvlView =
00471       iGuillotineBlock.getConstSegmentCabinDTDRangeAvailabilitySnapshotView (lSegBegin, iNbOfUsableSegments -1, iDCPEnd, iDCPBegin);
00472     
00473     // Browse the list of segments and build the historical booking holder.
00474     const stdair::ValueTypeIndexMap_T& lVTIdxMap =
00475       iGuillotineBlock.getValueTypeIndexMap();
00476     const unsigned int lNbOfValueTypes = lVTIdxMap.size();
00477     HistoricalBookingHolder lHBHolder;
00478     std::vector<short> lDataIndexList;
00479     for (short i = 0; i < iNbOfUsableSegments-lSegBegin; ++i) {
00480       stdair::Flag_T lCensorshipFlag = false;
00481       stdair::NbOfBookings_T lNbOfHistoricalBkgs = 0.0;
00482       const short lNbOfDTDs = iDCPBegin - iDCPEnd + 1;
00483       
00484       // Parse the DTDs during the period
00485       for (short j = 0; j < lNbOfDTDs; ++j) {
00486         // Check if the data has been censored during this day.
00487         // STDAIR_LOG_DEBUG ("i: " << i << ", NbOfValues: " << lNbOfValueTypes
00488         //                   << ", BlockIdx: " << iBlockIdx << ", j: " << j);
00489         if (lCensorshipFlag == false) {
00490           if (lAvlView[i*lNbOfValueTypes + iBlockIdx][j] < 1.0) {
00491             lCensorshipFlag = true;
00492           }
00493         }
00494         
00495         // Get the bookings of the day.
00496         //STDAIR_LOG_DEBUG ("Bookings of the day: " << lBookingView[i*lNbOfValueTypes + iBlockIdx][j]);
00497         lNbOfHistoricalBkgs += lBookingView[i*lNbOfValueTypes + iBlockIdx][j];
00498       }
00499 
00500       // If there is no booking till now for this class and for this segment,
00501       // there will be no unconstraining process.
00502       stdair::NbOfRequests_T& lUncDemand = ioUncDemVector.at (i);
00503       if (lUncDemand < 1.0) {
00504         lUncDemand += lNbOfHistoricalBkgs;
00505       } else {
00506         double lBkgDemandFactor = lNbOfHistoricalBkgs / lUncDemand;
00507         HistoricalBooking lHistoricalBkg (lBkgDemandFactor, lCensorshipFlag);
00508         lHBHolder.addHistoricalBooking (lHistoricalBkg);
00509         lDataIndexList.push_back (i);
00510       }
00511       
00512       // DEBUG
00513       STDAIR_LOG_DEBUG ("Historical bkgs: " << lNbOfHistoricalBkgs
00514                         << ", censored: " << lCensorshipFlag);
00515     }
00516 
00517     // DEBUG
00518     STDAIR_LOG_DEBUG ("Unconstrain by multiplicative pick-up");
00519     
00520     // Unconstrain the booking figures
00521     unconstrainUsingMultiplicativePickUp (lHBHolder);
00522 
00523     // Update the unconstrained demand vector.
00524     // LOG
00525     const stdair::SegmentDate& lSegmentDate = stdair::BomManager::
00526       getParent<stdair::SegmentDate, stdair::SegmentCabin> (iSegmentCabin);
00527     const stdair::FlightDate& lFlightDate = stdair::BomManager::
00528       getParent<stdair::FlightDate, stdair::SegmentDate> (lSegmentDate);
00529     const stdair::Date_T& lDepDate = lFlightDate.getDepartureDate();
00530     const boost::gregorian::date_duration lDD = lDepDate - iCurrentDate;
00531     const long lDTD = lDD.days();
00532     stdair::Date_T lRefDate (2012, boost::gregorian::Jan, 01);
00533     
00534     short i = 0;
00535     for (std::vector<short>::iterator itIdx = lDataIndexList.begin();
00536          itIdx != lDataIndexList.end(); ++itIdx, ++i) {
00537       short lIdx = *itIdx;
00538       stdair::NbOfRequests_T& lPastDemand = ioUncDemVector.at (lIdx);
00539       const stdair::NbOfRequests_T& lUncDemandFactorOfThisPeriod =
00540         lHBHolder.getUnconstrainedDemand (i);
00541       const double lUncDemThisPeriod =
00542         lPastDemand * lUncDemandFactorOfThisPeriod;
00543       lPastDemand *= (1+lUncDemandFactorOfThisPeriod);
00544       if (lDepDate > lRefDate) {
00545         const stdair::DateOffset_T lDateOffset (7 *(53 - lIdx) + 420);
00546         const stdair::Date_T lHDate = lDepDate - lDateOffset;
00547         STDAIR_LOG_NOTIFICATION (boost::gregorian::to_iso_string(lDepDate)
00548                                  << ";" << lDTD << ";" << iDCPBegin << ";"
00549                                  << iDCPEnd << ";"
00550                                  << boost::gregorian::to_iso_string (lHDate)
00551                                  << ";" << lUncDemThisPeriod);
00552       }
00553     }
00554   }
00555 
00556   // ////////////////////////////////////////////////////////////////////
00557   void Detruncator::
00558   unconstrainUsingMultiplicativePickUp (HistoricalBookingHolder& ioHBHolder) {
00559     // We use two loops in this algorithm. The first one is for calculating the
00560     // average of unconstrained data. The second one is fore calculating the
00561     // average of unconstrained data and the constrained data which are higher
00562     // than the first average.
00563     short lNbOfUsedData = ioHBHolder.getNbOfUncensoredData();
00564     if (lNbOfUsedData > 0) {
00565       double lSumOfValues = 0.0;
00566       const short lNbOfData = ioHBHolder.getNbOfFlights();
00567 
00568       // First loop
00569       for (short i = 0; i < lNbOfData; ++i) {
00570         if (ioHBHolder.getCensorshipFlag (i) == false) {
00571           lSumOfValues += ioHBHolder.getHistoricalBooking (i);
00572         }
00573       }
00574       double lFirstAverage = lSumOfValues / lNbOfUsedData;
00575 
00576       // Second loop
00577       for (short i = 0; i < lNbOfData; ++i) {
00578         if (ioHBHolder.getCensorshipFlag (i) == true) {
00579           const stdair::NbOfBookings_T& lBkgs =
00580             ioHBHolder.getHistoricalBooking (i);
00581           if (lBkgs >= lFirstAverage) {
00582             lSumOfValues += lBkgs;
00583             ++lNbOfUsedData;
00584           }
00585         }
00586       }
00587       double lSecondAverage = lSumOfValues / lNbOfUsedData;
00588 
00589       // Last loop for updating the demand.
00590       for (short i = 0; i < lNbOfData; ++i) {
00591         if (ioHBHolder.getCensorshipFlag (i) == true) {
00592           const stdair::NbOfBookings_T& lBkgs =
00593             ioHBHolder.getHistoricalBooking (i);
00594           if (lBkgs < lSecondAverage) {
00595             ioHBHolder.setUnconstrainedDemand (lSecondAverage, i);
00596           }
00597         }
00598       }      
00599     }
00600   }
00601 }
00602   
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines