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

rmol/command/OldQFF.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/SegmentDate.hpp>
00013 #include <stdair/bom/SegmentCabin.hpp>
00014 #include <stdair/bom/SegmentSnapshotTable.hpp>
00015 #include <stdair/bom/FareFamily.hpp>
00016 #include <stdair/bom/BookingClass.hpp>
00017 #include <stdair/bom/Policy.hpp>
00018 #include <stdair/service/Logger.hpp>
00019 // RMOL
00020 #include <rmol/bom/Utilities.hpp>
00021 #include <rmol/bom/SegmentSnapshotTableHelper.hpp>
00022 #include <rmol/bom/HistoricalBookingHolder.hpp>
00023 #include <rmol/bom/HistoricalBooking.hpp>
00024 #include <rmol/bom/EMDetruncator.hpp>
00025 #include <rmol/command/OldQFF.hpp>
00026 #include <rmol/command/Detruncator.hpp>
00027 
00028 namespace RMOL {
00029   // ////////////////////////////////////////////////////////////////////
00030   bool OldQFF::
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 
00056     // Retrieve the list of all policies and reset the demand forecast
00057     // for each one.
00058     const stdair::PolicyList_T& lPolicyList =
00059       stdair::BomManager::getList<stdair::Policy> (ioSegmentCabin);
00060     for (stdair::PolicyList_T::const_iterator itPolicy = lPolicyList.begin();
00061          itPolicy != lPolicyList.end(); ++itPolicy) {
00062       stdair::Policy* lPolicy_ptr = *itPolicy;
00063       assert (lPolicy_ptr != NULL);
00064       lPolicy_ptr->resetDemandForecast();
00065     }
00066 
00067     // Browse all remaining DCP's and do unconstraining, forecasting
00068     // and dispatching.
00069     const stdair::DCPList_T lWholeDCPList = stdair::DEFAULT_DCP_LIST;
00070     stdair::DCPList_T::const_iterator itDCP = lWholeDCPList.begin();
00071     stdair::DCPList_T::const_iterator itNextDCP = itDCP; ++itNextDCP;
00072     for (; itNextDCP != lWholeDCPList.end(); ++itDCP, ++itNextDCP) {
00073       const stdair::DCP_T& lCurrentDCP = *itDCP;
00074       const stdair::DCP_T& lNextDCP = *itNextDCP;
00075 
00076       // The end of the interval is after the current DTD.
00077       if (lNextDCP < iCurrentDTD) {
00078         // Get the number of similar segments which has already passed the
00079         // (lNextDCP+1)
00080         const stdair::NbOfSegments_T& lNbOfUsableSegments =
00081           SegmentSnapshotTableHelper::
00082           getNbOfSegmentAlreadyPassedThisDTD (lSegmentSnapshotTable,
00083                                               lNextDCP+1,
00084                                               iCurrentDate);
00085         stdair::NbOfSegments_T lSegmentBegin = 0;
00086         const stdair::NbOfSegments_T lSegmentEnd = lNbOfUsableSegments-1;
00087         if (iNbOfDepartedSegments > 52) {
00088           lSegmentBegin = iNbOfDepartedSegments - 52;
00089         }
00090         
00091         // Retrieve the historical bookings and convert them to
00092         // Q-equivalent bookings.
00093         HistoricalBookingHolder lHBHolder;
00094         prepareHistoricalBooking (ioSegmentCabin, lSegmentSnapshotTable,
00095                                   lHBHolder, lCurrentDCP, lNextDCP,
00096                                   lSegmentBegin, lSegmentEnd,
00097                                   lBCSellUpCurveMap);
00098 
00099         // Unconstrain the historical bookings.
00100         Detruncator::unconstrain (lHBHolder, iUnconstrainingMethod);
00101 
00102         // Retrieve the historical unconstrained demand and perform the
00103         // forecasting.
00104         stdair::UncDemVector_T lUncDemVector;
00105         const short lNbOfHistoricalFlights = lHBHolder.getNbOfFlights();
00106         for (short i = 0; i < lNbOfHistoricalFlights; ++i) {
00107           const stdair::NbOfBookings_T& lUncDemand =
00108             lHBHolder.getUnconstrainedDemand (i);
00109           lUncDemVector.push_back (lUncDemand);
00110         }
00111         stdair::MeanValue_T lMean = 0.0;
00112         stdair::StdDevValue_T lStdDev = 0.0;
00113         Utilities::computeDistributionParameters (lUncDemVector,
00114                                                   lMean, lStdDev);
00115 
00116         // Add the demand forecast to the fare family.
00117         const stdair::MeanValue_T& lCurrentMean = lFF_ptr->getMean();
00118         const stdair::StdDevValue_T& lCurrentStdDev = lFF_ptr->getStdDev();
00119 
00120         const stdair::MeanValue_T lNewMean = lCurrentMean + lMean;
00121         const stdair::StdDevValue_T lNewStdDev = 
00122           std::sqrt (lCurrentStdDev * lCurrentStdDev + lStdDev * lStdDev);
00123 
00124         lFF_ptr->setMean (lNewMean);
00125         lFF_ptr->setStdDev (lNewStdDev);
00126  
00127         // Dispatch the demand forecast to the policies.
00128         dispatchDemandForecastToPolicies (lPolicyList, lCurrentDCP, lMean,
00129                                           lStdDev, lBCSellUpCurveMap);
00130       }
00131     }
00132 
00133     return true;
00134   }
00135   
00136   // ////////////////////////////////////////////////////////////////////
00137   void OldQFF::prepareHistoricalBooking
00138   (const stdair::SegmentCabin& iSegmentCabin,
00139    const stdair::SegmentSnapshotTable& iSegmentSnapshotTable,
00140    HistoricalBookingHolder& ioHBHolder,
00141    const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
00142    const stdair::NbOfSegments_T& iSegmentBegin,
00143    const stdair::NbOfSegments_T& iSegmentEnd,
00144    const stdair::BookingClassSellUpCurveMap_T& iBCSellUpCurveMap) {
00145     
00146     // Retrieve the segment-cabin index within the snapshot table
00147     std::ostringstream lSCMapKey;
00148     lSCMapKey << stdair::DEFAULT_SEGMENT_CABIN_VALUE_TYPE
00149               << iSegmentCabin.describeKey();    
00150     const stdair::ClassIndex_T& lCabinIdx =
00151       iSegmentSnapshotTable.getClassIndex (lSCMapKey.str());
00152     
00153     // Retrieve the gross daily booking and availability snapshots.
00154     const stdair::ConstSegmentCabinDTDRangeSnapshotView_T lPriceBookingView =
00155       iSegmentSnapshotTable.getConstSegmentCabinDTDRangePriceOrientedGrossBookingSnapshotView (iSegmentBegin, iSegmentEnd, iDCPEnd, iDCPBegin);
00156     const stdair::ConstSegmentCabinDTDRangeSnapshotView_T lProductBookingView =
00157       iSegmentSnapshotTable.getConstSegmentCabinDTDRangeProductOrientedGrossBookingSnapshotView (iSegmentBegin, iSegmentEnd, iDCPEnd, iDCPBegin);
00158     const stdair::ConstSegmentCabinDTDRangeSnapshotView_T lAvlView =
00159       iSegmentSnapshotTable.getConstSegmentCabinDTDRangeAvailabilitySnapshotView (iSegmentBegin, iSegmentEnd, iDCPEnd, iDCPBegin);
00160     
00161     // Browse the list of segments and build the historical booking holder.
00162     const stdair::ClassIndexMap_T& lVTIdxMap =
00163       iSegmentSnapshotTable.getClassIndexMap();
00164     const stdair::NbOfClasses_T lNbOfClasses = lVTIdxMap.size();
00165 
00166     for (short i = 0; i <= iSegmentEnd-iSegmentBegin; ++i) {
00167       stdair::Flag_T lCensorshipFlag = false;
00168       const short lNbOfDTDs = iDCPBegin - iDCPEnd + 1;
00169       const stdair::UnsignedIndex_T lAvlIdx = i*lNbOfClasses + lCabinIdx;
00170 
00171       // Parse the DTDs during the period and compute the censorship flag
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 << ", NbOfClasses: " << lNbOfClasses
00175         //                   << ", ClassIdx: " << iClassIdx << ", j: " << j);
00176         if (lAvlView[lAvlIdx][j] < 1.0) {
00177           lCensorshipFlag = true;
00178           break;
00179         }
00180       }
00181 
00182       // Compute the Q-equivalent bookings
00183       stdair::NbOfBookings_T lNbOfHistoricalBkgs = 0.0;
00184       const stdair::BookingClassList_T& lBCList =
00185         stdair::BomManager::getList<stdair::BookingClass> (iSegmentCabin);
00186       for (short j = 0; j < lNbOfDTDs; ++j) {
00187         stdair::BookingClass* lLowestBC_ptr = NULL;
00188         stdair::NbOfBookings_T lNbOfBksOfTheDay = 0.0;
00189         for (stdair::BookingClassList_T::const_iterator itBC = lBCList.begin();
00190              itBC != lBCList.end(); ++itBC) {
00191           stdair::BookingClass* lBC_ptr = *itBC;
00192           assert (lBC_ptr != NULL);
00193           
00194           // Retrieve the number of bookings
00195           const stdair::ClassIndex_T& lClassIdx =
00196             iSegmentSnapshotTable.getClassIndex(lBC_ptr->describeKey());
00197           const stdair::UnsignedIndex_T lIdx = i*lNbOfClasses + lClassIdx;
00198           const stdair::NbOfBookings_T lNbOfBookings =
00199             lPriceBookingView[lIdx][j] + lProductBookingView[lIdx][j];
00200           lNbOfBksOfTheDay += lNbOfBookings;
00201 
00202           if (lAvlView[lIdx][j] >= 1.0) {
00203             lLowestBC_ptr = lBC_ptr;
00204           }
00205         }
00206 
00207         // Convert the number of bookings of the day to Q-equivalent
00208         // bookings using the sell-up probability of the lowest class
00209         // available of the day.
00210         if (lLowestBC_ptr != NULL) {
00211           stdair::BookingClassSellUpCurveMap_T::const_iterator itBCSUC =
00212              iBCSellUpCurveMap.find (lLowestBC_ptr);
00213           assert (itBCSUC != iBCSellUpCurveMap.end());
00214           const stdair::SellUpCurve_T& lSellUpCurve = itBCSUC->second;
00215           stdair::SellUpCurve_T::const_iterator itSellUp =
00216             lSellUpCurve.find (iDCPBegin);
00217           assert (itSellUp != lSellUpCurve.end());
00218           const stdair::SellupProbability_T& lSellUp = itSellUp->second;
00219           assert (lSellUp != 0);
00220           
00221           lNbOfHistoricalBkgs += lNbOfBksOfTheDay/lSellUp;          
00222         }
00223       }
00224       
00225       HistoricalBooking lHistoricalBkg (lNbOfHistoricalBkgs, lCensorshipFlag);
00226       ioHBHolder.addHistoricalBooking (lHistoricalBkg);
00227     }
00228   }
00229 
00230   // ////////////////////////////////////////////////////////////////////
00231   void OldQFF::
00232   dispatchDemandForecastToPolicies (const stdair::PolicyList_T& iPolicyList,
00233                                     const stdair::DCP_T& iCurrentDCP,
00234                                     const stdair::MeanValue_T& iMean,
00235                                     const stdair::StdDevValue_T& iStdDev,
00236                                     const stdair::BookingClassSellUpCurveMap_T& iBCSellUpCurveMap) {
00237     for (stdair::PolicyList_T::const_iterator itPolicy = iPolicyList.begin();
00238          itPolicy != iPolicyList.end(); ++itPolicy) {
00239       stdair::Policy* lPolicy_ptr = *itPolicy;
00240       assert (lPolicy_ptr != NULL);
00241       dispatchDemandForecastToPolicy (*lPolicy_ptr,
00242                                       iCurrentDCP,
00243                                       iMean,
00244                                       iStdDev,
00245                                       iBCSellUpCurveMap);
00246     }
00247   }
00248  
00249   // ////////////////////////////////////////////////////////////////////
00250   void OldQFF::
00251   dispatchDemandForecastToPolicy (stdair::Policy& ioPolicy,
00252                                   const stdair::DCP_T& iCurrentDCP,
00253                                   const stdair::MeanValue_T& iMean,
00254                                   const stdair::StdDevValue_T& iStdDev,
00255                                   const stdair::BookingClassSellUpCurveMap_T& iBCSellUpCurveMap) {
00256     const stdair::MeanValue_T& lPolicyDemand = ioPolicy.getDemand();
00257     const stdair::StdDevValue_T& lPolicyStdDev = ioPolicy.getStdDev();
00258 
00259     // Browse the list of booking classes of the policy and use the
00260     // cumulative price-oriented demand forecast of each class.
00261     const bool hasAListOfBC = 
00262       stdair::BomManager::hasList<stdair::BookingClass> (ioPolicy);
00263     if (hasAListOfBC == true) { 
00264       const stdair::BookingClassList_T& lBCList =
00265         stdair::BomManager::getList<stdair::BookingClass> (ioPolicy);
00266       stdair::BookingClassList_T::const_reverse_iterator itCurrentBC =
00267         lBCList.rbegin();
00268       assert(itCurrentBC != lBCList.rend());
00269       stdair::BookingClass* lLowestBC_ptr = *itCurrentBC;
00270       assert (lLowestBC_ptr != NULL);
00271       const stdair::Yield_T& lLowestBCYield = lLowestBC_ptr->getYield();
00272       // Retrieve the sell-up factor for the lowest class.
00273       stdair::BookingClassSellUpCurveMap_T::const_iterator itBCSU =
00274         iBCSellUpCurveMap.find (lLowestBC_ptr);
00275       assert (itBCSU != iBCSellUpCurveMap.end());
00276       const stdair::SellUpCurve_T& lSellUpCurve = itBCSU->second;
00277       stdair::SellUpCurve_T::const_iterator itSellUpFactor =
00278         lSellUpCurve.find (iCurrentDCP);
00279       assert (itSellUpFactor != lSellUpCurve.end());
00280       const stdair::SellupProbability_T& lSUToLowestClass = itSellUpFactor->second;
00281       
00282       const stdair::MeanValue_T lAdditinalPolicyDemandMean = 
00283         iMean * lSUToLowestClass;
00284       const stdair::StdDevValue_T lAdditinalPolicyDemandStdDev = 
00285         iStdDev * std::sqrt (lSUToLowestClass);
00286 
00287       const stdair::MeanValue_T lNewPolicyDemandMean = 
00288         lPolicyDemand + lAdditinalPolicyDemandMean;
00289       const stdair::StdDevValue_T lNewPolicyDemandStdDev = 
00290         std::sqrt (lPolicyStdDev*lPolicyStdDev
00291         + lAdditinalPolicyDemandStdDev * lAdditinalPolicyDemandStdDev);
00292       //
00293       ioPolicy.setDemand (lNewPolicyDemandMean);
00294       ioPolicy.setStdDev (lNewPolicyDemandStdDev);
00295 
00296       ioPolicy.addYieldDemand (lLowestBCYield,
00297                                lAdditinalPolicyDemandMean);
00298 
00299       // Iterate other classes.
00300       stdair::BookingClassList_T::const_reverse_iterator itNextBC=itCurrentBC;
00301       ++itNextBC;
00302       for (; itNextBC != lBCList.rend(); ++itNextBC, ++itCurrentBC) {
00303         stdair::BookingClass* lCurrentBC_ptr = *itCurrentBC;
00304         assert (lCurrentBC_ptr != NULL);
00305         stdair::BookingClass* lNextBC_ptr = *itNextBC;
00306         assert (lNextBC_ptr != NULL);
00307 
00308         // Retrieve the disutility for the current policy to the next one.
00309         const stdair::FareFamily& lCurrentFF =
00310           stdair::BomManager::getParent<stdair::FareFamily> (*lCurrentBC_ptr);
00311         const stdair::FFDisutilityCurve_T& lDisutilityCurve =
00312           lCurrentFF.getDisutilityCurve();
00313         stdair::FFDisutilityCurve_T::const_iterator itDU =
00314           lDisutilityCurve.find (iCurrentDCP);
00315         assert (itDU != lDisutilityCurve.end());
00316         const double& lDU = itDU->second;
00317         
00318         // Retrieve the sell-up factor for the next class.
00319         stdair::BookingClassSellUpCurveMap_T::const_iterator itBCSUN =
00320           iBCSellUpCurveMap.find (lNextBC_ptr);
00321         assert (itBCSUN != iBCSellUpCurveMap.end());
00322         const stdair::SellUpCurve_T& lSellUpCurveN = itBCSUN->second;
00323         stdair::SellUpCurve_T::const_iterator itSellUpFactorN =
00324           lSellUpCurveN.find (iCurrentDCP);
00325         assert (itSellUpFactorN != lSellUpCurveN.end());
00326         const stdair::SellupProbability_T& lSUToNextClass = itSellUpFactorN->second;
00327         assert (lSUToNextClass > 0.0);
00328         assert(lSUToNextClass < lSUToLowestClass);
00329 
00330         // Retrieve the yields of the two classes
00331         const stdair::Yield_T& lCurrentYield = lCurrentBC_ptr->getYield();
00332         const stdair::Yield_T& lNextYield = lNextBC_ptr->getYield();
00333         const double lBuyUpFactor = exp ((lCurrentYield-lNextYield)*lDU);
00334 
00335         // Withdraw an amount demand forecast from the current class. This
00336         // amount of forecast will be added to the next class.
00337         const stdair::MeanValue_T lDemandForNextClass =
00338           iMean * lSUToNextClass * lBuyUpFactor;
00339         ioPolicy.addYieldDemand (lNextYield, lDemandForNextClass);
00340         ioPolicy.addYieldDemand (lCurrentYield, -lDemandForNextClass);
00341       }
00342     }
00343   }
00344 }