RMOL Logo  1.00.14
C++ library of Revenue Management and Optimisation classes and functions
Loading...
Searching...
No Matches
NewQFF.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/SegmentDate.hpp>
13#include <stdair/bom/SegmentCabin.hpp>
14#include <stdair/bom/SegmentSnapshotTable.hpp>
15#include <stdair/bom/FareFamily.hpp>
16#include <stdair/bom/BookingClass.hpp>
17#include <stdair/bom/Policy.hpp>
18#include <stdair/service/Logger.hpp>
19// RMOL
27
28namespace RMOL {
29 // ////////////////////////////////////////////////////////////////////
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 // Browse the list of fare families and execute "Q-forecasting" within
41 // each fare family.
42 const stdair::FareFamilyList_T& lFFList =
43 stdair::BomManager::getList<stdair::FareFamily>(ioSegmentCabin);
44 for (stdair::FareFamilyList_T::const_iterator itFF = lFFList.begin();
45 itFF != lFFList.end(); ++itFF) {
46 stdair::FareFamily* lFF_ptr = *itFF;
47 assert (lFF_ptr != NULL);
48
49 forecast (*lFF_ptr,
50 iCurrentDate,
51 iCurrentDTD,
52 iUnconstrainingMethod,
53 iNbOfDepartedSegments,
54 lSegmentSnapshotTable);
55 }
56
57 // Dispatch the demand forecast to the policies.
58 dispatchDemandForecastToPolicies (ioSegmentCabin);
59
60 return true;
61 }
62
63 // ////////////////////////////////////////////////////////////////////
64 void NewQFF::
65 forecast (stdair::FareFamily& ioFareFamily,
66 const stdair::Date_T& iCurrentDate,
67 const stdair::DTD_T& iCurrentDTD,
68 const stdair::UnconstrainingMethod& iUnconstrainingMethod,
69 const stdair::NbOfSegments_T& iNbOfDepartedSegments,
70 const stdair::SegmentSnapshotTable& iSegmentSnapshotTable) {
71 // Retrieve the FRAT5Curve.
72 const stdair::FRAT5Curve_T& lFRAT5Curve = ioFareFamily.getFrat5Curve();
73
74 // Retrieve the booking class list and compute the sell up curves
75 // and the dispatching curves.
76 const stdair::BookingClassList_T& lBCList =
77 stdair::BomManager::getList<stdair::BookingClass>(ioFareFamily);
78 const stdair::BookingClassSellUpCurveMap_T lBCSellUpCurveMap =
79 Utilities::computeSellUpFactorCurves (lFRAT5Curve, lBCList);
80 const stdair::BookingClassDispatchingCurveMap_T lBCDispatchingCurveMap =
81 Utilities::computeDispatchingFactorCurves (lFRAT5Curve, lBCList);
82
83 // Browse all remaining DCP's and do unconstraining, forecasting
84 // and dispatching.
85 const stdair::DCPList_T lWholeDCPList = stdair::DEFAULT_DCP_LIST;
86 stdair::DCPList_T::const_iterator itDCP = lWholeDCPList.begin();
87 stdair::DCPList_T::const_iterator itNextDCP = itDCP; ++itNextDCP;
88 for (; itNextDCP != lWholeDCPList.end(); ++itDCP, ++itNextDCP) {
89 const stdair::DCP_T& lCurrentDCP = *itDCP;
90 const stdair::DCP_T& lNextDCP = *itNextDCP;
91
92 // The end of the interval is after the current DTD.
93 if (lNextDCP < iCurrentDTD) {
94 // Get the number of similar segments which has already passed the
95 // (lNextDCP+1)
96 const stdair::NbOfSegments_T& lNbOfUsableSegments =
98 getNbOfSegmentAlreadyPassedThisDTD (iSegmentSnapshotTable,
99 lNextDCP+1,
100 iCurrentDate);
101 stdair::NbOfSegments_T lSegmentBegin = 0;
102 const stdair::NbOfSegments_T lSegmentEnd = lNbOfUsableSegments-1;
103 if (iNbOfDepartedSegments > 52) {
104 lSegmentBegin = iNbOfDepartedSegments - 52;
105 }
106
107 // Retrieve the historical bookings and convert them to
108 // Q-equivalent bookings.
109 HistoricalBookingHolder lHBHolder;
110 preparePriceOrientedHistoricalBooking (ioFareFamily,
111 iSegmentSnapshotTable,
112 lHBHolder,
113 lCurrentDCP, lNextDCP,
114 lSegmentBegin, lSegmentEnd,
115 lBCSellUpCurveMap);
116
117 // Unconstrain the historical bookings.
118 Detruncator::unconstrain (lHBHolder, iUnconstrainingMethod);
119
120 // Retrieve the historical unconstrained demand and perform the
121 // forecasting.
122 stdair::UncDemVector_T lUncDemVector;
123 // Be careful, the getter returns the vector size,
124 // so there is no reference.
125 const short lNbOfHistoricalFlights = lHBHolder.getNbOfFlights();
126 for (short i = 0; i < lNbOfHistoricalFlights; ++i) {
127 const stdair::NbOfBookings_T& lUncDemand =
128 lHBHolder.getUnconstrainedDemand (i);
129 lUncDemVector.push_back (lUncDemand);
130 }
131 stdair::MeanValue_T lMean = 0.0;
132 stdair::StdDevValue_T lStdDev = 0.0;
134 lMean, lStdDev);
135
136 // Dispatch the forecast to all the classes.
137 Utilities::dispatchDemandForecast (lBCDispatchingCurveMap,
138 lMean, lStdDev, lCurrentDCP);
139
140 // Dispatch the forecast to all classes for Fare Adjustment or MRT.
141 // The sell-up probability will be used in this case.
143 lMean, lStdDev, lCurrentDCP);
144
145 // Add the demand forecast to the fare family.
146 const stdair::MeanValue_T& lCurrentMean = ioFareFamily.getMean();
147 const stdair::StdDevValue_T& lCurrentStdDev = ioFareFamily.getStdDev();
148
149 const stdair::MeanValue_T lNewMean = lCurrentMean + lMean;
150 const stdair::StdDevValue_T lNewStdDev =
151 std::sqrt (lCurrentStdDev * lCurrentStdDev + lStdDev * lStdDev);
152
153 ioFareFamily.setMean (lNewMean);
154 ioFareFamily.setStdDev (lNewStdDev);
155 }
156 }
157
158 }
159
160 // ////////////////////////////////////////////////////////////////////
161 void NewQFF::preparePriceOrientedHistoricalBooking
162 (const stdair::FareFamily& iFareFamily,
163 const stdair::SegmentSnapshotTable& iSegmentSnapshotTable,
164 HistoricalBookingHolder& ioHBHolder,
165 const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
166 const stdair::NbOfSegments_T& iSegmentBegin,
167 const stdair::NbOfSegments_T& iSegmentEnd,
168 const stdair::BookingClassSellUpCurveMap_T& iBCSellUpCurveMap) {
169
170 // Retrieve the gross daily booking and availability snapshots.
171 const stdair::ConstSegmentCabinDTDRangeSnapshotView_T lPriceBookingView =
172 iSegmentSnapshotTable.getConstSegmentCabinDTDRangePriceOrientedGrossBookingSnapshotView (iSegmentBegin, iSegmentEnd, iDCPEnd, iDCPBegin);
173 const stdair::ConstSegmentCabinDTDRangeSnapshotView_T lProductBookingView =
174 iSegmentSnapshotTable.getConstSegmentCabinDTDRangeProductOrientedGrossBookingSnapshotView (iSegmentBegin, iSegmentEnd, iDCPEnd, iDCPBegin);
175 const stdair::ConstSegmentCabinDTDRangeSnapshotView_T lAvlView =
176 iSegmentSnapshotTable.getConstSegmentCabinDTDRangeAvailabilitySnapshotView (iSegmentBegin, iSegmentEnd, iDCPEnd, iDCPBegin);
177
178 // Browse the list of segments and build the historical booking holder.
179 const stdair::ClassIndexMap_T& lVTIdxMap =
180 iSegmentSnapshotTable.getClassIndexMap();
181 const stdair::NbOfClasses_T lNbOfClasses = lVTIdxMap.size();
182
183 for (short i = 0; i <= iSegmentEnd-iSegmentBegin; ++i) {
184 stdair::Flag_T lCensorshipFlag = false;
185 const short lNbOfDTDs = iDCPBegin - iDCPEnd + 1;
186
187 // Parse the DTDs during the period and compute the censorship flag
188 for (short j = 0; j < lNbOfDTDs; ++j) {
189 // Check if the data has been censored during this day.
190 // STDAIR_LOG_DEBUG ("i: " << i << ", NbOfClasses: " << lNbOfClasses
191 // << ", ClassIdx: " << iClassIdx << ", j: " << j);
192 bool tempCensorship = true;
193 for (stdair::BookingClassSellUpCurveMap_T::const_iterator itBCSUC =
194 iBCSellUpCurveMap.begin();
195 itBCSUC != iBCSellUpCurveMap.end(); ++itBCSUC) {
196 const stdair::BookingClass* lBookingClass_ptr = itBCSUC->first;
197 assert (lBookingClass_ptr != NULL);
198 const stdair::ClassIndex_T& lClassIdx =
199 iSegmentSnapshotTable.getClassIndex(lBookingClass_ptr->describeKey());
200 const stdair::UnsignedIndex_T lAvlIdx = i*lNbOfClasses + lClassIdx;
201 if (lAvlView[lAvlIdx][j] >= 1.0) {
202 tempCensorship = false;
203 break;
204 }
205 }
206 if (tempCensorship == true) {
207 lCensorshipFlag = true;
208 break;
209 }
210 }
211
212 // Compute the Q-equivalent bookings
213 stdair::NbOfBookings_T lNbOfHistoricalBkgs = 0.0;
214 for (stdair::BookingClassSellUpCurveMap_T::const_iterator itBCSUC =
215 iBCSellUpCurveMap.begin();
216 itBCSUC != iBCSellUpCurveMap.end(); ++itBCSUC) {
217 const stdair::BookingClass* lBookingClass_ptr = itBCSUC->first;
218 assert (lBookingClass_ptr != NULL);
219 const stdair::SellUpCurve_T& lSellUpCurve = itBCSUC->second;
220 stdair::SellUpCurve_T::const_iterator itSellUp =
221 lSellUpCurve.find (iDCPBegin);
222 assert (itSellUp != lSellUpCurve.end());
223 const stdair::SellupProbability_T& lSellUp = itSellUp->second;
224 assert (lSellUp != 0);
225
226 // Retrieve the number of bookings
227 const stdair::ClassIndex_T& lClassIdx =
228 iSegmentSnapshotTable.getClassIndex(lBookingClass_ptr->describeKey());
229 const stdair::UnsignedIndex_T lIdx = i*lNbOfClasses + lClassIdx;
230
231 stdair::NbOfBookings_T lNbOfBookings = 0.0;
232 for (short j = 0; j < lNbOfDTDs; ++j) {
233 lNbOfBookings +=
234 lPriceBookingView[lIdx][j] + lProductBookingView[lIdx][j];
235 }
236 const stdair::NbOfBookings_T lNbOfQEquivalentBkgs=lNbOfBookings/lSellUp;
237
238 lNbOfHistoricalBkgs += lNbOfQEquivalentBkgs;
239 }
240
241 HistoricalBooking lHistoricalBkg (lNbOfHistoricalBkgs, lCensorshipFlag);
242 ioHBHolder.addHistoricalBooking (lHistoricalBkg);
243 }
244 }
245
246 // ////////////////////////////////////////////////////////////////////
247 void NewQFF::
248 dispatchDemandForecastToPolicies (const stdair::SegmentCabin& iSegmentCabin){
249 // Retrieve the list of policies.
250 const stdair::PolicyList_T& lPolicyList =
251 stdair::BomManager::getList<stdair::Policy> (iSegmentCabin);
252
253 for (stdair::PolicyList_T::const_iterator itPolicy = lPolicyList.begin();
254 itPolicy != lPolicyList.end(); ++itPolicy) {
255 stdair::Policy* lPolicy_ptr = *itPolicy;
256 assert (lPolicy_ptr != NULL);
257 dispatchDemandForecastToPolicy(*lPolicy_ptr);
258 }
259 }
260
261 // ////////////////////////////////////////////////////////////////////
262 void NewQFF::
263 dispatchDemandForecastToPolicy (stdair::Policy& ioPolicy){
264 // Reset the demand forecast of the policy
265 ioPolicy.resetDemandForecast();
266
267 const stdair::MeanValue_T& lPolicyDemand = ioPolicy.getDemand();
268 const stdair::StdDevValue_T& lPolicyStdDev = ioPolicy.getStdDev();
269 stdair::MeanValue_T lNewPolicyDemand = lPolicyDemand;
270 stdair::MeanValue_T lNewPolicyStdDev = lPolicyStdDev;
271
272 // Browse the list of booking classes of the policy and use the
273 // cumulative price-oriented demand forecast of each class.
274 const bool hasAListOfBC =
275 stdair::BomManager::hasList<stdair::BookingClass> (ioPolicy);
276 if (hasAListOfBC == true) {
277 const stdair::BookingClassList_T& lBCList =
278 stdair::BomManager::getList<stdair::BookingClass> (ioPolicy);
279 for (stdair::BookingClassList_T::const_iterator itBC = lBCList.begin();
280 itBC != lBCList.end(); ++itBC) {
281 const stdair::BookingClass* lBC_ptr = *itBC;
282 assert (lBC_ptr != NULL);
283 const stdair::Yield_T& lYield = lBC_ptr->getYield();
284 const stdair::MeanValue_T& lDemand = lBC_ptr->getCumuPriceDemMean();
285 const stdair::StdDevValue_T& lStdDev =
286 lBC_ptr->getCumuPriceDemStdDev();
287
288 ioPolicy.addYieldDemand (lYield, lDemand);
289 lNewPolicyDemand += lDemand;
290 const stdair::StdDevValue_T lSquareNewPolicyStdDev =
291 lNewPolicyStdDev*lNewPolicyStdDev + lStdDev*lStdDev;
292 lNewPolicyStdDev =
293 std::sqrt (lSquareNewPolicyStdDev);
294 }
295 ioPolicy.setDemand(lNewPolicyDemand);
296 ioPolicy.setStdDev(lNewPolicyStdDev);
297 }
298 }
299}
static stdair::NbOfSegments_T getNbOfSegmentAlreadyPassedThisDTD(const stdair::SegmentSnapshotTable &, const stdair::DTD_T &, const stdair::Date_T &)
static void dispatchDemandForecast(const stdair::BookingClassDispatchingCurveMap_T &, const stdair::MeanValue_T &, const stdair::StdDevValue_T &, const stdair::DTD_T &)
static stdair::BookingClassDispatchingCurveMap_T computeDispatchingFactorCurves(const stdair::FRAT5Curve_T &, const stdair::BookingClassList_T &)
static void computeDistributionParameters(const stdair::UncDemVector_T &, stdair::MeanValue_T &, stdair::StdDevValue_T &)
Definition Utilities.cpp:27
static stdair::BookingClassSellUpCurveMap_T computeSellUpFactorCurves(const stdair::FRAT5Curve_T &, const stdair::BookingClassList_T &)
static void dispatchDemandForecastForFA(const stdair::BookingClassSellUpCurveMap_T &, const stdair::MeanValue_T &, const stdair::StdDevValue_T &, const stdair::DTD_T &)
static void unconstrain(HistoricalBookingHolder &, const stdair::UnconstrainingMethod &)
static bool forecast(stdair::SegmentCabin &, const stdair::Date_T &, const stdair::DTD_T &, const stdair::UnconstrainingMethod &, const stdair::NbOfSegments_T &)
Definition NewQFF.cpp:31