$treeview $search $mathjax
RMOL Logo  1.00.0
$projectbrief
$projectbrief
$searchbox

rmol/command/QForecasting.cpp

Go to the documentation of this file.
00001 // //////////////////////////////////////////////////////////////////////
00002 // Import section
00003 // //////////////////////////////////////////////////////////////////////
00004 // STL
00005 #include <cassert>
00006 #include <sstream>
00007 #include <cmath>
00008 // StdAir
00009 #include <stdair/basic/BasConst_General.hpp>
00010 #include <stdair/basic/BasConst_Inventory.hpp>
00011 #include <stdair/bom/BomManager.hpp>
00012 #include <stdair/bom/LegDate.hpp>
00013 #include <stdair/bom/SegmentDate.hpp>
00014 #include <stdair/bom/LegCabin.hpp>
00015 #include <stdair/bom/SegmentCabin.hpp>
00016 #include <stdair/bom/SegmentSnapshotTable.hpp>
00017 #include <stdair/bom/FareFamily.hpp>
00018 #include <stdair/bom/BookingClass.hpp>
00019 #include <stdair/service/Logger.hpp>
00020 // RMOL
00021 #include <rmol/bom/Utilities.hpp>
00022 #include <rmol/bom/SegmentSnapshotTableHelper.hpp>
00023 #include <rmol/bom/HistoricalBookingHolder.hpp>
00024 #include <rmol/bom/HistoricalBooking.hpp>
00025 #include <rmol/command/QForecasting.hpp>
00026 #include <rmol/command/Detruncator.hpp>
00027 
00028 namespace RMOL {
00029   // ////////////////////////////////////////////////////////////////////
00030   bool QForecasting::
00031   forecast (stdair::SegmentCabin& ioSegmentCabin,
00032             const stdair::Date_T& iCurrentDate,
00033             const stdair::DTD_T& iCurrentDTD,
00034             const stdair::UnconstrainingMethod& iUnconstrainingMethod,
00035             const stdair::NbOfSegments_T& iNbOfDepartedSegments) {
00036     // Retrieve the snapshot table.
00037     const stdair::SegmentSnapshotTable& lSegmentSnapshotTable =
00038       ioSegmentCabin.getSegmentSnapshotTable();
00039 
00040     // Retrieve the FRAT5Curve.
00041     const stdair::FareFamilyList_T& lFFList =
00042       stdair::BomManager::getList<stdair::FareFamily>(ioSegmentCabin);
00043     stdair::FareFamilyList_T::const_reverse_iterator itFF = lFFList.rbegin();
00044     assert (itFF != lFFList.rend());
00045     stdair::FareFamily* lFF_ptr = *itFF;
00046     assert (lFF_ptr != NULL);
00047     const stdair::FRAT5Curve_T lFRAT5Curve = lFF_ptr->getFrat5Curve();
00048 
00049     // Retrieve the booking class list and compute the sell up curves
00050     // and the dispatching curves.
00051     const stdair::BookingClassList_T& lBCList =
00052       stdair::BomManager::getList<stdair::BookingClass>(ioSegmentCabin);
00053     const stdair::BookingClassSellUpCurveMap_T lBCSellUpCurveMap =
00054       Utilities::computeSellUpFactorCurves (lFRAT5Curve, lBCList);
00055     const stdair::BookingClassDispatchingCurveMap_T lBCDispatchingCurveMap =
00056       Utilities::computeDispatchingFactorCurves (lFRAT5Curve, lBCList);
00057       
00058 
00059     // Browse all remaining DCP's and do unconstraining, forecasting
00060     // and dispatching.
00061     const stdair::DCPList_T lWholeDCPList = stdair::DEFAULT_DCP_LIST;
00062     stdair::DCPList_T::const_iterator itDCP = lWholeDCPList.begin();
00063     stdair::DCPList_T::const_iterator itNextDCP = itDCP; ++itNextDCP;
00064     for (; itNextDCP != lWholeDCPList.end(); ++itDCP, ++itNextDCP) {
00065       const stdair::DCP_T& lCurrentDCP = *itDCP;
00066       const stdair::DCP_T& lNextDCP = *itNextDCP;
00067 
00068       // The end of the interval is after the current DTD.
00069       if (lNextDCP < iCurrentDTD) {
00070         // Get the number of similar segments which has already passed the
00071         // (lNextDCP+1)
00072         const stdair::NbOfSegments_T& lNbOfUsableSegments =
00073           SegmentSnapshotTableHelper::
00074           getNbOfSegmentAlreadyPassedThisDTD (lSegmentSnapshotTable,
00075                                               lNextDCP+1,
00076                                               iCurrentDate);
00077         stdair::NbOfSegments_T lSegmentBegin = 0;
00078         const stdair::NbOfSegments_T lSegmentEnd = lNbOfUsableSegments-1;
00079         if (iNbOfDepartedSegments > 52) {
00080           lSegmentBegin = iNbOfDepartedSegments - 52;
00081         }
00082         
00083         // Retrieve the historical bookings and convert them to
00084         // Q-equivalent bookings.
00085         HistoricalBookingHolder lHBHolder;
00086         preparePriceOrientedHistoricalBooking (ioSegmentCabin,
00087                                                lSegmentSnapshotTable, lHBHolder,
00088                                                lCurrentDCP, lNextDCP,
00089                                                lSegmentBegin, lSegmentEnd,
00090                                                lBCSellUpCurveMap);
00091 
00092         // Unconstrain the historical bookings.
00093         Detruncator::unconstrain (lHBHolder, iUnconstrainingMethod);
00094 
00095         // Retrieve the historical unconstrained demand and perform the
00096         // forecasting.
00097         stdair::UncDemVector_T lUncDemVector;
00098         const short lNbOfHistoricalFlights = lHBHolder.getNbOfFlights();
00099         for (short i = 0; i < lNbOfHistoricalFlights; ++i) {
00100           const stdair::NbOfBookings_T& lUncDemand =
00101             lHBHolder.getUnconstrainedDemand (i);
00102           lUncDemVector.push_back (lUncDemand);
00103         }
00104         stdair::MeanValue_T lMean = 0.0;
00105         stdair::StdDevValue_T lStdDev = 0.0;
00106         Utilities::computeDistributionParameters (lUncDemVector,
00107                                                   lMean, lStdDev);
00108 
00109         // Dispatch the forecast to all the classes.
00110         Utilities::dispatchDemandForecast (lBCDispatchingCurveMap,
00111                                            lMean, lStdDev, lCurrentDCP);
00112 
00113         // Dispatch the forecast to all classes for Fare Adjustment or MRT.
00114         // The sell-up probability will be used in this case.
00115         Utilities::dispatchDemandForecastForFA (lBCDispatchingCurveMap,
00116                                                 lMean, lStdDev, lCurrentDCP);
00117 
00118         // Add the demand forecast to the fare family.
00119         const stdair::MeanValue_T& lCurrentMean = lFF_ptr->getMean();
00120         const stdair::StdDevValue_T& lCurrentStdDev = lFF_ptr->getStdDev();
00121 
00122         const stdair::MeanValue_T lNewMean = lCurrentMean + lMean;
00123         const stdair::StdDevValue_T lNewStdDev = 
00124           std::sqrt (lCurrentStdDev * lCurrentStdDev + lStdDev * lStdDev);
00125 
00126         lFF_ptr->setMean (lNewMean);
00127         lFF_ptr->setStdDev (lNewStdDev);       
00128       }
00129     }
00130 
00131     return true;
00132   }
00133   
00134   // ////////////////////////////////////////////////////////////////////
00135   void QForecasting::preparePriceOrientedHistoricalBooking
00136     (const stdair::SegmentCabin& iSegmentCabin,
00137      const stdair::SegmentSnapshotTable& iSegmentSnapshotTable,
00138      HistoricalBookingHolder& ioHBHolder,
00139      const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
00140      const stdair::NbOfSegments_T& iSegmentBegin,
00141      const stdair::NbOfSegments_T& iSegmentEnd,
00142      const stdair::BookingClassSellUpCurveMap_T& iBCSellUpCurveMap) {
00143 
00144     // Retrieve the segment-cabin index within the snapshot table
00145     std::ostringstream lSCMapKey;
00146     lSCMapKey << stdair::DEFAULT_SEGMENT_CABIN_VALUE_TYPE
00147               << iSegmentCabin.describeKey();    
00148     const stdair::ClassIndex_T& lCabinIdx =
00149       iSegmentSnapshotTable.getClassIndex (lSCMapKey.str());
00150 
00151     // Retrieve the gross daily booking and availability snapshots.
00152     const stdair::ConstSegmentCabinDTDRangeSnapshotView_T lBookingView =
00153       iSegmentSnapshotTable.getConstSegmentCabinDTDRangePriceOrientedGrossBookingSnapshotView (iSegmentBegin, iSegmentEnd, iDCPEnd, iDCPBegin);
00154     const stdair::ConstSegmentCabinDTDRangeSnapshotView_T lAvlView =
00155       iSegmentSnapshotTable.getConstSegmentCabinDTDRangeAvailabilitySnapshotView (iSegmentBegin, iSegmentEnd, iDCPEnd, iDCPBegin);
00156     
00157     // Browse the list of segments and build the historical booking holder.
00158     const stdair::ClassIndexMap_T& lVTIdxMap =
00159       iSegmentSnapshotTable.getClassIndexMap();
00160     const stdair::NbOfClasses_T lNbOfClasses = lVTIdxMap.size();
00161 
00162     for (short i = 0; i <= iSegmentEnd-iSegmentBegin; ++i) {
00163       stdair::Flag_T lCensorshipFlag = false;
00164       const short lNbOfDTDs = iDCPBegin - iDCPEnd + 1;
00165       const stdair::UnsignedIndex_T lIdx = i*lNbOfClasses + lCabinIdx;
00166 
00167       // Parse the DTDs during the period and compute the censorship flag
00168       for (short j = 0; j < lNbOfDTDs; ++j) {
00169         // Check if the data has been censored during this day.
00170         // STDAIR_LOG_DEBUG ("i: " << i << ", NbOfClasses: " << lNbOfClasses
00171         //                   << ", ClassIdx: " << iClassIdx << ", j: " << j);
00172         if (lAvlView[lIdx][j] < 1.0) {
00173           lCensorshipFlag = true;
00174           break;
00175         }
00176       }
00177 
00178       // Compute the Q-equivalent bookings
00179       stdair::NbOfBookings_T lNbOfHistoricalBkgs = 0.0;
00180       for (stdair::BookingClassSellUpCurveMap_T::const_iterator itBCSUC =
00181              iBCSellUpCurveMap.begin();
00182            itBCSUC != iBCSellUpCurveMap.end(); ++itBCSUC) {
00183         const stdair::BookingClass* lBookingClass_ptr = itBCSUC->first;
00184         assert (lBookingClass_ptr != NULL);
00185         const stdair::SellUpCurve_T& lSellUpCurve = itBCSUC->second;
00186         stdair::SellUpCurve_T::const_iterator itSellUp =
00187           lSellUpCurve.find (iDCPBegin);
00188         assert (itSellUp != lSellUpCurve.end());
00189         const stdair::SellupProbability_T& lSellUp = itSellUp->second;
00190         assert (lSellUp != 0);
00191 
00192         // Retrieve the number of bookings
00193         const stdair::ClassIndex_T& lClassIdx =
00194           iSegmentSnapshotTable.getClassIndex(lBookingClass_ptr->describeKey());
00195         stdair::NbOfBookings_T lNbOfBookings = 0.0;
00196         for (short j = 0; j < lNbOfDTDs; ++j) {
00197           lNbOfBookings += lBookingView[i*lNbOfClasses + lClassIdx][j];
00198         }
00199 
00200         const stdair::NbOfBookings_T lNbOfQEquivalentBkgs=lNbOfBookings/lSellUp;
00201         lNbOfHistoricalBkgs += lNbOfQEquivalentBkgs;
00202       }
00203 
00204       HistoricalBooking lHistoricalBkg (lNbOfHistoricalBkgs, lCensorshipFlag);
00205       ioHBHolder.addHistoricalBooking (lHistoricalBkg);
00206     }
00207   }
00208 }