RMOL Logo  1.00.0
C++ library of Revenue Management and Optimisation classes and functions
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
QForecasting.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/LegDate.hpp>
13 #include <stdair/bom/SegmentDate.hpp>
14 #include <stdair/bom/LegCabin.hpp>
15 #include <stdair/bom/SegmentCabin.hpp>
16 #include <stdair/bom/SegmentSnapshotTable.hpp>
17 #include <stdair/bom/FareFamily.hpp>
18 #include <stdair/bom/BookingClass.hpp>
19 #include <stdair/service/Logger.hpp>
20 // RMOL
21 #include <rmol/bom/Utilities.hpp>
27 
28 namespace RMOL {
29  // ////////////////////////////////////////////////////////////////////
30  bool QForecasting::
31  forecast (stdair::SegmentCabin& ioSegmentCabin,
32  const stdair::Date_T& iCurrentDate,
33  const stdair::DTD_T& iCurrentDTD,
34  const stdair::UnconstrainingMethod& iUnconstrainingMethod,
35  const stdair::NbOfSegments_T& iNbOfDepartedSegments) {
36  // Retrieve the snapshot table.
37  const stdair::SegmentSnapshotTable& lSegmentSnapshotTable =
38  ioSegmentCabin.getSegmentSnapshotTable();
39 
40  // Retrieve the FRAT5Curve.
41  const stdair::FareFamilyList_T& lFFList =
42  stdair::BomManager::getList<stdair::FareFamily>(ioSegmentCabin);
43  stdair::FareFamilyList_T::const_reverse_iterator itFF = lFFList.rbegin();
44  assert (itFF != lFFList.rend());
45  stdair::FareFamily* lFF_ptr = *itFF;
46  assert (lFF_ptr != NULL);
47  const stdair::FRAT5Curve_T lFRAT5Curve = lFF_ptr->getFrat5Curve();
48 
49  // Retrieve the booking class list and compute the sell up curves
50  // and the dispatching curves.
51  const stdair::BookingClassList_T& lBCList =
52  stdair::BomManager::getList<stdair::BookingClass>(ioSegmentCabin);
53  const stdair::BookingClassSellUpCurveMap_T lBCSellUpCurveMap =
54  Utilities::computeSellUpFactorCurves (lFRAT5Curve, lBCList);
55  const stdair::BookingClassDispatchingCurveMap_T lBCDispatchingCurveMap =
56  Utilities::computeDispatchingFactorCurves (lFRAT5Curve, lBCList);
57 
58 
59  // Browse all remaining DCP's and do unconstraining, forecasting
60  // and dispatching.
61  const stdair::DCPList_T lWholeDCPList = stdair::DEFAULT_DCP_LIST;
62  stdair::DCPList_T::const_iterator itDCP = lWholeDCPList.begin();
63  stdair::DCPList_T::const_iterator itNextDCP = itDCP; ++itNextDCP;
64  for (; itNextDCP != lWholeDCPList.end(); ++itDCP, ++itNextDCP) {
65  const stdair::DCP_T& lCurrentDCP = *itDCP;
66  const stdair::DCP_T& lNextDCP = *itNextDCP;
67 
68  // The end of the interval is after the current DTD.
69  if (lNextDCP < iCurrentDTD) {
70  // Get the number of similar segments which has already passed the
71  // (lNextDCP+1)
72  const stdair::NbOfSegments_T& lNbOfUsableSegments =
74  getNbOfSegmentAlreadyPassedThisDTD (lSegmentSnapshotTable,
75  lNextDCP+1,
76  iCurrentDate);
77  stdair::NbOfSegments_T lSegmentBegin = 0;
78  const stdair::NbOfSegments_T lSegmentEnd = lNbOfUsableSegments-1;
79  if (iNbOfDepartedSegments > 52) {
80  lSegmentBegin = iNbOfDepartedSegments - 52;
81  }
82 
83  // Retrieve the historical bookings and convert them to
84  // Q-equivalent bookings.
85  HistoricalBookingHolder lHBHolder;
87  lSegmentSnapshotTable, lHBHolder,
88  lCurrentDCP, lNextDCP,
89  lSegmentBegin, lSegmentEnd,
90  lBCSellUpCurveMap);
91 
92  // Unconstrain the historical bookings.
93  Detruncator::unconstrain (lHBHolder, iUnconstrainingMethod);
94 
95  // Retrieve the historical unconstrained demand and perform the
96  // forecasting.
97  stdair::UncDemVector_T lUncDemVector;
98  const short lNbOfHistoricalFlights = lHBHolder.getNbOfFlights();
99  for (short i = 0; i < lNbOfHistoricalFlights; ++i) {
100  const stdair::NbOfBookings_T& lUncDemand =
101  lHBHolder.getUnconstrainedDemand (i);
102  lUncDemVector.push_back (lUncDemand);
103  }
104  stdair::MeanValue_T lMean = 0.0;
105  stdair::StdDevValue_T lStdDev = 0.0;
107  lMean, lStdDev);
108 
109  // Dispatch the forecast to all the classes.
110  Utilities::dispatchDemandForecast (lBCDispatchingCurveMap,
111  lMean, lStdDev, lCurrentDCP);
112 
113  // Dispatch the forecast to all classes for Fare Adjustment or MRT.
114  // The sell-up probability will be used in this case.
115  Utilities::dispatchDemandForecastForFA (lBCDispatchingCurveMap,
116  lMean, lStdDev, lCurrentDCP);
117 
118  // Add the demand forecast to the fare family.
119  const stdair::MeanValue_T& lCurrentMean = lFF_ptr->getMean();
120  const stdair::StdDevValue_T& lCurrentStdDev = lFF_ptr->getStdDev();
121 
122  const stdair::MeanValue_T lNewMean = lCurrentMean + lMean;
123  const stdair::StdDevValue_T lNewStdDev =
124  std::sqrt (lCurrentStdDev * lCurrentStdDev + lStdDev * lStdDev);
125 
126  lFF_ptr->setMean (lNewMean);
127  lFF_ptr->setStdDev (lNewStdDev);
128  }
129  }
130 
131  return true;
132  }
133 
134  // ////////////////////////////////////////////////////////////////////
136  (const stdair::SegmentCabin& iSegmentCabin,
137  const stdair::SegmentSnapshotTable& iSegmentSnapshotTable,
138  HistoricalBookingHolder& ioHBHolder,
139  const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
140  const stdair::NbOfSegments_T& iSegmentBegin,
141  const stdair::NbOfSegments_T& iSegmentEnd,
142  const stdair::BookingClassSellUpCurveMap_T& iBCSellUpCurveMap) {
143 
144  // Retrieve the segment-cabin index within the snapshot table
145  std::ostringstream lSCMapKey;
146  lSCMapKey << stdair::DEFAULT_SEGMENT_CABIN_VALUE_TYPE
147  << iSegmentCabin.describeKey();
148  const stdair::ClassIndex_T& lCabinIdx =
149  iSegmentSnapshotTable.getClassIndex (lSCMapKey.str());
150 
151  // Retrieve the gross daily booking and availability snapshots.
152  const stdair::ConstSegmentCabinDTDRangeSnapshotView_T lBookingView =
153  iSegmentSnapshotTable.getConstSegmentCabinDTDRangePriceOrientedGrossBookingSnapshotView (iSegmentBegin, iSegmentEnd, iDCPEnd, iDCPBegin);
154  const stdair::ConstSegmentCabinDTDRangeSnapshotView_T lAvlView =
155  iSegmentSnapshotTable.getConstSegmentCabinDTDRangeAvailabilitySnapshotView (iSegmentBegin, iSegmentEnd, iDCPEnd, iDCPBegin);
156 
157  // Browse the list of segments and build the historical booking holder.
158  const stdair::ClassIndexMap_T& lVTIdxMap =
159  iSegmentSnapshotTable.getClassIndexMap();
160  const stdair::NbOfClasses_T lNbOfClasses = lVTIdxMap.size();
161 
162  for (short i = 0; i <= iSegmentEnd-iSegmentBegin; ++i) {
163  stdair::Flag_T lCensorshipFlag = false;
164  const short lNbOfDTDs = iDCPBegin - iDCPEnd + 1;
165  const stdair::UnsignedIndex_T lIdx = i*lNbOfClasses + lCabinIdx;
166 
167  // Parse the DTDs during the period and compute the censorship flag
168  for (short j = 0; j < lNbOfDTDs; ++j) {
169  // Check if the data has been censored during this day.
170  // STDAIR_LOG_DEBUG ("i: " << i << ", NbOfClasses: " << lNbOfClasses
171  // << ", ClassIdx: " << iClassIdx << ", j: " << j);
172  if (lAvlView[lIdx][j] < 1.0) {
173  lCensorshipFlag = true;
174  break;
175  }
176  }
177 
178  // Compute the Q-equivalent bookings
179  stdair::NbOfBookings_T lNbOfHistoricalBkgs = 0.0;
180  for (stdair::BookingClassSellUpCurveMap_T::const_iterator itBCSUC =
181  iBCSellUpCurveMap.begin();
182  itBCSUC != iBCSellUpCurveMap.end(); ++itBCSUC) {
183  const stdair::BookingClass* lBookingClass_ptr = itBCSUC->first;
184  assert (lBookingClass_ptr != NULL);
185  const stdair::SellUpCurve_T& lSellUpCurve = itBCSUC->second;
186  stdair::SellUpCurve_T::const_iterator itSellUp =
187  lSellUpCurve.find (iDCPBegin);
188  assert (itSellUp != lSellUpCurve.end());
189  const stdair::SellupProbability_T& lSellUp = itSellUp->second;
190  assert (lSellUp != 0);
191 
192  // Retrieve the number of bookings
193  const stdair::ClassIndex_T& lClassIdx =
194  iSegmentSnapshotTable.getClassIndex(lBookingClass_ptr->describeKey());
195  stdair::NbOfBookings_T lNbOfBookings = 0.0;
196  for (short j = 0; j < lNbOfDTDs; ++j) {
197  lNbOfBookings += lBookingView[i*lNbOfClasses + lClassIdx][j];
198  }
199 
200  const stdair::NbOfBookings_T lNbOfQEquivalentBkgs=lNbOfBookings/lSellUp;
201  lNbOfHistoricalBkgs += lNbOfQEquivalentBkgs;
202  }
203 
204  HistoricalBooking lHistoricalBkg (lNbOfHistoricalBkgs, lCensorshipFlag);
205  ioHBHolder.addHistoricalBooking (lHistoricalBkg);
206  }
207  }
208 }