AirTSP Logo  1.01.14
C++ Simulated Airline Travel Solution Provider (TSP) Library
Loading...
Searching...
No Matches
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
22namespace 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 =
102 &stdair::FacBom<ReachableUniverse>::instance().create (lKey);
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 =
128 &stdair::FacBom<OriginDestinationSet>::instance().create (lKey);
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 =
393 &stdair::FacBom<OriginDestinationSet>::instance().create (lKey);
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}
Class representing the root of the schedule-related BOM tree.
static void createSegmentPathNetwork(const stdair::BomRoot &)
Class representing a segment/path.
std::vector< stdair::DateOffset_T > DateOffsetList_T
std::vector< const SegmentPathPeriod * > SegmentPathPeriodLightList_T
std::vector< SegmentPathPeriodLightList_T > SegmentPathPeriodListList_T
std::list< ReachableUniverse * > ReachableUniverseList_T