$treeview $search $mathjax
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 }