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

rmol/command/NewQFF.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/NewQFF.hpp>
00026 #include <rmol/command/Detruncator.hpp>
00027 
00028 namespace RMOL {
00029   // ////////////////////////////////////////////////////////////////////
00030   bool NewQFF::
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     // Browse the list of fare families and execute "Q-forecasting" within
00041     // each fare family.
00042     const stdair::FareFamilyList_T& lFFList =
00043       stdair::BomManager::getList<stdair::FareFamily>(ioSegmentCabin);
00044     for (stdair::FareFamilyList_T::const_iterator itFF = lFFList.begin();
00045          itFF != lFFList.end(); ++itFF) {
00046       stdair::FareFamily* lFF_ptr = *itFF;
00047       assert (lFF_ptr != NULL);
00048 
00049       forecast (*lFF_ptr,
00050                 iCurrentDate,
00051                 iCurrentDTD,
00052                 iUnconstrainingMethod,
00053                 iNbOfDepartedSegments,
00054                 lSegmentSnapshotTable);
00055     }
00056 
00057     // Dispatch the demand forecast to the policies.
00058     dispatchDemandForecastToPolicies (ioSegmentCabin);
00059 
00060     return true;
00061   }
00062 
00063   // ////////////////////////////////////////////////////////////////////
00064   void NewQFF::
00065   forecast (stdair::FareFamily& ioFareFamily,
00066             const stdair::Date_T& iCurrentDate,
00067             const stdair::DTD_T& iCurrentDTD,
00068             const stdair::UnconstrainingMethod& iUnconstrainingMethod,
00069             const stdair::NbOfSegments_T& iNbOfDepartedSegments,
00070             const stdair::SegmentSnapshotTable& iSegmentSnapshotTable) {
00071     // Retrieve the FRAT5Curve.
00072     const stdair::FRAT5Curve_T& lFRAT5Curve = ioFareFamily.getFrat5Curve();
00073 
00074     // Retrieve the booking class list and compute the sell up curves
00075     // and the dispatching curves.
00076     const stdair::BookingClassList_T& lBCList =
00077       stdair::BomManager::getList<stdair::BookingClass>(ioFareFamily);
00078     const stdair::BookingClassSellUpCurveMap_T lBCSellUpCurveMap =
00079       Utilities::computeSellUpFactorCurves (lFRAT5Curve, lBCList);
00080     const stdair::BookingClassDispatchingCurveMap_T lBCDispatchingCurveMap =
00081       Utilities::computeDispatchingFactorCurves (lFRAT5Curve, lBCList);
00082     
00083     // Browse all remaining DCP's and do unconstraining, forecasting
00084     // and dispatching.
00085     const stdair::DCPList_T lWholeDCPList = stdair::DEFAULT_DCP_LIST;
00086     stdair::DCPList_T::const_iterator itDCP = lWholeDCPList.begin();
00087     stdair::DCPList_T::const_iterator itNextDCP = itDCP; ++itNextDCP;
00088     for (; itNextDCP != lWholeDCPList.end(); ++itDCP, ++itNextDCP) {
00089       const stdair::DCP_T& lCurrentDCP = *itDCP;
00090       const stdair::DCP_T& lNextDCP = *itNextDCP;
00091 
00092       // The end of the interval is after the current DTD.
00093       if (lNextDCP < iCurrentDTD) {
00094         // Get the number of similar segments which has already passed the
00095         // (lNextDCP+1)
00096         const stdair::NbOfSegments_T& lNbOfUsableSegments =
00097           SegmentSnapshotTableHelper::
00098           getNbOfSegmentAlreadyPassedThisDTD (iSegmentSnapshotTable,
00099                                               lNextDCP+1,
00100                                               iCurrentDate);
00101         stdair::NbOfSegments_T lSegmentBegin = 0;
00102         const stdair::NbOfSegments_T lSegmentEnd = lNbOfUsableSegments-1;
00103         if (iNbOfDepartedSegments > 52) {
00104           lSegmentBegin = iNbOfDepartedSegments - 52;
00105         }
00106       
00107         // Retrieve the historical bookings and convert them to
00108         // Q-equivalent bookings.
00109         HistoricalBookingHolder lHBHolder;
00110         preparePriceOrientedHistoricalBooking (ioFareFamily,
00111                                                iSegmentSnapshotTable,
00112                                                lHBHolder,
00113                                                lCurrentDCP, lNextDCP,
00114                                                lSegmentBegin, lSegmentEnd,
00115                                                lBCSellUpCurveMap);
00116 
00117         // Unconstrain the historical bookings.
00118         Detruncator::unconstrain (lHBHolder, iUnconstrainingMethod);
00119 
00120         // Retrieve the historical unconstrained demand and perform the
00121         // forecasting.
00122         stdair::UncDemVector_T lUncDemVector;
00123         // Be careful, the getter returns the vector size,
00124         // so there is no reference.
00125         const short lNbOfHistoricalFlights = lHBHolder.getNbOfFlights();
00126         for (short i = 0; i < lNbOfHistoricalFlights; ++i) {
00127           const stdair::NbOfBookings_T& lUncDemand =
00128             lHBHolder.getUnconstrainedDemand (i);
00129           lUncDemVector.push_back (lUncDemand);
00130         }
00131         stdair::MeanValue_T lMean = 0.0;
00132         stdair::StdDevValue_T lStdDev = 0.0;
00133         Utilities::computeDistributionParameters (lUncDemVector,
00134                                                   lMean, lStdDev);
00135 
00136         // Dispatch the forecast to all the classes.
00137         Utilities::dispatchDemandForecast (lBCDispatchingCurveMap,
00138                                            lMean, lStdDev, lCurrentDCP);
00139 
00140         // Dispatch the forecast to all classes for Fare Adjustment or MRT.
00141         // The sell-up probability will be used in this case.
00142         Utilities::dispatchDemandForecastForFA (lBCSellUpCurveMap,
00143                                                 lMean, lStdDev, lCurrentDCP);
00144 
00145         // Add the demand forecast to the fare family.
00146         const stdair::MeanValue_T& lCurrentMean = ioFareFamily.getMean();
00147         const stdair::StdDevValue_T& lCurrentStdDev = ioFareFamily.getStdDev();
00148 
00149         const stdair::MeanValue_T lNewMean = lCurrentMean + lMean;
00150         const stdair::StdDevValue_T lNewStdDev = 
00151           std::sqrt (lCurrentStdDev * lCurrentStdDev + lStdDev * lStdDev);
00152 
00153         ioFareFamily.setMean (lNewMean);
00154         ioFareFamily.setStdDev (lNewStdDev);
00155       }
00156     }
00157 
00158   }
00159   
00160   // ////////////////////////////////////////////////////////////////////
00161   void NewQFF::preparePriceOrientedHistoricalBooking
00162     (const stdair::FareFamily& iFareFamily,
00163      const stdair::SegmentSnapshotTable& iSegmentSnapshotTable,
00164      HistoricalBookingHolder& ioHBHolder,
00165      const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
00166      const stdair::NbOfSegments_T& iSegmentBegin,
00167      const stdair::NbOfSegments_T& iSegmentEnd,
00168      const stdair::BookingClassSellUpCurveMap_T& iBCSellUpCurveMap) {
00169 
00170     // Retrieve the gross daily booking and availability snapshots.
00171     const stdair::ConstSegmentCabinDTDRangeSnapshotView_T lPriceBookingView =
00172       iSegmentSnapshotTable.getConstSegmentCabinDTDRangePriceOrientedGrossBookingSnapshotView (iSegmentBegin, iSegmentEnd, iDCPEnd, iDCPBegin);
00173     const stdair::ConstSegmentCabinDTDRangeSnapshotView_T lProductBookingView =
00174       iSegmentSnapshotTable.getConstSegmentCabinDTDRangeProductOrientedGrossBookingSnapshotView (iSegmentBegin, iSegmentEnd, iDCPEnd, iDCPBegin);
00175     const stdair::ConstSegmentCabinDTDRangeSnapshotView_T lAvlView =
00176       iSegmentSnapshotTable.getConstSegmentCabinDTDRangeAvailabilitySnapshotView (iSegmentBegin, iSegmentEnd, iDCPEnd, iDCPBegin);
00177     
00178     // Browse the list of segments and build the historical booking holder.
00179     const stdair::ClassIndexMap_T& lVTIdxMap =
00180       iSegmentSnapshotTable.getClassIndexMap();
00181     const stdair::NbOfClasses_T lNbOfClasses = lVTIdxMap.size();
00182     
00183     for (short i = 0; i <= iSegmentEnd-iSegmentBegin; ++i) {
00184       stdair::Flag_T lCensorshipFlag = false;
00185       const short lNbOfDTDs = iDCPBegin - iDCPEnd + 1;
00186       
00187       // Parse the DTDs during the period and compute the censorship flag
00188       for (short j = 0; j < lNbOfDTDs; ++j) {
00189         // Check if the data has been censored during this day.
00190         // STDAIR_LOG_DEBUG ("i: " << i << ", NbOfClasses: " << lNbOfClasses
00191         //                   << ", ClassIdx: " << iClassIdx << ", j: " << j);
00192         bool tempCensorship = true;
00193         for (stdair::BookingClassSellUpCurveMap_T::const_iterator itBCSUC =
00194              iBCSellUpCurveMap.begin();
00195            itBCSUC != iBCSellUpCurveMap.end(); ++itBCSUC) {
00196           const stdair::BookingClass* lBookingClass_ptr = itBCSUC->first;
00197           assert (lBookingClass_ptr != NULL);
00198           const stdair::ClassIndex_T& lClassIdx =
00199             iSegmentSnapshotTable.getClassIndex(lBookingClass_ptr->describeKey());
00200           const stdair::UnsignedIndex_T lAvlIdx = i*lNbOfClasses + lClassIdx;
00201           if (lAvlView[lAvlIdx][j] >= 1.0) {
00202             tempCensorship = false;
00203             break;
00204           }
00205         }
00206         if (tempCensorship == true) {
00207           lCensorshipFlag = true;
00208           break;
00209         }
00210       }
00211 
00212       // Compute the Q-equivalent bookings
00213       stdair::NbOfBookings_T lNbOfHistoricalBkgs = 0.0;
00214       for (stdair::BookingClassSellUpCurveMap_T::const_iterator itBCSUC =
00215              iBCSellUpCurveMap.begin();
00216            itBCSUC != iBCSellUpCurveMap.end(); ++itBCSUC) {
00217         const stdair::BookingClass* lBookingClass_ptr = itBCSUC->first;
00218         assert (lBookingClass_ptr != NULL);
00219         const stdair::SellUpCurve_T& lSellUpCurve = itBCSUC->second;
00220         stdair::SellUpCurve_T::const_iterator itSellUp =
00221           lSellUpCurve.find (iDCPBegin);
00222         assert (itSellUp != lSellUpCurve.end());
00223         const stdair::SellupProbability_T& lSellUp = itSellUp->second;
00224         assert (lSellUp != 0);
00225 
00226         // Retrieve the number of bookings
00227         const stdair::ClassIndex_T& lClassIdx =
00228           iSegmentSnapshotTable.getClassIndex(lBookingClass_ptr->describeKey());
00229         const stdair::UnsignedIndex_T lIdx = i*lNbOfClasses + lClassIdx;
00230 
00231         stdair::NbOfBookings_T lNbOfBookings = 0.0;
00232         for (short j = 0; j < lNbOfDTDs; ++j) {
00233           lNbOfBookings += 
00234             lPriceBookingView[lIdx][j] + lProductBookingView[lIdx][j];
00235         }
00236         const stdair::NbOfBookings_T lNbOfQEquivalentBkgs=lNbOfBookings/lSellUp;
00237 
00238         lNbOfHistoricalBkgs += lNbOfQEquivalentBkgs;
00239       }
00240 
00241       HistoricalBooking lHistoricalBkg (lNbOfHistoricalBkgs, lCensorshipFlag);
00242       ioHBHolder.addHistoricalBooking (lHistoricalBkg);
00243     }
00244   }
00245 
00246   // ////////////////////////////////////////////////////////////////////
00247   void NewQFF::
00248   dispatchDemandForecastToPolicies (const stdair::SegmentCabin& iSegmentCabin){
00249     // Retrieve the list of policies.
00250     const stdair::PolicyList_T& lPolicyList =
00251       stdair::BomManager::getList<stdair::Policy> (iSegmentCabin);
00252 
00253     for (stdair::PolicyList_T::const_iterator itPolicy = lPolicyList.begin();
00254          itPolicy != lPolicyList.end(); ++itPolicy) {
00255       stdair::Policy* lPolicy_ptr = *itPolicy;
00256       assert (lPolicy_ptr != NULL);
00257       dispatchDemandForecastToPolicy(*lPolicy_ptr);
00258     }
00259   }
00260 
00261   // ////////////////////////////////////////////////////////////////////
00262   void NewQFF::
00263   dispatchDemandForecastToPolicy (stdair::Policy& ioPolicy){
00264     // Reset the demand forecast of the policy
00265     ioPolicy.resetDemandForecast();
00266 
00267     const stdair::MeanValue_T& lPolicyDemand = ioPolicy.getDemand();
00268     const stdair::StdDevValue_T& lPolicyStdDev = ioPolicy.getStdDev();
00269     stdair::MeanValue_T lNewPolicyDemand = lPolicyDemand;
00270     stdair::MeanValue_T lNewPolicyStdDev = lPolicyStdDev;
00271 
00272     // Browse the list of booking classes of the policy and use the
00273     // cumulative price-oriented demand forecast of each class.
00274     const bool hasAListOfBC = 
00275       stdair::BomManager::hasList<stdair::BookingClass> (ioPolicy);
00276     if (hasAListOfBC == true) { 
00277       const stdair::BookingClassList_T& lBCList =
00278         stdair::BomManager::getList<stdair::BookingClass> (ioPolicy);
00279       for (stdair::BookingClassList_T::const_iterator itBC = lBCList.begin();
00280            itBC != lBCList.end(); ++itBC) {
00281         const stdair::BookingClass* lBC_ptr = *itBC;
00282         assert (lBC_ptr != NULL);
00283         const stdair::Yield_T& lYield = lBC_ptr->getYield();
00284         const stdair::MeanValue_T& lDemand = lBC_ptr->getCumuPriceDemMean();
00285         const stdair::StdDevValue_T& lStdDev = 
00286           lBC_ptr->getCumuPriceDemStdDev();
00287 
00288         ioPolicy.addYieldDemand (lYield, lDemand);
00289         lNewPolicyDemand += lDemand;
00290         const stdair::StdDevValue_T lSquareNewPolicyStdDev =
00291           lNewPolicyStdDev*lNewPolicyStdDev + lStdDev*lStdDev;
00292         lNewPolicyStdDev = 
00293           std::sqrt (lSquareNewPolicyStdDev);
00294       }
00295       ioPolicy.setDemand(lNewPolicyDemand);
00296       ioPolicy.setStdDev(lNewPolicyStdDev);
00297     }
00298   }
00299 }