RMOL Logo  0.25.3
C++ library of Revenue Management and Optimisation classes and functions
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros Pages
Detruncator.cpp
Go to the documentation of this file.
1 // //////////////////////////////////////////////////////////////////////
2 // Import section
3 // //////////////////////////////////////////////////////////////////////
4 // STL
5 #include <cassert>
6 // StdAir
7 #include <stdair/basic/BasConst_Inventory.hpp>
8 #include <stdair/bom/GuillotineBlock.hpp>
9 #include <stdair/bom/BomManager.hpp>
10 #include <stdair/bom/FlightDate.hpp>
11 #include <stdair/bom/SegmentDate.hpp>
12 #include <stdair/bom/SegmentCabin.hpp>
13 #include <stdair/bom/BookingClass.hpp>
14 #include <stdair/service/Logger.hpp>
15 // RMOL
21 
22 namespace RMOL {
23  // ////////////////////////////////////////////////////////////////////
24  void Detruncator::
25  unconstrainUsingAdditivePickUp (const stdair::SegmentCabin& iSegmentCabin,
26  BookingClassUnconstrainedDemandVectorMap_T& ioBkgClassUncDemMap,
27  UnconstrainedDemandVector_T& ioQEquivalentDemandVector,
28  const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
29  const stdair::Date_T& iCurrentDate) {
30 
31  // Retrieve the guillotine block.
32  const stdair::GuillotineBlock& lGuillotineBlock =
33  iSegmentCabin.getGuillotineBlock();
34 
35  // Build the historical booking holders for the product-oriented bookings
36  // of the casses and the Q-equivalent (price-oriented) bookings of the cabin
37  const stdair::NbOfSegments_T lNbOfUsableSegments = GuillotineBlockHelper::
38  getNbOfSegmentAlreadyPassedThisDTD (lGuillotineBlock, iDCPEnd,
39  iCurrentDate);
40 
41  // Parse the booking class list and unconstrain historical bookings.
42  for (BookingClassUnconstrainedDemandVectorMap_T::iterator itBCUDV =
43  ioBkgClassUncDemMap.begin(); itBCUDV != ioBkgClassUncDemMap.end();
44  ++itBCUDV) {
45  stdair::BookingClass* lBC_ptr = itBCUDV->first;
46  assert (lBC_ptr != NULL);
47  const stdair::MapKey_T& lBCKey = lBC_ptr->describeKey();
48  const stdair::BlockIndex_T& lBlockIdx =
49  lGuillotineBlock.getBlockIndex (lBCKey);
50  UnconstrainedDemandVector_T& lUncDemVector = itBCUDV->second;
51 
52  STDAIR_LOG_DEBUG ("Unconstrain product-oriented bookings for " << lBCKey);
53  // STDAIR_LOG_NOTIFICATION (lBCKey << ";" << iDCPBegin
54  // << ";" << iDCPEnd);
55  unconstrainUsingAdditivePickUp (lGuillotineBlock, lUncDemVector,
56  iDCPBegin, iDCPEnd,
57  lNbOfUsableSegments, lBlockIdx);
58  }
59 
60  // Unconstrain the Q-equivalent bookings.
61  // Retrieve the block index of the segment-cabin.
62  std::ostringstream lSCMapKey;
63  lSCMapKey << stdair::DEFAULT_SEGMENT_CABIN_VALUE_TYPE
64  << iSegmentCabin.describeKey();
65  const stdair::BlockIndex_T& lCabinIdx =
66  lGuillotineBlock.getBlockIndex (lSCMapKey.str());
67 
68  STDAIR_LOG_DEBUG ("Unconstrain price-oriented bookings");
69  //STDAIR_LOG_NOTIFICATION (iDCPBegin << ";" << iDCPEnd);
70  unconstrainUsingAdditivePickUp (lGuillotineBlock, ioQEquivalentDemandVector,
71  iDCPBegin, iDCPEnd, lNbOfUsableSegments,
72  lCabinIdx, iSegmentCabin, iCurrentDate);
73  }
74 
75  // ////////////////////////////////////////////////////////////////////
77  (const stdair::GuillotineBlock& iGuillotineBlock,
78  UnconstrainedDemandVector_T& ioUncDemVector,
79  const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
80  const stdair::NbOfSegments_T& iNbOfUsableSegments,
81  const stdair::BlockIndex_T& iBlockIdx) {
82  // TODO:
83  stdair::NbOfSegments_T lSegBegin = 0;
84  if (iNbOfUsableSegments > 52) lSegBegin = iNbOfUsableSegments - 52;
85  // Retrieve the gross daily booking and availability snapshots.
86  stdair::ConstSegmentCabinDTDRangeSnapshotView_T lBookingView =
87  iGuillotineBlock.getConstSegmentCabinDTDRangeProductAndPriceOrientedBookingSnapshotView (lSegBegin, iNbOfUsableSegments -1, iDCPEnd, iDCPBegin);
88  stdair::ConstSegmentCabinDTDRangeSnapshotView_T lAvlView =
89  iGuillotineBlock.getConstSegmentCabinDTDRangeAvailabilitySnapshotView (lSegBegin, iNbOfUsableSegments -1, iDCPEnd, iDCPBegin);
90 
91  // Browse the list of segments and build the historical booking holder.
92  const stdair::ValueTypeIndexMap_T& lVTIdxMap =
93  iGuillotineBlock.getValueTypeIndexMap();
94  const unsigned int lNbOfValueTypes = lVTIdxMap.size();
95  HistoricalBookingHolder lHBHolder;
96  for (short i = 0; i < iNbOfUsableSegments-lSegBegin; ++i) {
97  stdair::Flag_T lCensorshipFlag = false;
98  stdair::NbOfBookings_T lNbOfHistoricalBkgs = 0.0;
99  const short lNbOfDTDs = iDCPBegin - iDCPEnd + 1;
100 
101  // Parse the DTDs during the period
102  for (short j = 0; j < lNbOfDTDs; ++j) {
103  // Check if the data has been censored during this day.
104  // STDAIR_LOG_DEBUG ("i: " << i << ", NbOfValues: " << lNbOfValueTypes
105  // << ", BlockIdx: " << iBlockIdx << ", j: " << j);
106  if (lCensorshipFlag == false) {
107  if (lAvlView[i*lNbOfValueTypes + iBlockIdx][j] < 1.0) {
108  lCensorshipFlag = true;
109  }
110  }
111 
112  // Get the bookings of the day.
113  //STDAIR_LOG_DEBUG ("Bookings of the day: " << lBookingView[i*lNbOfValueTypes + iBlockIdx][j]);
114  lNbOfHistoricalBkgs += lBookingView[i*lNbOfValueTypes + iBlockIdx][j];
115  }
116 
117  HistoricalBooking lHistoricalBkg (lNbOfHistoricalBkgs, lCensorshipFlag);
118  lHBHolder.addHistoricalBooking (lHistoricalBkg);
119 
120  // DEBUG
121  STDAIR_LOG_DEBUG ("Historical bkgs: " << lNbOfHistoricalBkgs
122  << ", censored: " << lCensorshipFlag);
123  // STDAIR_LOG_NOTIFICATION (lNbOfHistoricalBkgs
124  // << ";" << lCensorshipFlag);
125  }
126 
127  // DEBUG
128  STDAIR_LOG_DEBUG ("Unconstrain by EM");
129 
130  // Unconstrain the booking figures
132 
133  // Add the unconstrained demand of the period to the unconstrained demand
134  // vector.
135  short idx = 0;
136  for (UnconstrainedDemandVector_T::iterator itUD = ioUncDemVector.begin();
137  itUD != ioUncDemVector.end(); ++itUD, ++idx) {
138  *itUD += lHBHolder.getUnconstrainedDemand (idx);
139  //STDAIR_LOG_NOTIFICATION (lHBHolder.getUnconstrainedDemand (idx));
140  }
141  }
142 
143  // ////////////////////////////////////////////////////////////////////
145  (const stdair::GuillotineBlock& iGuillotineBlock,
146  UnconstrainedDemandVector_T& ioUncDemVector,
147  const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
148  const stdair::NbOfSegments_T& iNbOfUsableSegments,
149  const stdair::BlockIndex_T& iBlockIdx,
150  const stdair::SegmentCabin& iSegmentCabin,
151  const stdair::Date_T& iCurrentDate) {
152  // TODO
153  stdair::NbOfSegments_T lSegBegin = 0;
154  if (iNbOfUsableSegments > 52) lSegBegin = iNbOfUsableSegments - 52;
155  // Retrieve the gross daily booking and availability snapshots.
156  stdair::ConstSegmentCabinDTDRangeSnapshotView_T lBookingView =
157  iGuillotineBlock.getConstSegmentCabinDTDRangeProductAndPriceOrientedBookingSnapshotView (lSegBegin, iNbOfUsableSegments -1, iDCPEnd, iDCPBegin);
158  stdair::ConstSegmentCabinDTDRangeSnapshotView_T lAvlView =
159  iGuillotineBlock.getConstSegmentCabinDTDRangeAvailabilitySnapshotView (lSegBegin, iNbOfUsableSegments -1, iDCPEnd, iDCPBegin);
160 
161  // Browse the list of segments and build the historical booking holder.
162  const stdair::ValueTypeIndexMap_T& lVTIdxMap =
163  iGuillotineBlock.getValueTypeIndexMap();
164  const unsigned int lNbOfValueTypes = lVTIdxMap.size();
165  HistoricalBookingHolder lHBHolder;
166  for (short i = 0; i < iNbOfUsableSegments-lSegBegin; ++i) {
167  stdair::Flag_T lCensorshipFlag = false;
168  stdair::NbOfBookings_T lNbOfHistoricalBkgs = 0.0;
169  const short lNbOfDTDs = iDCPBegin - iDCPEnd + 1;
170 
171  // Parse the DTDs during the period
172  for (short j = 0; j < lNbOfDTDs; ++j) {
173  // Check if the data has been censored during this day.
174  // STDAIR_LOG_DEBUG ("i: " << i << ", NbOfValues: " << lNbOfValueTypes
175  // << ", BlockIdx: " << iBlockIdx << ", j: " << j);
176  if (lCensorshipFlag == false) {
177  if (lAvlView[i*lNbOfValueTypes + iBlockIdx][j] < 1.0) {
178  lCensorshipFlag = true;
179  }
180  }
181 
182  // Get the bookings of the day.
183  //STDAIR_LOG_DEBUG ("Bookings of the day: " << lBookingView[i*lNbOfValueTypes + iBlockIdx][j]);
184  lNbOfHistoricalBkgs += lBookingView[i*lNbOfValueTypes + iBlockIdx][j];
185  }
186 
187  HistoricalBooking lHistoricalBkg (lNbOfHistoricalBkgs, lCensorshipFlag);
188  lHBHolder.addHistoricalBooking (lHistoricalBkg);
189 
190  // DEBUG
191  STDAIR_LOG_DEBUG ("Historical bkgs: " << lNbOfHistoricalBkgs
192  << ", censored: " << lCensorshipFlag);
193  // STDAIR_LOG_NOTIFICATION (lNbOfHistoricalBkgs
194  // << ";" << lCensorshipFlag);
195  }
196 
197  // DEBUG
198  STDAIR_LOG_DEBUG ("Unconstrain by EM");
199 
200  // Unconstrain the booking figures
202 
203  // Add the unconstrained demand of the period to the unconstrained demand
204  // vector.
205  // LOG
206  const stdair::SegmentDate& lSegmentDate = stdair::BomManager::
207  getParent<stdair::SegmentDate, stdair::SegmentCabin> (iSegmentCabin);
208  const stdair::FlightDate& lFlightDate = stdair::BomManager::
209  getParent<stdair::FlightDate, stdair::SegmentDate> (lSegmentDate);
210  const stdair::Date_T& lDepDate = lFlightDate.getDepartureDate();
211  const boost::gregorian::date_duration lDD = lDepDate - iCurrentDate;
212  const long lDTD = lDD.days();
213  stdair::Date_T lRefDate (2012, boost::gregorian::Jan, 01);
214 
215  short idx = 0;
216  for (UnconstrainedDemandVector_T::iterator itUD = ioUncDemVector.begin();
217  itUD != ioUncDemVector.end(); ++itUD, ++idx) {
218  *itUD += lHBHolder.getUnconstrainedDemand (idx);
219  if (lDepDate > lRefDate) {
220  const stdair::DateOffset_T lDateOffset (7 *(52 - idx) + 420);
221  const stdair::Date_T lHDate = lDepDate - lDateOffset;
222  STDAIR_LOG_NOTIFICATION (boost::gregorian::to_iso_string(lDepDate)
223  << ";" << lDTD << ";" << iDCPBegin << ";"
224  << iDCPEnd << ";"
225  << boost::gregorian::to_iso_string (lHDate)
226  <<";"<<lHBHolder.getUnconstrainedDemand (idx));
227 
228  STDAIR_LOG_NOTIFICATION (boost::gregorian::to_iso_string(lDepDate)
229  << ";" << lDTD << ";" << iDCPBegin << ";"
230  << iDCPEnd << ";"
231  << boost::gregorian::to_iso_string (lHDate)
232  <<";"<<lHBHolder.getHistoricalBooking (idx));
233  }
234  }
235  }
236 
237  // ////////////////////////////////////////////////////////////////////
239  (const stdair::SegmentCabin& iSegmentCabin,
240  BookingClassUnconstrainedDemandVectorMap_T& ioBkgClassUncDemVectorMap,
241  UnconstrainedDemandVector_T& ioQEquivalentDemandVector,
242  const stdair::DCP_T& iFirstDCP, const stdair::NbOfSegments_T& iNbOfSegments,
243  const stdair::NbOfSegments_T& iNbOfUsedSegments){
244 
245  // Retrieve the guillotine block.
246  const stdair::GuillotineBlock& lGuillotineBlock =
247  iSegmentCabin.getGuillotineBlock();
248 
249  // Parse the booking class list and unconstrain historical bookings.
250  for (BookingClassUnconstrainedDemandVectorMap_T::iterator itBCUDV =
251  ioBkgClassUncDemVectorMap.begin();
252  itBCUDV != ioBkgClassUncDemVectorMap.end(); ++itBCUDV) {
253  stdair::BookingClass* lBC_ptr = itBCUDV->first;
254  assert (lBC_ptr != NULL);
255  const stdair::MapKey_T& lBCKey = lBC_ptr->describeKey();
256  const stdair::BlockIndex_T& lBlockIdx =
257  lGuillotineBlock.getBlockIndex (lBCKey);
258  UnconstrainedDemandVector_T& lUncDemVector = itBCUDV->second;
259 
260  STDAIR_LOG_DEBUG("Retrieve the unconstrained product-oriented demand for "
261  << lBCKey);
262  retrieveUnconstrainedDemandForFirstDCP (lGuillotineBlock, lUncDemVector,
263  iFirstDCP, lBlockIdx,
264  iNbOfSegments, iNbOfUsedSegments);
265  }
266 
267  // Unconstrain the Q-equivalent bookings.
268  // Retrieve the block index of the segment-cabin.
269  std::ostringstream lSCMapKey;
270  lSCMapKey << stdair::DEFAULT_SEGMENT_CABIN_VALUE_TYPE
271  << iSegmentCabin.describeKey();
272  const stdair::BlockIndex_T& lCabinValueIdx =
273  lGuillotineBlock.getBlockIndex (lSCMapKey.str());
274 
275  STDAIR_LOG_DEBUG ("Retrieve the unconstrained price-oriented demand");
276  retrieveUnconstrainedDemandForFirstDCP (lGuillotineBlock,
277  ioQEquivalentDemandVector,iFirstDCP,
278  lCabinValueIdx, iNbOfSegments,
279  iNbOfUsedSegments);
280  }
281 
282  // ////////////////////////////////////////////////////////////////////
284  (const stdair::GuillotineBlock& iGuillotineBlock,
285  UnconstrainedDemandVector_T& ioUnconstrainedDemandVector,
286  const stdair::DCP_T& iFirstDCP, const stdair::BlockIndex_T& iValueIdx,
287  const stdair::NbOfSegments_T& iNbOfSegments,
288  const stdair::NbOfSegments_T& iNbOfUsedSegments) {
289 
290  //TODO
291  stdair::NbOfSegments_T lSegBegin = iNbOfSegments - iNbOfUsedSegments;
292 
293  // Retrieve the snapshots of the corresponding booking value from the
294  // first DTD (usually 365) till the given iFirstDCP.
295  stdair::ConstSegmentCabinDTDRangeSnapshotView_T lRangeBookingView =
296  iGuillotineBlock.getConstSegmentCabinDTDRangeProductAndPriceOrientedBookingSnapshotView (lSegBegin, iNbOfSegments -1, iFirstDCP, stdair::DEFAULT_MAX_DTD);
297 
298  // Sum the bookings from the first day till the given iFirstDCP in order to
299  // get the supposing unconstrained demand for this period.
300  const stdair::ValueTypeIndexMap_T& lVTIdxMap =
301  iGuillotineBlock.getValueTypeIndexMap();
302  const unsigned int lNbOfValueTypes = lVTIdxMap.size();
303  for (int itSegment = 0; itSegment < iNbOfSegments-lSegBegin; ++itSegment) {
304  for (int i = iFirstDCP; i <= stdair::DEFAULT_MAX_DTD; ++i) {
305  stdair::NbOfRequests_T& lUncDemand =
306  ioUnconstrainedDemandVector.at(itSegment);
307  lUncDemand +=
308  lRangeBookingView[iValueIdx + itSegment*lNbOfValueTypes][i-iFirstDCP];
309  }
310  // STDAIR_LOG_NOTIFICATION (ioUnconstrainedDemandVector.at(itSegment)
311  // << ";" << itSegment);
312  }
313  }
314 
315  // ////////////////////////////////////////////////////////////////////
317  (const stdair::SegmentCabin& iSegmentCabin,
318  BookingClassUnconstrainedDemandVectorMap_T& ioBkgClassUncDemMap,
319  UnconstrainedDemandVector_T& ioQEquivalentDemandVector,
320  const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
321  const stdair::Date_T& iCurrentDate,
322  const stdair::NbOfSegments_T& iNbOfDepartedSegments) {
323 
324  // Retrieve the guillotine block.
325  const stdair::GuillotineBlock& lGuillotineBlock =
326  iSegmentCabin.getGuillotineBlock();
327 
328  // Build the historical booking holders for the product-oriented bookings
329  // of the casses and the Q-equivalent (price-oriented) bookings of the cabin
330  const stdair::NbOfSegments_T lNbOfUsableSegments = GuillotineBlockHelper::
331  getNbOfSegmentAlreadyPassedThisDTD (lGuillotineBlock, iDCPEnd,
332  iCurrentDate);
333 
334  // Parse the booking class list and unconstrain historical bookings.
335  for (BookingClassUnconstrainedDemandVectorMap_T::iterator itBCUDV =
336  ioBkgClassUncDemMap.begin(); itBCUDV != ioBkgClassUncDemMap.end();
337  ++itBCUDV) {
338  stdair::BookingClass* lBC_ptr = itBCUDV->first;
339  assert (lBC_ptr != NULL);
340  const stdair::MapKey_T& lBCKey = lBC_ptr->describeKey();
341  const stdair::BlockIndex_T& lBlockIdx =
342  lGuillotineBlock.getBlockIndex (lBCKey);
343  UnconstrainedDemandVector_T& lUncDemVector = itBCUDV->second;
344 
345  STDAIR_LOG_DEBUG ("Unconstrain product-oriented bookings for " << lBCKey);
346  unconstrainUsingMultiplicativePickUp (lGuillotineBlock, lUncDemVector,
347  iDCPBegin, iDCPEnd,
348  lNbOfUsableSegments, lBlockIdx,
349  iNbOfDepartedSegments);
350  }
351 
352  // Unconstrain the Q-equivalent bookings.
353  // Retrieve the block index of the segment-cabin.
354  std::ostringstream lSCMapKey;
355  lSCMapKey << stdair::DEFAULT_SEGMENT_CABIN_VALUE_TYPE
356  << iSegmentCabin.describeKey();
357  const stdair::BlockIndex_T& lCabinIdx =
358  lGuillotineBlock.getBlockIndex (lSCMapKey.str());
359 
360  STDAIR_LOG_DEBUG ("Unconstrain price-oriented bookings");
361  unconstrainUsingMultiplicativePickUp (lGuillotineBlock,
362  ioQEquivalentDemandVector,
363  iDCPBegin, iDCPEnd,
364  lNbOfUsableSegments, lCabinIdx,
365  iNbOfDepartedSegments,
366  iSegmentCabin, iCurrentDate);
367  }
368 
369  // ////////////////////////////////////////////////////////////////////
371  (const stdair::GuillotineBlock& iGuillotineBlock,
372  UnconstrainedDemandVector_T& ioUncDemVector,
373  const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
374  const stdair::NbOfSegments_T& iNbOfUsableSegments,
375  const stdair::BlockIndex_T& iBlockIdx,
376  const stdair::NbOfSegments_T& iNbOfDepartedSegments) {
377  // TODO:
378  stdair::NbOfSegments_T lSegBegin = 0;
379  if (iNbOfDepartedSegments > 52) {
380  lSegBegin = iNbOfDepartedSegments - 52;
381  }
382 
383  // Retrieve the gross daily booking and availability snapshots.
384  stdair::ConstSegmentCabinDTDRangeSnapshotView_T lBookingView =
385  iGuillotineBlock.getConstSegmentCabinDTDRangeProductAndPriceOrientedBookingSnapshotView (lSegBegin, iNbOfUsableSegments -1, iDCPEnd, iDCPBegin);
386  stdair::ConstSegmentCabinDTDRangeSnapshotView_T lAvlView =
387  iGuillotineBlock.getConstSegmentCabinDTDRangeAvailabilitySnapshotView (lSegBegin, iNbOfUsableSegments -1, iDCPEnd, iDCPBegin);
388 
389  // Browse the list of segments and build the historical booking holder.
390  const stdair::ValueTypeIndexMap_T& lVTIdxMap =
391  iGuillotineBlock.getValueTypeIndexMap();
392  const unsigned int lNbOfValueTypes = lVTIdxMap.size();
393  HistoricalBookingHolder lHBHolder;
394  std::vector<short> lDataIndexList;
395  for (short i = 0; i < iNbOfUsableSegments-lSegBegin; ++i) {
396  stdair::Flag_T lCensorshipFlag = false;
397  stdair::NbOfBookings_T lNbOfHistoricalBkgs = 0.0;
398  const short lNbOfDTDs = iDCPBegin - iDCPEnd + 1;
399 
400  // Parse the DTDs during the period
401  for (short j = 0; j < lNbOfDTDs; ++j) {
402  // Check if the data has been censored during this day.
403  // STDAIR_LOG_DEBUG ("i: " << i << ", NbOfValues: " << lNbOfValueTypes
404  // << ", BlockIdx: " << iBlockIdx << ", j: " << j);
405  if (lCensorshipFlag == false) {
406  if (lAvlView[i*lNbOfValueTypes + iBlockIdx][j] < 1.0) {
407  lCensorshipFlag = true;
408  }
409  }
410 
411  // Get the bookings of the day.
412  //STDAIR_LOG_DEBUG ("Bookings of the day: " << lBookingView[i*lNbOfValueTypes + iBlockIdx][j]);
413  lNbOfHistoricalBkgs += lBookingView[i*lNbOfValueTypes + iBlockIdx][j];
414  }
415 
416  // If there is no booking till now for this class and for this segment,
417  // there will be no unconstraining process.
418  stdair::NbOfRequests_T& lUncDemand = ioUncDemVector.at (i);
419  if (lUncDemand < 1.0) {
420  lUncDemand += lNbOfHistoricalBkgs;
421  } else {
422  double lBkgDemandFactor = lNbOfHistoricalBkgs / lUncDemand;
423  HistoricalBooking lHistoricalBkg (lBkgDemandFactor, lCensorshipFlag);
424  lHBHolder.addHistoricalBooking (lHistoricalBkg);
425  lDataIndexList.push_back (i);
426  }
427 
428  // DEBUG
429  STDAIR_LOG_DEBUG ("Historical bkgs: " << lNbOfHistoricalBkgs
430  << ", censored: " << lCensorshipFlag);
431  }
432 
433  // DEBUG
434  STDAIR_LOG_DEBUG ("Unconstrain by multiplicative pick-up using EM");
435 
436  // Unconstrain the booking figures
438 
439  // Update the unconstrained demand vector.
440  short i = 0;
441  for (std::vector<short>::iterator itIdx = lDataIndexList.begin();
442  itIdx != lDataIndexList.end(); ++itIdx, ++i) {
443  short lIdx = *itIdx;
444  stdair::NbOfRequests_T& lPastDemand = ioUncDemVector.at (lIdx);
445  const stdair::NbOfRequests_T& lUncDemandFactorOfThisPeriod =
446  lHBHolder.getUnconstrainedDemand (i);
447  lPastDemand *= (1+lUncDemandFactorOfThisPeriod);
448  }
449  }
450 
451  // ////////////////////////////////////////////////////////////////////
453  (const stdair::GuillotineBlock& iGuillotineBlock,
454  UnconstrainedDemandVector_T& ioUncDemVector,
455  const stdair::DCP_T& iDCPBegin, const stdair::DCP_T& iDCPEnd,
456  const stdair::NbOfSegments_T& iNbOfUsableSegments,
457  const stdair::BlockIndex_T& iBlockIdx,
458  const stdair::NbOfSegments_T& iNbOfDepartedSegments,
459  const stdair::SegmentCabin& iSegmentCabin,
460  const stdair::Date_T& iCurrentDate) {
461  // TODO:
462  stdair::NbOfSegments_T lSegBegin = 0;
463  if (iNbOfDepartedSegments > 52) {
464  lSegBegin = iNbOfDepartedSegments - 52;
465  }
466 
467  // Retrieve the gross daily booking and availability snapshots.
468  stdair::ConstSegmentCabinDTDRangeSnapshotView_T lBookingView =
469  iGuillotineBlock.getConstSegmentCabinDTDRangeProductAndPriceOrientedBookingSnapshotView (lSegBegin, iNbOfUsableSegments -1, iDCPEnd, iDCPBegin);
470  stdair::ConstSegmentCabinDTDRangeSnapshotView_T lAvlView =
471  iGuillotineBlock.getConstSegmentCabinDTDRangeAvailabilitySnapshotView (lSegBegin, iNbOfUsableSegments -1, iDCPEnd, iDCPBegin);
472 
473  // Browse the list of segments and build the historical booking holder.
474  const stdair::ValueTypeIndexMap_T& lVTIdxMap =
475  iGuillotineBlock.getValueTypeIndexMap();
476  const unsigned int lNbOfValueTypes = lVTIdxMap.size();
477  HistoricalBookingHolder lHBHolder;
478  std::vector<short> lDataIndexList;
479  for (short i = 0; i < iNbOfUsableSegments-lSegBegin; ++i) {
480  stdair::Flag_T lCensorshipFlag = false;
481  stdair::NbOfBookings_T lNbOfHistoricalBkgs = 0.0;
482  const short lNbOfDTDs = iDCPBegin - iDCPEnd + 1;
483 
484  // Parse the DTDs during the period
485  for (short j = 0; j < lNbOfDTDs; ++j) {
486  // Check if the data has been censored during this day.
487  // STDAIR_LOG_DEBUG ("i: " << i << ", NbOfValues: " << lNbOfValueTypes
488  // << ", BlockIdx: " << iBlockIdx << ", j: " << j);
489  if (lCensorshipFlag == false) {
490  if (lAvlView[i*lNbOfValueTypes + iBlockIdx][j] < 1.0) {
491  lCensorshipFlag = true;
492  }
493  }
494 
495  // Get the bookings of the day.
496  //STDAIR_LOG_DEBUG ("Bookings of the day: " << lBookingView[i*lNbOfValueTypes + iBlockIdx][j]);
497  lNbOfHistoricalBkgs += lBookingView[i*lNbOfValueTypes + iBlockIdx][j];
498  }
499 
500  // If there is no booking till now for this class and for this segment,
501  // there will be no unconstraining process.
502  stdair::NbOfRequests_T& lUncDemand = ioUncDemVector.at (i);
503  if (lUncDemand < 1.0) {
504  lUncDemand += lNbOfHistoricalBkgs;
505  } else {
506  double lBkgDemandFactor = lNbOfHistoricalBkgs / lUncDemand;
507  HistoricalBooking lHistoricalBkg (lBkgDemandFactor, lCensorshipFlag);
508  lHBHolder.addHistoricalBooking (lHistoricalBkg);
509  lDataIndexList.push_back (i);
510  }
511 
512  // DEBUG
513  STDAIR_LOG_DEBUG ("Historical bkgs: " << lNbOfHistoricalBkgs
514  << ", censored: " << lCensorshipFlag);
515  }
516 
517  // DEBUG
518  STDAIR_LOG_DEBUG ("Unconstrain by multiplicative pick-up");
519 
520  // Unconstrain the booking figures
522 
523  // Update the unconstrained demand vector.
524  // LOG
525  const stdair::SegmentDate& lSegmentDate = stdair::BomManager::
526  getParent<stdair::SegmentDate, stdair::SegmentCabin> (iSegmentCabin);
527  const stdair::FlightDate& lFlightDate = stdair::BomManager::
528  getParent<stdair::FlightDate, stdair::SegmentDate> (lSegmentDate);
529  const stdair::Date_T& lDepDate = lFlightDate.getDepartureDate();
530  const boost::gregorian::date_duration lDD = lDepDate - iCurrentDate;
531  const long lDTD = lDD.days();
532  stdair::Date_T lRefDate (2012, boost::gregorian::Jan, 01);
533 
534  short i = 0;
535  for (std::vector<short>::iterator itIdx = lDataIndexList.begin();
536  itIdx != lDataIndexList.end(); ++itIdx, ++i) {
537  short lIdx = *itIdx;
538  stdair::NbOfRequests_T& lPastDemand = ioUncDemVector.at (lIdx);
539  const stdair::NbOfRequests_T& lUncDemandFactorOfThisPeriod =
540  lHBHolder.getUnconstrainedDemand (i);
541  const double lUncDemThisPeriod =
542  lPastDemand * lUncDemandFactorOfThisPeriod;
543  lPastDemand *= (1+lUncDemandFactorOfThisPeriod);
544  if (lDepDate > lRefDate) {
545  const stdair::DateOffset_T lDateOffset (7 *(53 - lIdx) + 420);
546  const stdair::Date_T lHDate = lDepDate - lDateOffset;
547  STDAIR_LOG_NOTIFICATION (boost::gregorian::to_iso_string(lDepDate)
548  << ";" << lDTD << ";" << iDCPBegin << ";"
549  << iDCPEnd << ";"
550  << boost::gregorian::to_iso_string (lHDate)
551  << ";" << lUncDemThisPeriod);
552  }
553  }
554  }
555 
556  // ////////////////////////////////////////////////////////////////////
557  void Detruncator::
559  // We use two loops in this algorithm. The first one is for calculating the
560  // average of unconstrained data. The second one is fore calculating the
561  // average of unconstrained data and the constrained data which are higher
562  // than the first average.
563  short lNbOfUsedData = ioHBHolder.getNbOfUncensoredData();
564  if (lNbOfUsedData > 0) {
565  double lSumOfValues = 0.0;
566  const short lNbOfData = ioHBHolder.getNbOfFlights();
567 
568  // First loop
569  for (short i = 0; i < lNbOfData; ++i) {
570  if (ioHBHolder.getCensorshipFlag (i) == false) {
571  lSumOfValues += ioHBHolder.getHistoricalBooking (i);
572  }
573  }
574  double lFirstAverage = lSumOfValues / lNbOfUsedData;
575 
576  // Second loop
577  for (short i = 0; i < lNbOfData; ++i) {
578  if (ioHBHolder.getCensorshipFlag (i) == true) {
579  const stdair::NbOfBookings_T& lBkgs =
580  ioHBHolder.getHistoricalBooking (i);
581  if (lBkgs >= lFirstAverage) {
582  lSumOfValues += lBkgs;
583  ++lNbOfUsedData;
584  }
585  }
586  }
587  double lSecondAverage = lSumOfValues / lNbOfUsedData;
588 
589  // Last loop for updating the demand.
590  for (short i = 0; i < lNbOfData; ++i) {
591  if (ioHBHolder.getCensorshipFlag (i) == true) {
592  const stdair::NbOfBookings_T& lBkgs =
593  ioHBHolder.getHistoricalBooking (i);
594  if (lBkgs < lSecondAverage) {
595  ioHBHolder.setUnconstrainedDemand (lSecondAverage, i);
596  }
597  }
598  }
599  }
600  }
601 }
602