$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/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 }