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

rmol/command/Forecaster.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/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 }