$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/FlightDate.hpp> 00013 #include <stdair/bom/SegmentDate.hpp> 00014 #include <stdair/bom/SegmentCabin.hpp> 00015 #include <stdair/bom/SegmentSnapshotTable.hpp> 00016 #include <stdair/bom/FareFamily.hpp> 00017 #include <stdair/bom/BookingClass.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/command/BasedForecasting.hpp> 00025 #include <rmol/command/Forecaster.hpp> 00026 #include <rmol/command/QForecasting.hpp> 00027 #include <rmol/command/HybridForecasting.hpp> 00028 #include <rmol/command/OldQFF.hpp> 00029 #include <rmol/command/NewQFF.hpp> 00030 00031 namespace RMOL { 00032 00033 // //////////////////////////////////////////////////////////////////// 00034 bool Forecaster:: 00035 forecast (stdair::FlightDate& ioFlightDate, 00036 const stdair::DateTime_T& iEventTime, 00037 const stdair::UnconstrainingMethod& iUnconstrainingMethod, 00038 const stdair::ForecastingMethod& iForecastingMethod) { 00039 // Build the offset dates. 00040 const stdair::Date_T& lEventDate = iEventTime.date(); 00041 00042 // 00043 bool isSucceeded = true; 00044 const stdair::SegmentDateList_T& lSDList = 00045 stdair::BomManager::getList<stdair::SegmentDate> (ioFlightDate); 00046 for (stdair::SegmentDateList_T::const_iterator itSD = lSDList.begin(); 00047 itSD != lSDList.end(); ++itSD) { 00048 stdair::SegmentDate* lSD_ptr = *itSD; 00049 assert (lSD_ptr != NULL); 00050 00051 // TODO: Take into account the case where the segment departure date 00052 // is not the same as the flight departure date. 00053 // const stdair::Date_T& lBoardingDate = lSD_ptr->getBoardingDate(); 00054 // const stdair::DateOffset_T lSegmentDateOffset = 00055 // lBoardingDate - lEventDate; 00056 // const stdair::DTD_T lSegmentDTD = lSegmentDateOffset.days(); 00057 00058 // 00059 const stdair::SegmentCabinList_T& lSCList = 00060 stdair::BomManager::getList<stdair::SegmentCabin> (*lSD_ptr); 00061 for (stdair::SegmentCabinList_T::const_iterator itSC = lSCList.begin(); 00062 itSC != lSCList.end(); ++itSC) { 00063 stdair::SegmentCabin* lSC_ptr = *itSC; 00064 assert (lSC_ptr != NULL); 00065 00066 // 00067 // STDAIR_LOG_NOTIFICATION (ioFlightDate.getDepartureDate() 00068 // << ";" << lSegmentDTD); 00069 bool isForecasted = forecast (*lSC_ptr, lEventDate, 00070 iUnconstrainingMethod, 00071 iForecastingMethod); 00072 if (isForecasted == false) { 00073 isSucceeded = false; 00074 } 00075 } 00076 } 00077 00078 return isSucceeded; 00079 } 00080 00081 // //////////////////////////////////////////////////////////////////// 00082 bool Forecaster:: 00083 forecast (stdair::SegmentCabin& ioSegmentCabin, 00084 const stdair::Date_T& iEventDate, 00085 const stdair::UnconstrainingMethod& iUnconstrainingMethod, 00086 const stdair::ForecastingMethod& iForecastingMethod) { 00087 // Retrieve the number of departed similar segments. 00088 stdair::NbOfSegments_T lNbOfDepartedSegments = 00089 Utilities::getNbOfDepartedSimilarSegments (ioSegmentCabin, iEventDate); 00090 00091 // DEBUG 00092 // STDAIR_LOG_DEBUG ("Nb of similar departed segments: " 00093 // << lNbOfDepartedSegments); 00094 00095 // If the number of departed segments are less than two, there 00096 // will be no forecast, and thus no optimisation. 00097 if (lNbOfDepartedSegments < 2) { 00098 return false; 00099 } else { 00100 setDemandForecastsToZero (ioSegmentCabin); 00101 const stdair::SegmentDate& lSegmentDate = 00102 stdair::BomManager::getParent<stdair::SegmentDate> (ioSegmentCabin); 00103 const stdair::Date_T& lBoardingDate = lSegmentDate.getBoardingDate(); 00104 const stdair::DateOffset_T lDateOffset = lBoardingDate - iEventDate; 00105 const stdair::DTD_T& lDaysBeforeDeparture = lDateOffset.days(); 00106 00107 // If the forecasting method is QFF (old or new), but there are 00108 // not more than two fare families in the cabin, hybrid 00109 // forecasting will be used. 00110 const stdair::ForecastingMethod::EN_ForecastingMethod lForecastingMethod = 00111 iForecastingMethod.getMethod(); 00112 switch (lForecastingMethod) { 00113 case stdair::ForecastingMethod::Q_FORECASTING: { 00114 return QForecasting::forecast (ioSegmentCabin, iEventDate, 00115 lDaysBeforeDeparture, 00116 iUnconstrainingMethod, 00117 lNbOfDepartedSegments); 00118 } 00119 case stdair::ForecastingMethod::HYBRID_FORECASTING: { 00120 return HybridForecasting::forecast (ioSegmentCabin, iEventDate, 00121 lDaysBeforeDeparture, 00122 iUnconstrainingMethod, 00123 lNbOfDepartedSegments); 00124 } 00125 case stdair::ForecastingMethod::NEW_QFF: { 00126 if (ioSegmentCabin.getFareFamilyStatus()==false) { 00127 00128 return HybridForecasting::forecast (ioSegmentCabin, iEventDate, 00129 lDaysBeforeDeparture, 00130 iUnconstrainingMethod, 00131 lNbOfDepartedSegments); 00132 } else { 00133 return NewQFF::forecast (ioSegmentCabin, iEventDate, 00134 lDaysBeforeDeparture, iUnconstrainingMethod, 00135 lNbOfDepartedSegments); 00136 } 00137 } 00138 case stdair::ForecastingMethod::OLD_QFF: { 00139 if (ioSegmentCabin.getFareFamilyStatus()==false) { 00140 00141 return HybridForecasting::forecast (ioSegmentCabin, iEventDate, 00142 lDaysBeforeDeparture, 00143 iUnconstrainingMethod, 00144 lNbOfDepartedSegments); 00145 } else { 00146 return OldQFF::forecast (ioSegmentCabin, iEventDate, 00147 lDaysBeforeDeparture, iUnconstrainingMethod, 00148 lNbOfDepartedSegments); 00149 } 00150 } 00151 case stdair::ForecastingMethod::BASED_FORECASTING: { 00152 return BasedForecasting::forecast (ioSegmentCabin, iEventDate, 00153 lDaysBeforeDeparture, 00154 iUnconstrainingMethod, 00155 lNbOfDepartedSegments); 00156 } 00157 default:{ 00158 assert (false); 00159 break; 00160 } 00161 } 00162 return false; 00163 } 00164 } 00165 00166 // //////////////////////////////////////////////////////////////////// 00167 void Forecaster:: 00168 setDemandForecastsToZero(const stdair::SegmentCabin& iSegmentCabin) { 00169 // Set the demand forecast for all classes and fare families to zero. 00170 const stdair::FareFamilyList_T& lFFList = 00171 stdair::BomManager::getList<stdair::FareFamily> (iSegmentCabin); 00172 for (stdair::FareFamilyList_T::const_iterator itFF = lFFList.begin(); 00173 itFF != lFFList.end(); ++itFF) { 00174 stdair::FareFamily* lFF_ptr = *itFF; 00175 assert (lFF_ptr != NULL); 00176 lFF_ptr->setMean (0.0); 00177 lFF_ptr->setStdDev (0.0); 00178 00179 const stdair::BookingClassList_T& lBCList = 00180 stdair::BomManager::getList<stdair::BookingClass> (*lFF_ptr); 00181 for (stdair::BookingClassList_T::const_iterator itBC = lBCList.begin(); 00182 itBC != lBCList.end(); ++itBC) { 00183 stdair::BookingClass* lBC_ptr = *itBC; 00184 assert (lBC_ptr != NULL); 00185 lBC_ptr->setMean (0.0); 00186 lBC_ptr->setStdDev (0.0); 00187 lBC_ptr->setPriceDemMean (0.0); 00188 lBC_ptr->setPriceDemStdDev (0.0); 00189 lBC_ptr->setProductDemMean (0.0); 00190 lBC_ptr->setProductDemStdDev (0.0); 00191 lBC_ptr->setCumuPriceDemMean (0.0); 00192 lBC_ptr->setCumuPriceDemStdDev (0.0); 00193 } 00194 } 00195 } 00196 }