AirInv Logo  0.1.2
C++ Simulated Airline Inventory Management System library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GuillotineBlockHelper.cpp
Go to the documentation of this file.
1 // //////////////////////////////////////////////////////////////////////
2 // Import section
3 // //////////////////////////////////////////////////////////////////////
4 // STL
5 #include <cassert>
6 #include <cmath>
7 // StdAir
8 #include <stdair/basic/BasConst_Inventory.hpp>
9 #include <stdair/bom/BomRetriever.hpp>
10 #include <stdair/bom/BomManager.hpp>
11 #include <stdair/bom/SegmentDate.hpp>
12 #include <stdair/bom/SegmentCabin.hpp>
13 #include <stdair/bom/FareFamily.hpp>
14 #include <stdair/bom/BookingClass.hpp>
15 #include <stdair/bom/GuillotineBlock.hpp>
16 #include <stdair/service/Logger.hpp>
17 // AirInv
22 
23 namespace AIRINV {
24 
25  // ////////////////////////////////////////////////////////////////////
27  takeSnapshots (stdair::GuillotineBlock& ioGuillotineBlock,
28  const stdair::DateTime_T& iSnapshotTime) {
29  // Retrieve the segment-cabin index and take the snapshots for
30  // each segment-cabin.
31  const stdair::SegmentCabinIndexMap_T& lSegmentCabinIndexMap =
32  ioGuillotineBlock.getSegmentCabinIndexMap();
33  for (stdair::SegmentCabinIndexMap_T::const_iterator itSCIdx =
34  lSegmentCabinIndexMap.begin();
35  itSCIdx != lSegmentCabinIndexMap.end(); ++itSCIdx) {
36  const stdair::SegmentCabin* lSC_ptr = itSCIdx->first;
37  assert (lSC_ptr != NULL);
38  const stdair::BlockNumber_T& lSCIdx = itSCIdx->second;
39 
40  const stdair::Date_T& lSnapshotDate = iSnapshotTime.date();
41 
42  // Compare the date of the snapshot time and the departure date of
43  // the segment-cabin in order to verify the necescity of taking snapshots.
44  const stdair::SegmentDate& lSegmentDate =
45  stdair::BomManager::getParent<stdair::SegmentDate> (*lSC_ptr);
46  const stdair::Date_T& lDepartureDate = lSegmentDate.getBoardingDate();
47  const stdair::DateOffset_T lDateOffset = lDepartureDate - lSnapshotDate;
48  const stdair::DTD_T lDTD = lDateOffset.days() + 1;
49 
50  if (lDTD >= 0 && lDTD <= stdair::DEFAULT_MAX_DTD) {
52  takeSnapshots (ioGuillotineBlock, lDTD, *lSC_ptr, lSCIdx);
53  registerProductAndPriceOrientedBookings (ioGuillotineBlock,
54  lDTD, *lSC_ptr, lSCIdx);
55  }
56  }
57  }
58 
59  // ////////////////////////////////////////////////////////////////////
61  takeSnapshots (stdair::GuillotineBlock& ioGuillotineBlock,
62  const stdair::DTD_T& iDTD,
63  const stdair::SegmentCabin& iSegmentCabin,
64  const stdair::BlockNumber_T iSegmentCabinIdx) {
65 
66  // Extract the views for the corresponding DTD and segment-cabin.
67  stdair::SegmentCabinDTDSnapshotView_T lBookingView = ioGuillotineBlock.
68  getSegmentCabinDTDBookingSnapshotView (iSegmentCabinIdx,
69  iSegmentCabinIdx, iDTD);
70  stdair::SegmentCabinDTDSnapshotView_T lCancellationView = ioGuillotineBlock.
71  getSegmentCabinDTDCancellationSnapshotView (iSegmentCabinIdx,
72  iSegmentCabinIdx, iDTD);
73  stdair::SegmentCabinDTDSnapshotView_T lAvailabilityView = ioGuillotineBlock.
74  getSegmentCabinDTDAvailabilitySnapshotView (iSegmentCabinIdx,
75  iSegmentCabinIdx, iDTD);
76 
77  // Retrieve the block index of the segment-cabin.
78  std::ostringstream lSCMapKey;
79  lSCMapKey << stdair::DEFAULT_SEGMENT_CABIN_VALUE_TYPE
80  << iSegmentCabin.describeKey();
81  const stdair::BlockIndex_T& lCabinIdx =
82  ioGuillotineBlock.getBlockIndex (lSCMapKey.str());
83  lAvailabilityView[lCabinIdx] = iSegmentCabin.getAvailabilityPool();
84 
85 
86  // Browse the booking class list
87  const stdair::BookingClassList_T& lBCList =
88  stdair::BomManager::getList<stdair::BookingClass> (iSegmentCabin);
89  for (stdair::BookingClassList_T::const_iterator itBC = lBCList.begin();
90  itBC != lBCList.end(); ++itBC) {
91  const stdair::BookingClass* lBookingClass_ptr = *itBC;
92  assert (lBookingClass_ptr != NULL);
93 
94  // Retrieve the block index of the booking class.
95  const stdair::BlockIndex_T& lIdx =
96  ioGuillotineBlock.getBlockIndex (lBookingClass_ptr->describeKey());
97 
98  // DEBUG
99  // STDAIR_LOG_DEBUG ("Taking snapshot for "
100  // << iSegmentCabin.describeKey() << ", "
101  // << lBookingClass_ptr->describeKey()
102  // << ", DTD: " << iDTD << ", nb of bookings: "
103  // << lBookingClass_ptr->getNbOfBookings());
104 
105  // Write the snapshot.
106  lBookingView[lIdx]=lBookingClass_ptr->getNbOfBookings();
107  lCancellationView[lIdx] =
108  lBookingClass_ptr->getNbOfCancellations();
109  lAvailabilityView[lIdx] =
110  lBookingClass_ptr->getSegmentAvailability();
111  }
112  }
113 
114  // ////////////////////////////////////////////////////////////////////
115  void GuillotineBlockHelper::registerProductAndPriceOrientedBookings
116  (stdair::GuillotineBlock& ioGuillotineBlock, const stdair::DTD_T& iDTD,
117  const stdair::SegmentCabin& iSegmentCabin,
118  const stdair::BlockNumber_T iSegmentCabinIdx) {
119 
120  // Extract the views for the corresponding DTD and segment-cabin.
121  stdair::SegmentCabinDTDRangeSnapshotView_T lRangeBookingView =
122  ioGuillotineBlock.getSegmentCabinDTDRangeBookingSnapshotView (iSegmentCabinIdx, iSegmentCabinIdx, iDTD, iDTD + 1);
123  stdair::SegmentCabinDTDRangeSnapshotView_T lRangeCancellationView =
124  ioGuillotineBlock.getSegmentCabinDTDRangeCancellationSnapshotView (iSegmentCabinIdx, iSegmentCabinIdx, iDTD, iDTD + 1);
125  stdair::SegmentCabinDTDSnapshotView_T lProductAndPriceOrientedBookingView =
126  ioGuillotineBlock.getSegmentCabinDTDProductAndPriceOrientedBookingSnapshotView (iSegmentCabinIdx, iSegmentCabinIdx, iDTD);
127 
128  // Retrieve the block index of the segment-cabin.
129  std::ostringstream lSCMapKey;
130  lSCMapKey << stdair::DEFAULT_SEGMENT_CABIN_VALUE_TYPE
131  << iSegmentCabin.describeKey();
132  const stdair::BlockIndex_T& lCabinIdx =
133  ioGuillotineBlock.getBlockIndex (lSCMapKey.str());
134 
135  // Retrieve the lowest class and treat the number of gross
136  // bookings of this class the price oriented bookings.
137  const stdair::BookingClassList_T& lBCList =
138  stdair::BomManager::getList<stdair::BookingClass> (iSegmentCabin);
139  stdair::BookingClassList_T::const_reverse_iterator itBC = lBCList.rbegin();
140  assert (itBC != lBCList.rend());
141  stdair::BookingClass* lLowestClass_ptr = *itBC; ++itBC;
142  assert (lLowestClass_ptr != NULL);
143 
144  // Retrieve the block index of the booking class.
145  const stdair::BlockIndex_T& lClassIdx =
146  ioGuillotineBlock.getBlockIndex (lLowestClass_ptr->describeKey());
147 
148  // Compute the number of gross bookings for this class.
149  const stdair::NbOfBookings_T lNbOfNetBkgs =
150  lRangeBookingView[lClassIdx][0] - lRangeBookingView[lClassIdx][1];
151  const stdair::NbOfCancellations_T lNbOfCx =
152  lRangeCancellationView[lClassIdx][0]-lRangeCancellationView[lClassIdx][1];
153  const stdair::NbOfBookings_T lNbOfGrossBkgs = lNbOfNetBkgs + lNbOfCx;
154 
155  // Write this number of bookings to the price-oriented value.
156  lProductAndPriceOrientedBookingView[lCabinIdx] = lNbOfGrossBkgs;
157 
158  // Retrieve the lowest yield.
159  const stdair::Yield_T& lLowestYield = lLowestClass_ptr->getYield();
160 
161  // Boolean for "no lower class available" verification.
162  bool noLowerClassAvl = true;
163  if (lLowestClass_ptr->getSegmentAvailability() >= 1.0) {
164  noLowerClassAvl = false;
165  }
166 
167  // Retrieve the FRAT5 coefficient and compute the sell-up coef.
168  const double lFRAT5Coef = getFRAT5Coefficient (iDTD);
169  const double lSellUpCoef = -log(0.5) / (lFRAT5Coef - 1);
170 
171  // Browse the booking class list
172  for (; itBC != lBCList.rend(); ++itBC) {
173  const stdair::BookingClass* lBookingClass_ptr = *itBC;
174  assert (lBookingClass_ptr != NULL);
175 
176  // Retrieve the yield of the this class.
177  const stdair::Yield_T& lYield = lBookingClass_ptr->getYield();
178  assert (lYield > lLowestYield);
179 
180  // Retrieve the block index of the booking class.
181  const stdair::BlockIndex_T& lIdx =
182  ioGuillotineBlock.getBlockIndex (lBookingClass_ptr->describeKey());
183 
184  // Compute the number of gross bookings for this class.
185  const stdair::NbOfBookings_T lNetBkgs =
186  lRangeBookingView[lIdx][0] - lRangeBookingView[lIdx][1];
187  const stdair::NbOfCancellations_T lCx =
188  lRangeCancellationView[lIdx][0] - lRangeCancellationView[lIdx][1];
189  const stdair::NbOfBookings_T lGrossBkgs = lNetBkgs + lCx;
190 
191  // If there is a lower class available, these gross bookings
192  // will be considered product-oriented. Otherwise, they will be
193  // considered price-oriented
194  if (noLowerClassAvl == false) {
195  lProductAndPriceOrientedBookingView[lIdx] = lGrossBkgs;
196  } else {
197  // Convert the bookings to Q-equivalent bookings.
198  const stdair::NbOfBookings_T lQEquiBkgs =
199  lGrossBkgs / exp ((1.0 - lYield/lLowestYield) * lSellUpCoef);
200  lProductAndPriceOrientedBookingView[lCabinIdx] += lQEquiBkgs;
201 
202  if (lBookingClass_ptr->getSegmentAvailability() >= 1.0) {
203  noLowerClassAvl = false;
204  }
205  }
206  }
207  }
208 
209  // ////////////////////////////////////////////////////////////////////
210  double GuillotineBlockHelper::getFRAT5Coefficient (const stdair::DTD_T& iDTD){
211  FRAT5Curve_T::const_iterator itFRAT5 =
212  DEFAULT_PICKUP_FRAT5_CURVE.lower_bound (iDTD);
213  assert (itFRAT5 != DEFAULT_PICKUP_FRAT5_CURVE.end());
214 
215  if (itFRAT5 == DEFAULT_PICKUP_FRAT5_CURVE.begin()) {
216  return itFRAT5->second;
217  }
218 
219  assert (itFRAT5 != DEFAULT_PICKUP_FRAT5_CURVE.begin());
220  FRAT5Curve_T::const_iterator itNextFRAT5 = itFRAT5; --itNextFRAT5;
221 
222  const stdair::DTD_T& lPrevDTD = itFRAT5->first;
223  const stdair::DTD_T& lNextDTD = itNextFRAT5->first;
224  const double& lPrevFRAT5 = itFRAT5->second;
225  const double& lNextFRAT5 = itNextFRAT5->second;
226  assert (lPrevDTD > lNextDTD);
227 
228  double oFRAT5 = lPrevFRAT5
229  + (iDTD - lNextDTD) * (lNextFRAT5 - lPrevFRAT5) / (lPrevDTD - lNextDTD);
230 
231  return oFRAT5;
232  }
233 }