RMOL Logo  1.00.0
C++ library of Revenue Management and Optimisation classes and functions
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
Forecaster.cpp
Go to the documentation of this file.
1 // //////////////////////////////////////////////////////////////////////
2 // Import section
3 // //////////////////////////////////////////////////////////////////////
4 // STL
5 #include <cassert>
6 #include <sstream>
7 #include <cmath>
8 // StdAir
9 #include <stdair/basic/BasConst_General.hpp>
10 #include <stdair/basic/BasConst_Inventory.hpp>
11 #include <stdair/bom/BomManager.hpp>
12 #include <stdair/bom/FlightDate.hpp>
13 #include <stdair/bom/SegmentDate.hpp>
14 #include <stdair/bom/SegmentCabin.hpp>
15 #include <stdair/bom/SegmentSnapshotTable.hpp>
16 #include <stdair/bom/FareFamily.hpp>
17 #include <stdair/bom/BookingClass.hpp>
18 #include <stdair/service/Logger.hpp>
19 // RMOL
20 #include <rmol/bom/Utilities.hpp>
28 #include <rmol/command/OldQFF.hpp>
29 #include <rmol/command/NewQFF.hpp>
30 
31 namespace RMOL {
32 
33  // ////////////////////////////////////////////////////////////////////
34  bool Forecaster::
35  forecast (stdair::FlightDate& ioFlightDate,
36  const stdair::DateTime_T& iEventTime,
37  const stdair::UnconstrainingMethod& iUnconstrainingMethod,
38  const stdair::ForecastingMethod& iForecastingMethod) {
39  // Build the offset dates.
40  const stdair::Date_T& lEventDate = iEventTime.date();
41 
42  //
43  bool isSucceeded = true;
44  const stdair::SegmentDateList_T& lSDList =
45  stdair::BomManager::getList<stdair::SegmentDate> (ioFlightDate);
46  for (stdair::SegmentDateList_T::const_iterator itSD = lSDList.begin();
47  itSD != lSDList.end(); ++itSD) {
48  stdair::SegmentDate* lSD_ptr = *itSD;
49  assert (lSD_ptr != NULL);
50 
51  // TODO: Take into account the case where the segment departure date
52  // is not the same as the flight departure date.
53  // const stdair::Date_T& lBoardingDate = lSD_ptr->getBoardingDate();
54  // const stdair::DateOffset_T lSegmentDateOffset =
55  // lBoardingDate - lEventDate;
56  // const stdair::DTD_T lSegmentDTD = lSegmentDateOffset.days();
57 
58  //
59  const stdair::SegmentCabinList_T& lSCList =
60  stdair::BomManager::getList<stdair::SegmentCabin> (*lSD_ptr);
61  for (stdair::SegmentCabinList_T::const_iterator itSC = lSCList.begin();
62  itSC != lSCList.end(); ++itSC) {
63  stdair::SegmentCabin* lSC_ptr = *itSC;
64  assert (lSC_ptr != NULL);
65 
66  //
67  // STDAIR_LOG_NOTIFICATION (ioFlightDate.getDepartureDate()
68  // << ";" << lSegmentDTD);
69  bool isForecasted = forecast (*lSC_ptr, lEventDate,
70  iUnconstrainingMethod,
71  iForecastingMethod);
72  if (isForecasted == false) {
73  isSucceeded = false;
74  }
75  }
76  }
77 
78  return isSucceeded;
79  }
80 
81  // ////////////////////////////////////////////////////////////////////
82  bool Forecaster::
83  forecast (stdair::SegmentCabin& ioSegmentCabin,
84  const stdair::Date_T& iEventDate,
85  const stdair::UnconstrainingMethod& iUnconstrainingMethod,
86  const stdair::ForecastingMethod& iForecastingMethod) {
87  // Retrieve the number of departed similar segments.
88  stdair::NbOfSegments_T lNbOfDepartedSegments =
89  Utilities::getNbOfDepartedSimilarSegments (ioSegmentCabin, iEventDate);
90 
91  // DEBUG
92  // STDAIR_LOG_DEBUG ("Nb of similar departed segments: "
93  // << lNbOfDepartedSegments);
94 
95  // If the number of departed segments are less than two, there
96  // will be no forecast, and thus no optimisation.
97  if (lNbOfDepartedSegments < 2) {
98  return false;
99  } else {
100  setDemandForecastsToZero (ioSegmentCabin);
101  const stdair::SegmentDate& lSegmentDate =
102  stdair::BomManager::getParent<stdair::SegmentDate> (ioSegmentCabin);
103  const stdair::Date_T& lBoardingDate = lSegmentDate.getBoardingDate();
104  const stdair::DateOffset_T lDateOffset = lBoardingDate - iEventDate;
105  const stdair::DTD_T& lDaysBeforeDeparture = lDateOffset.days();
106 
107  // If the forecasting method is QFF (old or new), but there are
108  // not more than two fare families in the cabin, hybrid
109  // forecasting will be used.
110  const stdair::ForecastingMethod::EN_ForecastingMethod lForecastingMethod =
111  iForecastingMethod.getMethod();
112  switch (lForecastingMethod) {
113  case stdair::ForecastingMethod::Q_FORECASTING: {
114  return QForecasting::forecast (ioSegmentCabin, iEventDate,
115  lDaysBeforeDeparture,
116  iUnconstrainingMethod,
117  lNbOfDepartedSegments);
118  }
119  case stdair::ForecastingMethod::HYBRID_FORECASTING: {
120  return HybridForecasting::forecast (ioSegmentCabin, iEventDate,
121  lDaysBeforeDeparture,
122  iUnconstrainingMethod,
123  lNbOfDepartedSegments);
124  }
125  case stdair::ForecastingMethod::NEW_QFF: {
126  if (ioSegmentCabin.getFareFamilyStatus()==false) {
127 
128  return HybridForecasting::forecast (ioSegmentCabin, iEventDate,
129  lDaysBeforeDeparture,
130  iUnconstrainingMethod,
131  lNbOfDepartedSegments);
132  } else {
133  return NewQFF::forecast (ioSegmentCabin, iEventDate,
134  lDaysBeforeDeparture, iUnconstrainingMethod,
135  lNbOfDepartedSegments);
136  }
137  }
138  case stdair::ForecastingMethod::OLD_QFF: {
139  if (ioSegmentCabin.getFareFamilyStatus()==false) {
140 
141  return HybridForecasting::forecast (ioSegmentCabin, iEventDate,
142  lDaysBeforeDeparture,
143  iUnconstrainingMethod,
144  lNbOfDepartedSegments);
145  } else {
146  return OldQFF::forecast (ioSegmentCabin, iEventDate,
147  lDaysBeforeDeparture, iUnconstrainingMethod,
148  lNbOfDepartedSegments);
149  }
150  }
151  case stdair::ForecastingMethod::BASED_FORECASTING: {
152  return BasedForecasting::forecast (ioSegmentCabin, iEventDate,
153  lDaysBeforeDeparture,
154  iUnconstrainingMethod,
155  lNbOfDepartedSegments);
156  }
157  default:{
158  assert (false);
159  break;
160  }
161  }
162  return false;
163  }
164  }
165 
166  // ////////////////////////////////////////////////////////////////////
167  void Forecaster::
168  setDemandForecastsToZero(const stdair::SegmentCabin& iSegmentCabin) {
169  // Set the demand forecast for all classes and fare families to zero.
170  const stdair::FareFamilyList_T& lFFList =
171  stdair::BomManager::getList<stdair::FareFamily> (iSegmentCabin);
172  for (stdair::FareFamilyList_T::const_iterator itFF = lFFList.begin();
173  itFF != lFFList.end(); ++itFF) {
174  stdair::FareFamily* lFF_ptr = *itFF;
175  assert (lFF_ptr != NULL);
176  lFF_ptr->setMean (0.0);
177  lFF_ptr->setStdDev (0.0);
178 
179  const stdair::BookingClassList_T& lBCList =
180  stdair::BomManager::getList<stdair::BookingClass> (*lFF_ptr);
181  for (stdair::BookingClassList_T::const_iterator itBC = lBCList.begin();
182  itBC != lBCList.end(); ++itBC) {
183  stdair::BookingClass* lBC_ptr = *itBC;
184  assert (lBC_ptr != NULL);
185  lBC_ptr->setMean (0.0);
186  lBC_ptr->setStdDev (0.0);
187  lBC_ptr->setPriceDemMean (0.0);
188  lBC_ptr->setPriceDemStdDev (0.0);
189  lBC_ptr->setProductDemMean (0.0);
190  lBC_ptr->setProductDemStdDev (0.0);
191  lBC_ptr->setCumuPriceDemMean (0.0);
192  lBC_ptr->setCumuPriceDemStdDev (0.0);
193  }
194  }
195  }
196 }