AirTSP Logo  1.01.0
C++ Simulated Airline Travel Solution Provider Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SegmentPathGenerator.cpp
Go to the documentation of this file.
1 // //////////////////////////////////////////////////////////////////////
2 // Import section
3 // //////////////////////////////////////////////////////////////////////
4 // STL
5 #include <cassert>
6 #include <vector>
7 // StdAir
8 #include <stdair/basic/BasConst_Inventory.hpp>
9 #include <stdair/bom/BomManager.hpp>
10 #include <stdair/bom/BomRoot.hpp>
11 #include <stdair/bom/Inventory.hpp>
12 #include <stdair/bom/FlightPeriod.hpp>
13 #include <stdair/bom/SegmentPeriod.hpp>
14 #include <stdair/factory/FacBomManager.hpp>
15 #include <stdair/service/Logger.hpp>
16 // AirTSP
21 
22 namespace AIRTSP {
23 
24  // ////////////////////////////////////////////////////////////////////
26  createSegmentPathNetwork (const stdair::BomRoot& iBomRoot) {
27 
28  // Build the list of single-segment segment path objects.
29  const stdair::InventoryList_T& lInventoryList =
30  stdair::BomManager::getList<stdair::Inventory> (iBomRoot);
31  for (stdair::InventoryList_T::const_iterator itInv = lInventoryList.begin();
32  itInv != lInventoryList.end(); ++itInv) {
33  const stdair::Inventory* lCurrentInventory_ptr = *itInv;
34  assert (lCurrentInventory_ptr != NULL);
35 
36  //
37  createSinglePaths (*lCurrentInventory_ptr);
38  }
39 
40  // Build the list of i-fixed-length segment path objects. In other words,
41  // build the whole segment path network.
42  for (stdair::NbOfSegments_T i = 2;
43  i <= stdair::MAXIMAL_NUMBER_OF_SEGMENTS_IN_OND; ++i) {
44  buildSegmentPathNetwork (iBomRoot, i);
45  }
46  }
47 
48  // ////////////////////////////////////////////////////////////////////
49  void SegmentPathGenerator::
50  createSinglePaths (const stdair::Inventory& iInventory) {
51 
52  const stdair::FlightPeriodList_T& lFlightPeriodList =
53  stdair::BomManager::getList<stdair::FlightPeriod> (iInventory);
54  for (stdair::FlightPeriodList_T::const_iterator itFlightPeriod =
55  lFlightPeriodList.begin();
56  itFlightPeriod != lFlightPeriodList.end(); ++itFlightPeriod) {
57  const stdair::FlightPeriod* lCurrentFlightPeriod_ptr = *itFlightPeriod;
58  assert (lCurrentFlightPeriod_ptr != NULL);
59 
60  //
61  createSinglePaths (*lCurrentFlightPeriod_ptr);
62  }
63  }
64 
65  // ////////////////////////////////////////////////////////////////////
66  void SegmentPathGenerator::
67  createSinglePaths (const stdair::FlightPeriod& iFlightPeriod) {
68 
69  const stdair::SegmentPeriodList_T& lSegmentPeriodList =
70  stdair::BomManager::getList<stdair::SegmentPeriod> (iFlightPeriod);
71  for (stdair::SegmentPeriodList_T::const_iterator itSegmentPeriod =
72  lSegmentPeriodList.begin();
73  itSegmentPeriod != lSegmentPeriodList.end(); ++itSegmentPeriod) {
74  stdair::SegmentPeriod* lCurrentSegmentPeriod_ptr = *itSegmentPeriod;
75  assert (lCurrentSegmentPeriod_ptr != NULL);
76 
77  //
78  createSinglePath (*lCurrentSegmentPeriod_ptr);
79  }
80  }
81 
82  // ////////////////////////////////////////////////////////////////////
83  void SegmentPathGenerator::
84  createSinglePath (stdair::SegmentPeriod& ioSegmentPeriod) {
85 
86  // Retrieve the BOM tree root
87  const stdair::AirportCode_T& lOrigin = ioSegmentPeriod.getBoardingPoint();
88  const stdair::FlightPeriod& lFlightPeriod =
89  stdair::BomManager::getParent<stdair::FlightPeriod> (ioSegmentPeriod);
90  const stdair::Inventory& lInventory =
91  stdair::BomManager::getParent<stdair::Inventory> (lFlightPeriod);
92  stdair::BomRoot& lBomRoot =
93  stdair::BomManager::getParent<stdair::BomRoot> (lInventory);
94 
95  // Retrieve the ReachableUniverse (if existing) which corresponds
96  // to the origin. If it does not exist, then create one.
97  ReachableUniverse* lReachableUniverse_ptr =
98  stdair::BomManager::getObjectPtr<ReachableUniverse> (lBomRoot, lOrigin);
99  if (lReachableUniverse_ptr == NULL) {
100  ReachableUniverseKey lKey (lOrigin);
101  lReachableUniverse_ptr =
103  stdair::FacBomManager::addToListAndMap (lBomRoot, *lReachableUniverse_ptr);
104  stdair::FacBomManager::linkWithParent (lBomRoot, *lReachableUniverse_ptr);
105  }
106  assert (lReachableUniverse_ptr != NULL);
107 
108  //
109  createSinglePath (*lReachableUniverse_ptr, ioSegmentPeriod);
110  }
111 
112  // ////////////////////////////////////////////////////////////////////
113  void SegmentPathGenerator::
114  createSinglePath (ReachableUniverse& ioReachableUniverse,
115  stdair::SegmentPeriod& ioSegmentPeriod) {
116 
117  const stdair::AirportCode_T& lDestination = ioSegmentPeriod.getOffPoint();
118 
119  // Retrieve the origin-destination set (if existing) which corresponds
120  // to the destination. If it does not exist, then create one.
121  OriginDestinationSet* lOriginDestinationSet_ptr =
122  stdair::BomManager::getObjectPtr<OriginDestinationSet>(ioReachableUniverse,
123  lDestination);
124  if (lOriginDestinationSet_ptr == NULL) {
125  OriginDestinationSetKey lKey (lDestination);
126 
127  lOriginDestinationSet_ptr =
129  stdair::FacBomManager::addToListAndMap (ioReachableUniverse,
130  *lOriginDestinationSet_ptr);
131  stdair::FacBomManager::linkWithParent (ioReachableUniverse,
132  *lOriginDestinationSet_ptr);
133  }
134  assert (lOriginDestinationSet_ptr != NULL);
135 
136  // Create a segment path period and add it to the corresponding
137  // origin-destination set and reachable-universe.
138  const stdair::FlightPeriod& lFlightPeriod =
139  stdair::BomManager::getParent<stdair::FlightPeriod> (ioSegmentPeriod);
140  const stdair::PeriodStruct& lPeriodOfFlight = lFlightPeriod.getPeriod();
141 
142  // The departure period of the segment is the departure period of
143  // the flight plus the boarding date offset of the segment.
144  const stdair::DateOffset_T& lBoardingDateOffset =
145  ioSegmentPeriod.getBoardingDateOffset();
146 
147  const stdair::PeriodStruct lPeriodOfSegment =
148  lPeriodOfFlight.addDateOffset (lBoardingDateOffset);
149 
150  const stdair::Duration_T& lBoardingTime = ioSegmentPeriod.getBoardingTime();
151  const stdair::Duration_T& lElapsed = ioSegmentPeriod.getElapsedTime();
152 
153  DateOffsetList_T lDateOffsetList;
154  const stdair::DateOffset_T lFirstDateOffset (0);
155  lDateOffsetList.push_back (lFirstDateOffset);
156 
157  const SegmentPathPeriodKey lSegmentPathKey (lPeriodOfSegment,
158  lBoardingTime, lElapsed,
159  lDateOffsetList, 1);
160 
161  SegmentPathPeriod& lSegmentPathPeriod =
162  stdair::FacBom<SegmentPathPeriod>::instance().create (lSegmentPathKey);
163 
170  addSegmentPathPeriod (ioReachableUniverse, lSegmentPathPeriod);
171 
172  // Link the SegmentPathPeriod object with its parent, namely
173  // OriginDestinationSet
174  stdair::FacBomManager::addToList (*lOriginDestinationSet_ptr,
175  lSegmentPathPeriod);
176  stdair::FacBomManager::linkWithParent (*lOriginDestinationSet_ptr,
177  lSegmentPathPeriod);
178 
179  // Link the SegmentPathPeriod and SegmentPeriod objects. Note that
180  // the SegmentPeriod object has already a parent, namely FlightPeriod.
181  stdair::FacBomManager::addToList (lSegmentPathPeriod,
182  ioSegmentPeriod);
183  }
184 
185  // ////////////////////////////////////////////////////////////////////
186  void SegmentPathGenerator::
187  addSegmentPathPeriod (ReachableUniverse& ioReachableUniverse,
188  const SegmentPathPeriod& iSegmentPathPeriod) {
189 
190  const stdair::NbOfSegments_T& lNbOfSegments =
191  iSegmentPathPeriod.getNbOfSegments();
192 
193  assert (lNbOfSegments > 0
194  && lNbOfSegments <= stdair::MAXIMAL_NUMBER_OF_SEGMENTS_IN_OND);
195 
196  // If needed, initialise the list of lists with empty fixed-length
197  // segment path period lists.
198 
199  SegmentPathPeriodListList_T& lSegmentPathPeriodListList =
200  ioReachableUniverse._segmentPathPeriodListList;
201  while (lSegmentPathPeriodListList.size() < lNbOfSegments) {
202  SegmentPathPeriodLightList_T lSegmentPathPeriodList;
203  lSegmentPathPeriodListList.push_back (lSegmentPathPeriodList);
204  }
205 
206  // Retrieve the i-fixed-length segment path period list (i = number of
207  // segments).
208  SegmentPathPeriodLightList_T& lSegmentPathPeriodList =
209  lSegmentPathPeriodListList.at (lNbOfSegments-1);
210 
211  // Add the SegmentPathPeriod to that fixed-length-path list.
212  lSegmentPathPeriodList.push_back (&iSegmentPathPeriod);
213  }
214 
215  // ////////////////////////////////////////////////////////////////////
216  void SegmentPathGenerator::
217  buildSegmentPathNetwork (const stdair::BomRoot& iBomRoot,
218  const stdair::NbOfSegments_T& lNbOfSegments) {
219 
225  const ReachableUniverseList_T& lReachableUniverseList =
226  stdair::BomManager::getList<ReachableUniverse> (iBomRoot);
227  for (ReachableUniverseList_T::const_iterator itReachableUniverse =
228  lReachableUniverseList.begin();
229  itReachableUniverse != lReachableUniverseList.end();
230  ++itReachableUniverse) {
231  ReachableUniverse* lReachableUniverse_ptr = *itReachableUniverse;
232  assert (lReachableUniverse_ptr != NULL);
233 
234  //
235  buildSegmentPathNetwork (*lReachableUniverse_ptr, lNbOfSegments);
236  }
237  }
238 
239  // ////////////////////////////////////////////////////////////////////
240  void SegmentPathGenerator::
241  buildSegmentPathNetwork (ReachableUniverse& ioReachableUniverse,
242  const stdair::NbOfSegments_T& iNbOfSegments) {
243 
244  // The goal of that method is to build the i-fixed-length
245  // segment path period objects, knowing that all the
246  // lower-fixed-length segment path period objects have already been
247  // built during the previous steps. Once an i-fixed-length
248  // segment path period object is created, it is added to the list of
249  // the (fixed-length segment path period object) lists.
250 
251  // Hence, at that iteration, by construction, the list of the
252  // (fixed-length segment path period object) lists should already get
253  // a size of i-1, if there were such possibilities (in terms of
254  // segment path period). In that case, at the end of the method, its
255  // size should be of i.
256 
257  // If the size of the list of the (fixed-length segment path period
258  // object) lists is (strictly) less than i-1, it means that that
259  // reachable universe has no more possibilities of destinations. We
260  // are thus done at that stage.
261  const SegmentPathPeriodListList_T& lSegmentPathPeriodListList =
262  ioReachableUniverse.getSegmentPathPeriodListList();
263  const unsigned short lNbOfSegments_m1 = iNbOfSegments - 1;
264  assert (lNbOfSegments_m1 >= 0);
265  if (lSegmentPathPeriodListList.size() < lNbOfSegments_m1) {
266  return;
267  }
268 
269  // Retrieve the (i-1)-fixed-length segment path period list (i = number of
270  // segments).
271 
272  // Note that a STL vector starts at 0, whereas the number of segments
273  // starts at 1. Hence, (i-1) for the length (in number of segments)
274  // corresponds to [iNbOfSegments-2] for the STL vector.
275 
276  // As the lSegmentPathPeriodListList may change during the next loop
277  // iterations (as some SegmentPathPeriod objects are created and linked to
278  // ReachableUniverse), we need to take the initial copy of that list.
279  const SegmentPathPeriodLightList_T lSegmentPathPeriodLightList_im1 =
280  lSegmentPathPeriodListList.at (iNbOfSegments-2);
281 
282  // Iterate on the (i-1)-fixed-length segment path period objects, in order
283  // to build a i-fixed-length segment path period objects.
284  // There are two steps:
285  // 1. Retrieve the airport-dates at a (i-1) length (in number of segments)
286  // of the origin airport-date.
287  // 2. From each of such (i-1) airport-date, add the single-segment pathes
288  // to the (i-1)-length pathes, so as to make i-length pathes.
289  for (SegmentPathPeriodLightList_T::const_iterator itSegmentPathPeriodList =
290  lSegmentPathPeriodLightList_im1.begin();
291  itSegmentPathPeriodList != lSegmentPathPeriodLightList_im1.end();
292  ++itSegmentPathPeriodList) {
293  const SegmentPathPeriod* lSegmentPathPeriod_im1_ptr =
294  *itSegmentPathPeriodList;
295  assert (lSegmentPathPeriod_im1_ptr != NULL);
296 
297  // Get the reachable-universe departing from the destination of
298  // the current segment path period.
299  const stdair::AirportCode_T& lDestination_im1 =
300  lSegmentPathPeriod_im1_ptr->getDestination();
301  const stdair::BomRoot& lBomRoot =
302  stdair::BomManager::getParent<stdair::BomRoot> (ioReachableUniverse);
303  const ReachableUniverse* lReachableUniverseFromDestination_im1_ptr =
304  stdair::BomManager::getObjectPtr<ReachableUniverse> (lBomRoot,
305  lDestination_im1);
306 
307  // If there is no ReachableUniverse corresponding to the destination (off
308  // point of the last SegmentDate), it means that the destination is
309  // an end point (no other SegmentDate is starting from there).
310  // Hence, there is nothing else to do for now for that (final)
311  // destination, and we can process the next (i-1)-segment path period.
312  if (lReachableUniverseFromDestination_im1_ptr == NULL) {
313  continue;
314  }
315  assert (lReachableUniverseFromDestination_im1_ptr != NULL);
316 
317  // Retrieve the single-segment segment path period list,
318  // so as to make a i-length SegmentPathPeriod.
320  lSegmentPathPeriodListListFromDestination_im1 =
321  lReachableUniverseFromDestination_im1_ptr->
322  getSegmentPathPeriodListList();
323  assert (lSegmentPathPeriodListListFromDestination_im1.size() >= 1);
324 
325  // As the lSegmentPathPeriodListListFromDestination_im1 may change during
326  // the next loop iterations (as some SegmentPathPeriod objects are
327  // created and linked to ReachableUniverse), we need to take the initial
328  // copy of that list.
329  const SegmentPathPeriodLightList_T lSingleSegmentPathPeriodLightListFromDestination_im1 =
330  lSegmentPathPeriodListListFromDestination_im1.at (0);
331 
332  for (SegmentPathPeriodLightList_T::const_iterator
333  itSegmentPathPeriodFromDestination_im1 =
334  lSingleSegmentPathPeriodLightListFromDestination_im1.begin();
335  itSegmentPathPeriodFromDestination_im1
336  != lSingleSegmentPathPeriodLightListFromDestination_im1.end();
337  ++itSegmentPathPeriodFromDestination_im1) {
338  const SegmentPathPeriod* lSingleSegmentPathPeriodFromDestination_im1_ptr=
339  *itSegmentPathPeriodFromDestination_im1;
340  assert (lSingleSegmentPathPeriodFromDestination_im1_ptr != NULL);
341 
342  // Check if the (i-1)-length segment path period can be fused with the
343  // single segment segment path period in order to create an i-length
344  // segment path period. The function will return a valid or non-valid
345  // segment path period key.
346 
347  // The two segment path period above can be fused (and will produce a
348  // valid new segment path period key) if:
349  // 1. A passenger can connect from the last segment of the
350  // first segment path and the first segment of the next segment path.
351  // These two segments should not create another segment.
352  // 2. There is no circle within the new segment path.
353  // 3. The intersection of the two periods is non-empty.
354  SegmentPathPeriodKey lSegmentPathPeriodKey_i =
355  lSegmentPathPeriod_im1_ptr->connectWithAnotherSegment (*lSingleSegmentPathPeriodFromDestination_im1_ptr);
356 
357  if (lSegmentPathPeriodKey_i.isValid () == false) {
358  continue;
359  }
360 
361  // Get the off point of the single-segment SegmentPathPeriod
362  // attached to the intermediate destination (im1). That off point is
363  // at a length i of the initial ReachableUniverse: (i-1) + 1.
364  const stdair::AirportCode_T& lDestination_i =
365  lSingleSegmentPathPeriodFromDestination_im1_ptr->getDestination();
366 
367  // Build the i-length SegmentPathPeriod
368  // Get the parameters of the last segment
369  stdair::SegmentPeriod* lSegmentPeriod_1_ptr =
370  lSingleSegmentPathPeriodFromDestination_im1_ptr->getFirstSegmentPeriod();
371  assert (lSegmentPeriod_1_ptr != NULL);
372 
373  // Calculate the number of airlines flown by the i-length
374  // segment path period
375  const stdair::FlightPeriod& lFlightPeriod = stdair::BomManager::
376  getParent<stdair::FlightPeriod> (*lSegmentPeriod_1_ptr);
377  const stdair::Inventory& lInventory =
378  stdair::BomManager::getParent<stdair::Inventory> (lFlightPeriod);
379  const stdair::AirlineCode_T& lAirlineCode_1 =lInventory.getAirlineCode();
380  stdair::NbOfAirlines_T lNbOfAirlines_i =
381  lSegmentPathPeriod_im1_ptr->getNbOfAirlines();
382  if (lSegmentPathPeriod_im1_ptr->isAirlineFlown(lAirlineCode_1) == false){
383  ++lNbOfAirlines_i;
384  }
385  lSegmentPathPeriodKey_i.setNbOfAirlines (lNbOfAirlines_i);
386 
387  // Create the new segment path and add it to the dedicated lists.
388  OriginDestinationSet* lOriginDestinationSet_ptr = stdair::BomManager::
389  getObjectPtr<OriginDestinationSet>(ioReachableUniverse,lDestination_i);
390  if (lOriginDestinationSet_ptr == NULL) {
391  OriginDestinationSetKey lKey (lDestination_i);
392  lOriginDestinationSet_ptr =
394  stdair::FacBomManager::addToListAndMap (ioReachableUniverse,
395  *lOriginDestinationSet_ptr);
396  stdair::FacBomManager::linkWithParent (ioReachableUniverse,
397  *lOriginDestinationSet_ptr);
398  }
399  assert (lOriginDestinationSet_ptr != NULL);
400 
401 
402  SegmentPathPeriod& lSegmentPathPeriod_i = stdair::
403  FacBom<SegmentPathPeriod>::instance().create (lSegmentPathPeriodKey_i);
404  stdair::FacBomManager::addToList (*lOriginDestinationSet_ptr,
405  lSegmentPathPeriod_i);
406  stdair::FacBomManager::linkWithParent (*lOriginDestinationSet_ptr,
407  lSegmentPathPeriod_i);
408 
409  // Clone the list of SegmentPeriod references of the given
410  // SegmentPathPeriod object (passed as the second parameter).
411  stdair::FacBomManager::
412  cloneHolder<stdair::SegmentPeriod> (lSegmentPathPeriod_i,
413  *lSegmentPathPeriod_im1_ptr);
414 
415 
416  // Add the SegmentPeriod reference to the dedicated list within
417  // the SegmentPathPeriod. Note that this must be done before
418  // the link between the SegmentPathPeriod and
419  // ReachableUniverse, as that latter method uses the number of
420  // segments within the SegmentPathPeriod object.
421  stdair::FacBomManager::addToList (lSegmentPathPeriod_i,
422  *lSegmentPeriod_1_ptr);
423 
431  addSegmentPathPeriod (ioReachableUniverse, lSegmentPathPeriod_i);
432  }
433  }
434  }
435 }