RMOL Logo  1.00.8
C++ library of Revenue Management and Optimisation classes and functions
Loading...
Searching...
No Matches
Utilities.cpp
Go to the documentation of this file.
1
2// //////////////////////////////////////////////////////////////////////
3// Import section
4// //////////////////////////////////////////////////////////////////////
5// STL
6#include <cassert>
7#include <string>
8#include <numeric>
9#include <algorithm>
10#include <cmath>
11// StdAir
12#include <stdair/basic/BasConst_Inventory.hpp>
13#include <stdair/bom/BomManager.hpp>
14#include <stdair/bom/SegmentCabin.hpp>
15#include <stdair/bom/FareFamily.hpp>
16#include <stdair/bom/BookingClass.hpp>
17#include <stdair/bom/BookingClassTypes.hpp>
18#include <stdair/service/Logger.hpp>
19// RMOL
23
24namespace RMOL {
25 // ////////////////////////////////////////////////////////////////////
27 computeDistributionParameters (const stdair::UncDemVector_T& iVector,
28 stdair::MeanValue_T& ioMean,
29 stdair::StdDevValue_T& ioStdDev) {
30 ioMean = 0.0; ioStdDev = 0.0;
31 const stdair::NbOfSamples_T lNbOfSamples = iVector.size();
32 assert (lNbOfSamples > 1);
33
34 // Compute the mean
35 for (stdair::UncDemVector_T::const_iterator itSample = iVector.begin();
36 itSample != iVector.end(); ++itSample) {
37 //STDAIR_LOG_NOTIFICATION (*itSample);
38 ioMean += *itSample;
39 }
40 ioMean /= lNbOfSamples;
41
42 // Compute the standard deviation
43 for (stdair::UncDemVector_T::const_iterator itSample = iVector.begin();
44 itSample != iVector.end(); ++itSample) {
45 const stdair::MeanValue_T& lSample = *itSample;
46 ioStdDev += ((lSample - ioMean) * (lSample - ioMean));
47 }
48 ioStdDev /= (lNbOfSamples - 1);
49 ioStdDev = std::sqrt (ioStdDev);
50
51 // Sanity check
52 if (ioStdDev == 0) {
53 ioStdDev = 0.1;
54 }
55 }
56
57 // ////////////////////////////////////////////////////////////////////
58 stdair::DCPList_T Utilities::
59 buildRemainingDCPList (const stdair::DTD_T& iDTD) {
60 stdair::DCPList_T oDCPList;
61
62 const stdair::DCPList_T lWholeDCPList = stdair::DEFAULT_DCP_LIST;
63 stdair::DCPList_T::const_iterator itDCP = lWholeDCPList.begin();
64 while (itDCP != lWholeDCPList.end()) {
65 const stdair::DCP_T& lDCP = *itDCP;
66 if (iDTD >= lDCP) {
67 break;
68 }
69 ++itDCP;
70 }
71 assert (itDCP != lWholeDCPList.end());
72
73 oDCPList.push_back (iDTD);
74 ++itDCP;
75 for (; itDCP != lWholeDCPList.end(); ++itDCP) {
76 oDCPList.push_back (*itDCP);
77 }
78
79 return oDCPList;
80 }
81
82 // ////////////////////////////////////////////////////////////////////
83 stdair::DCPList_T Utilities::
84 buildPastDCPList (const stdair::DTD_T& iDTD) {
85 stdair::DCPList_T oDCPList;
86
87 const stdair::DCPList_T lWholeDCPList = stdair::DEFAULT_DCP_LIST;
88 stdair::DCPList_T::const_iterator itDCP = lWholeDCPList.begin();
89 while (itDCP != lWholeDCPList.end()) {
90 const stdair::DCP_T& lDCP = *itDCP;
91 if (iDTD <= lDCP) {
92 oDCPList.push_back (lDCP);
93 ++itDCP;
94 } else {
95 break;
96 }
97 }
98
99 return oDCPList;
100 }
101
102 // ////////////////////////////////////////////////////////////////////
103 stdair::NbOfSegments_T Utilities::
104 getNbOfDepartedSimilarSegments (const stdair::SegmentCabin& iSegmentCabin,
105 const stdair::Date_T& iEventDate) {
106 stdair::DTD_T lDTD = 0;
107 // Retrieve the guillotine block.
108 const stdair::SegmentSnapshotTable& lSegmentSnapshotTable =
109 iSegmentCabin.getSegmentSnapshotTable();
111 getNbOfSegmentAlreadyPassedThisDTD (lSegmentSnapshotTable, lDTD, iEventDate);
112 }
113
114 // ////////////////////////////////////////////////////////////////////
115 stdair::BookingClassSellUpCurveMap_T Utilities::
116 computeSellUpFactorCurves (const stdair::FRAT5Curve_T& iFRAT5Curve,
117 const stdair::BookingClassList_T& iBCList) {
118 stdair::BookingClassSellUpCurveMap_T oBCSellUpFactorMap;
119
120 // Initialise a sell-up factor curve of 1.0 values
121 stdair::SellUpCurve_T lBasedSellUpCurve;
122 for (stdair::FRAT5Curve_T::const_iterator itFRAT5 = iFRAT5Curve.begin();
123 itFRAT5 != iFRAT5Curve.end(); ++itFRAT5) {
124 const stdair::DTD_T& lDTD = itFRAT5->first;
125 lBasedSellUpCurve.insert(stdair::SellUpCurve_T::value_type(lDTD, 1.0));
126 }
127
128 // Retrieve the classes from low to high and compute the distributions of
129 // product-oriented and price-oriented demand.
130 // Retrieve the lowest class.
131 stdair::BookingClassList_T::const_reverse_iterator itCurrentClass =
132 iBCList.rbegin();
133 assert (itCurrentClass != iBCList.rend());
134
135 // If there is only one class in the cabin, all the sell-up factors
136 // will be 1.
137 stdair::BookingClass* lLowestBC_ptr = *itCurrentClass;
138 assert (lLowestBC_ptr != NULL);
139 const stdair::Yield_T& lLowestYield = lLowestBC_ptr->getYield();
140 bool insert = oBCSellUpFactorMap.
141 insert (stdair::BookingClassSellUpCurveMap_T::
142 value_type(lLowestBC_ptr, lBasedSellUpCurve)).second;
143 assert (insert == true);
144 ++itCurrentClass;
145
146 // Compute the demand for higher class using the formula
147 // Pro_sell_up_from_Q_to_F = e ^ ((y_F/y_Q - 1) * ln (0.5) / (FRAT5 - 1))
148 for (; itCurrentClass != iBCList.rend(); ++itCurrentClass) {
149 stdair::BookingClass* lCurrentBC_ptr = *itCurrentClass;
150 assert (lCurrentBC_ptr != NULL);
151 const stdair::Yield_T& lCurrentYield = lCurrentBC_ptr->getYield();
152
153 // Compute the sell-up factor curve for the current class.
154 stdair::SellUpCurve_T lCurrentSellUpCurve;
155 for (stdair::FRAT5Curve_T::const_iterator itFRAT5 = iFRAT5Curve.begin();
156 itFRAT5 != iFRAT5Curve.end(); ++itFRAT5) {
157 const stdair::DTD_T& lDTD = itFRAT5->first;
158 const stdair::FRAT5_T& lFRAT5 = itFRAT5->second;
159 const double lSellUpCoef = log(0.5)/(lFRAT5-1);
160 const stdair::SellupProbability_T lSellUpFactor =
161 exp ((lCurrentYield/lLowestYield - 1.0) * lSellUpCoef);
162 const bool isInsertionSuccessful =
163 lCurrentSellUpCurve.insert (stdair::SellUpCurve_T::value_type(lDTD, lSellUpFactor)).second;
164 assert (isInsertionSuccessful == true);
165 }
166 const bool isInsertionSuccessful = oBCSellUpFactorMap.
167 insert (stdair::BookingClassSellUpCurveMap_T::
168 value_type(lCurrentBC_ptr, lCurrentSellUpCurve)).second;
169 assert (isInsertionSuccessful == true);
170 }
171 return oBCSellUpFactorMap;
172 }
173
174
175 // ////////////////////////////////////////////////////////////////////
176 stdair::BookingClassDispatchingCurveMap_T Utilities::
177 computeDispatchingFactorCurves (const stdair::FRAT5Curve_T& iFRAT5Curve,
178 const stdair::BookingClassList_T& iBCList) {
179 stdair::BookingClassDispatchingCurveMap_T oBCDispatchingFactorMap;
180
181 // Initialise a sell-up factor curve of 1.0 values
182 stdair::DispatchingCurve_T lBasedDispatchingCurve;
183 for (stdair::FRAT5Curve_T::const_iterator itFRAT5 = iFRAT5Curve.begin();
184 itFRAT5 != iFRAT5Curve.end(); ++itFRAT5) {
185 const stdair::DTD_T& lDTD = itFRAT5->first;
186 lBasedDispatchingCurve.insert(stdair::DispatchingCurve_T::value_type(lDTD, 1.0));
187 }
188
189 // Retrieve the classes from low to high and compute the distributions of
190 // product-oriented and price-oriented demand.
191 // Retrieve the lowest class.
192 stdair::BookingClassList_T::const_reverse_iterator itCurrentClass =
193 iBCList.rbegin();
194 assert (itCurrentClass != iBCList.rend());
195 stdair::BookingClassList_T::const_reverse_iterator itNextClass =
196 itCurrentClass; ++itNextClass;
197
198 // If there is only one class in the cabin, all the sell-up factors
199 // will be 1.
200 stdair::BookingClass* lLowestBC_ptr = *itCurrentClass;
201 assert (lLowestBC_ptr != NULL);
202 const stdair::Yield_T& lLowestYield = lLowestBC_ptr->getYield();
203 if (itNextClass == iBCList.rend()) {
204 bool insert = oBCDispatchingFactorMap.
205 insert (stdair::BookingClassDispatchingCurveMap_T::
206 value_type(lLowestBC_ptr, lBasedDispatchingCurve)).second;
207 assert (insert == true);
208 } else {
209 // Compute the demand for higher class using the formula
210 // Pro_sell_up_from_Q_to_F = e ^ ((y_F/y_Q - 1) * ln (0.5) / (FRAT5 - 1))
211 for (; itNextClass != iBCList.rend(); ++itCurrentClass, ++itNextClass) {
212 stdair::BookingClass* lCurrentBC_ptr = *itCurrentClass;
213 stdair::BookingClass* lNextBC_ptr = *itNextClass;
214 assert (lNextBC_ptr != NULL);
215 const stdair::Yield_T& lNextYield = lNextBC_ptr->getYield();
216
217 // Compute the sell-up factor curve for the current class.
218 stdair::DispatchingCurve_T lCurrentDispatchingCurve;
219 for (stdair::FRAT5Curve_T::const_iterator itFRAT5 = iFRAT5Curve.begin();
220 itFRAT5 != iFRAT5Curve.end(); ++itFRAT5) {
221 const stdair::DTD_T& lDTD = itFRAT5->first;
222 const stdair::FRAT5_T& lFRAT5 = itFRAT5->second;
223 const double lDispatchingCoef = log(0.5)/(lFRAT5-1);
224 double lDispatchingFactor =
225 exp ((lNextYield/lLowestYield - 1.0) * lDispatchingCoef);
226 stdair::DispatchingCurve_T::iterator itBasedDispatching =
227 lBasedDispatchingCurve.find (lDTD);
228 assert (itBasedDispatching != lBasedDispatchingCurve.end());
229 double& lBasedFactor = itBasedDispatching->second;
230 bool insert = lCurrentDispatchingCurve.insert (stdair::DispatchingCurve_T::value_type(lDTD, lBasedFactor - lDispatchingFactor)).second;
231 assert (insert == true);
232 lBasedFactor = lDispatchingFactor;
233 }
234 bool insert = oBCDispatchingFactorMap.
235 insert (stdair::BookingClassDispatchingCurveMap_T::
236 value_type(lCurrentBC_ptr, lCurrentDispatchingCurve)).second;
237 assert (insert == true);
238 }
239
240 // Compute the sell-up factor curve for the highest class (which is the
241 // "current class")
242 stdair::BookingClass* lCurrentBC_ptr = *itCurrentClass;
243 bool insert = oBCDispatchingFactorMap.
244 insert (stdair::BookingClassDispatchingCurveMap_T::
245 value_type(lCurrentBC_ptr, lBasedDispatchingCurve)).second;
246 assert (insert == true);
247 }
248 return oBCDispatchingFactorMap;
249 }
250
251 // ////////////////////////////////////////////////////////////////////
253 (const stdair::BookingClassDispatchingCurveMap_T& iBCDispatchingCurveMap,
254 const stdair::MeanValue_T& iMean,
255 const stdair::StdDevValue_T& iStdDev,
256 const stdair::DTD_T& iCurrentDCP) {
257 for (stdair::BookingClassDispatchingCurveMap_T::const_iterator itBCDC =
258 iBCDispatchingCurveMap.begin();
259 itBCDC != iBCDispatchingCurveMap.end(); ++itBCDC) {
260 stdair::BookingClass* lBC_ptr = itBCDC->first;
261 assert (lBC_ptr != NULL);
262 const stdair::DispatchingCurve_T& lDispatchingCurve = itBCDC->second;
263 stdair::DispatchingCurve_T::const_iterator itDispatchingFactor =
264 lDispatchingCurve.find (iCurrentDCP);
265 assert (itDispatchingFactor != lDispatchingCurve.end());
266 const double& lDF = itDispatchingFactor->second;
267
268 const stdair::MeanValue_T& lCurrentMean = lBC_ptr->getPriceDemMean();
269 const stdair::StdDevValue_T& lCurrentStdDev = lBC_ptr->getPriceDemStdDev();
270
271 const stdair::MeanValue_T lAdditionalMean = iMean * lDF;
272 const stdair::StdDevValue_T lAdditionalStdDev = iStdDev * std::sqrt (lDF);
273
274 const stdair::MeanValue_T lNewMean = lCurrentMean + lAdditionalMean;
275 const stdair::StdDevValue_T lNewStdDev =
276 std::sqrt (lCurrentStdDev * lCurrentStdDev
277 + lAdditionalStdDev * lAdditionalStdDev);
278
279 lBC_ptr->setPriceDemMean (lNewMean);
280 lBC_ptr->setPriceDemStdDev (lNewStdDev);
281 }
282 }
283
284 // ////////////////////////////////////////////////////////////////////
286 (const stdair::BookingClassSellUpCurveMap_T& iBCSellUpCurveMap,
287 const stdair::MeanValue_T& iMean,
288 const stdair::StdDevValue_T& iStdDev,
289 const stdair::DTD_T& iCurrentDCP) {
290 for (stdair::BookingClassSellUpCurveMap_T::const_iterator itBCSU =
291 iBCSellUpCurveMap.begin();
292 itBCSU != iBCSellUpCurveMap.end(); ++itBCSU) {
293 stdair::BookingClass* lBC_ptr = itBCSU->first;
294 assert (lBC_ptr != NULL);
295 const stdair::SellUpCurve_T& lSellUpCurve = itBCSU->second;
296 stdair::SellUpCurve_T::const_iterator itSellUpFactor =
297 lSellUpCurve.find (iCurrentDCP);
298 assert (itSellUpFactor != lSellUpCurve.end());
299 const stdair::SellupProbability_T& lSU = itSellUpFactor->second;
300
301 const stdair::MeanValue_T& lCurrentMean = lBC_ptr->getCumuPriceDemMean();
302 const stdair::StdDevValue_T& lCurrentStdDev =
303 lBC_ptr->getCumuPriceDemStdDev();
304
305 const stdair::MeanValue_T lAdditionalMean = iMean * lSU;
306 const stdair::StdDevValue_T lAdditionalStdDev = iStdDev * std::sqrt (lSU);
307
308 const stdair::MeanValue_T lNewMean = lCurrentMean + lAdditionalMean;
309 const stdair::StdDevValue_T lNewStdDev =
310 std::sqrt (lCurrentStdDev * lCurrentStdDev
311 + lAdditionalStdDev * lAdditionalStdDev);
312
313 lBC_ptr->setCumuPriceDemMean (lNewMean);
314 lBC_ptr->setCumuPriceDemStdDev (lNewStdDev);
315 }
316 }
317}
Definition: BasConst.cpp:7
static stdair::NbOfSegments_T getNbOfSegmentAlreadyPassedThisDTD(const stdair::SegmentSnapshotTable &, const stdair::DTD_T &, const stdair::Date_T &)
static stdair::DCPList_T buildPastDCPList(const stdair::DTD_T &)
Definition: Utilities.cpp:84
static stdair::NbOfSegments_T getNbOfDepartedSimilarSegments(const stdair::SegmentCabin &, const stdair::Date_T &)
Definition: Utilities.cpp:104
static void dispatchDemandForecast(const stdair::BookingClassDispatchingCurveMap_T &, const stdair::MeanValue_T &, const stdair::StdDevValue_T &, const stdair::DTD_T &)
Definition: Utilities.cpp:253
static stdair::BookingClassDispatchingCurveMap_T computeDispatchingFactorCurves(const stdair::FRAT5Curve_T &, const stdair::BookingClassList_T &)
Definition: Utilities.cpp:177
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 &)
Definition: Utilities.cpp:116
static stdair::DCPList_T buildRemainingDCPList(const stdair::DTD_T &)
Definition: Utilities.cpp:59
static void dispatchDemandForecastForFA(const stdair::BookingClassSellUpCurveMap_T &, const stdair::MeanValue_T &, const stdair::StdDevValue_T &, const stdair::DTD_T &)
Definition: Utilities.cpp:286