TraDemGen Logo  1.00.0
C++ Simulated Travel Demand Generation Library
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
DemandManager.cpp
Go to the documentation of this file.
1 // //////////////////////////////////////////////////////////////////////
2 // Import section
3 // //////////////////////////////////////////////////////////////////////
4 // STL
5 #include <cassert>
6 // Boost
7 #include <boost/make_shared.hpp>
8 // StdAir
9 #include <stdair/basic/ProgressStatusSet.hpp>
10 #include <stdair/basic/BasConst_Request.hpp>
11 #include <stdair/bom/BomManager.hpp>
12 #include <stdair/bom/EventStruct.hpp>
13 #include <stdair/bom/BookingRequestStruct.hpp>
14 #include <stdair/bom/TravelSolutionStruct.hpp>
15 #include <stdair/bom/CancellationStruct.hpp>
16 #include <stdair/factory/FacBom.hpp>
17 #include <stdair/factory/FacBomManager.hpp>
18 #include <stdair/service/Logger.hpp>
19 // SEvMgr
20 #include <sevmgr/SEVMGR_Service.hpp>
21 // TraDemGen
27 
28 namespace TRADEMGEN {
29 
30  // //////////////////////////////////////////////////////////////////////
31  void DemandManager::
32  buildSampleBomStd (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr,
33  stdair::RandomGeneration& ioSharedGenerator,
34  const POSProbabilityMass_T& iPOSProbMass) {
35  // Sanity check
36  assert (ioSEVMGR_ServicePtr != NULL);
37 
38  // Key of the demand stream
39  const stdair::AirportCode_T lOrigin ("SIN");
40  const stdair::AirportCode_T lDestination ("BKK");
41  const stdair::Date_T lDepDate (2011, 2, 14);
42  const stdair::CabinCode_T lCabin ("Y");
43 
44  //
45  const DemandStreamKey lDemandStreamKey (lOrigin, lDestination, lDepDate,
46  lCabin);
47 
48  // DEBUG
49  // STDAIR_LOG_DEBUG ("Demand stream key: " << lDemandStreamKey.describe());
50 
51  // Distribution for the number of requests
52  const stdair::MeanValue_T lDemandMean (10.0);
53  const stdair::StdDevValue_T lDemandStdDev (1.0);
54  const DemandDistribution lDemandDistribution (lDemandMean, lDemandStdDev);
55 
56  // Seed
57  const stdair::RandomSeed_T& lRequestDateTimeSeed =
58  generateSeed (ioSharedGenerator);
59  const stdair::RandomSeed_T& lDemandCharacteristicsSeed =
60  generateSeed (ioSharedGenerator);
61 
62  //
64  lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-330,
65  0));
66  lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-40,
67  0.2));
68  lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-20,
69  0.6));
70  lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-1,
71  1.0));
72  //
73  POSProbabilityMassFunction_T lPOSProbDist;
74  lPOSProbDist.insert (POSProbabilityMassFunction_T::value_type ("BKK", 0.3));
75  lPOSProbDist.insert (POSProbabilityMassFunction_T::value_type ("SIN", 0.7));
76  //
77  ChannelProbabilityMassFunction_T lChannelProbDist;
78  lChannelProbDist.insert (ChannelProbabilityMassFunction_T::value_type ("DF",
79  0.1));
80  lChannelProbDist.insert (ChannelProbabilityMassFunction_T::value_type ("DN",
81  0.3));
82  lChannelProbDist.insert (ChannelProbabilityMassFunction_T::value_type ("IF",
83  0.4));
84  lChannelProbDist.insert (ChannelProbabilityMassFunction_T::value_type ("IN",
85  0.2));
86  //
88  lTripProbDist.insert (TripTypeProbabilityMassFunction_T::value_type ("RO",
89  0.6));
90  lTripProbDist.insert (TripTypeProbabilityMassFunction_T::value_type ("RI",
91  0.2));
92  lTripProbDist.insert (TripTypeProbabilityMassFunction_T::value_type ("OW",
93  0.2));
94  //
96  lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(0,
97  0.1));
98  lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(1,
99  0.1));
100  lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(2,
101  .15));
102  lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(3,
103  .15));
104  lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(4,
105  .15));
106  lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(5,
107  .35));
108  //
110  lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("P",
111  0.01));
112  lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("G",
113  0.05));
114  lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("S",
115  0.15));
116  lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("M",
117  0.3));
118  lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("N",
119  0.49));
120  //
122  lPrefDepTimeProbDist.
123  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (6 * stdair::HOUR_CONVERTED_IN_SECONDS, 0));
124  lPrefDepTimeProbDist.
125  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (7 * stdair::HOUR_CONVERTED_IN_SECONDS,
126  0.1));
127  lPrefDepTimeProbDist.
128  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (9 * stdair::HOUR_CONVERTED_IN_SECONDS,
129  0.3));
130  lPrefDepTimeProbDist.
131  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (17 * stdair::HOUR_CONVERTED_IN_SECONDS,
132  0.4));
133  lPrefDepTimeProbDist.
134  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (19 * stdair::HOUR_CONVERTED_IN_SECONDS,
135  0.80));
136  lPrefDepTimeProbDist.
137  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (20 * stdair::HOUR_CONVERTED_IN_SECONDS,
138  0.95));
139  lPrefDepTimeProbDist.
140  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (22 * stdair::HOUR_CONVERTED_IN_SECONDS,
141  1));
142  //
143  ValueOfTimeContinuousDistribution_T lTimeValueProbDist;
144  lTimeValueProbDist.insert(ValueOfTimeContinuousDistribution_T::value_type(15,
145  0));
146  lTimeValueProbDist.insert(ValueOfTimeContinuousDistribution_T::value_type(60,
147  1));
148 
149  //
150  const stdair::WTP_T lWTP (1000.0);
151  const stdair::ChangeFeesRatio_T lChangeFees (0.5);
152  const stdair::Disutility_T lChangeFeeDisutility (50);
153  const stdair::NonRefundableRatio_T lNonRefundable (0.5);
154  const stdair::Disutility_T lNonRefundableDisutility (50);
155 
156 
157  // Delegate the call to the dedicated command
158  DemandStream& lDemandStream =
159  createDemandStream (ioSEVMGR_ServicePtr, lDemandStreamKey, lDTDProbDist,
160  lPOSProbDist, lChannelProbDist, lTripProbDist,
161  lStayProbDist, lFFProbDist,
162  lChangeFees, lChangeFeeDisutility,
163  lNonRefundable, lNonRefundableDisutility,
164  lPrefDepTimeProbDist,
165  lWTP, lTimeValueProbDist, lDemandDistribution,
166  ioSharedGenerator.getBaseGenerator(),
167  lRequestDateTimeSeed,
168  lDemandCharacteristicsSeed, iPOSProbMass);
169 
170  // Calculate the expected total number of events for the current
171  // demand stream
172  const stdair::NbOfRequests_T& lExpectedTotalNbOfEvents =
173  lDemandStream.getMeanNumberOfRequests();
174 
178  ioSEVMGR_ServicePtr->addStatus (stdair::EventType::BKG_REQ,
179  lExpectedTotalNbOfEvents);
180  }
181 
182  // //////////////////////////////////////////////////////////////////////
183  DemandStream& DemandManager::createDemandStream
184  (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr,
185  const DemandStreamKey& iKey,
186  const ArrivalPatternCumulativeDistribution_T& iArrivalPattern,
187  const POSProbabilityMassFunction_T& iPOSProbMass,
188  const ChannelProbabilityMassFunction_T& iChannelProbMass,
189  const TripTypeProbabilityMassFunction_T& iTripTypeProbMass,
190  const StayDurationProbabilityMassFunction_T& iStayDurationProbMass,
191  const FrequentFlyerProbabilityMassFunction_T& iFrequentFlyerProbMass,
192  const stdair::ChangeFeesRatio_T& iChangeFeeProb,
193  const stdair::Disutility_T& iChangeFeeDisutility,
194  const stdair::NonRefundableRatio_T& iNonRefundableProb,
195  const stdair::Disutility_T& iNonRefundableDisutility,
196  const PreferredDepartureTimeContinuousDistribution_T& iPreferredDepartureTimeContinuousDistribution,
197  const stdair::WTP_T& iMinWTP,
198  const ValueOfTimeContinuousDistribution_T& iValueOfTimeContinuousDistribution,
199  const DemandDistribution& iDemandDistribution,
200  stdair::BaseGenerator_T& ioSharedGenerator,
201  const stdair::RandomSeed_T& iRequestDateTimeSeed,
202  const stdair::RandomSeed_T& iDemandCharacteristicsSeed,
203  const POSProbabilityMass_T& iDefaultPOSProbablityMass) {
204 
205  // Sanity check
206  assert (ioSEVMGR_ServicePtr != NULL);
207 
208  //
209  DemandStream& oDemandStream =
210  stdair::FacBom<DemandStream>::instance().create (iKey);
211 
212  oDemandStream.setAll (iArrivalPattern, iPOSProbMass,
213  iChannelProbMass, iTripTypeProbMass,
214  iStayDurationProbMass, iFrequentFlyerProbMass,
215  iChangeFeeProb, iChangeFeeDisutility,
216  iNonRefundableProb, iNonRefundableDisutility,
217  iPreferredDepartureTimeContinuousDistribution,
218  iMinWTP, iValueOfTimeContinuousDistribution,
219  iDemandDistribution, ioSharedGenerator,
220  iRequestDateTimeSeed, iDemandCharacteristicsSeed,
221  iDefaultPOSProbablityMass);
222 
223  ioSEVMGR_ServicePtr->addEventGenerator (oDemandStream);
224 
225  return oDemandStream;
226  }
227 
228  // //////////////////////////////////////////////////////////////////////
229  void DemandManager::
230  createDemandCharacteristics (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr,
231  stdair::RandomGeneration& ioSharedGenerator,
232  const POSProbabilityMass_T& iPOSProbMass,
233  const DemandStruct& iDemand) {
234  // Sanity check
235  assert (ioSEVMGR_ServicePtr != NULL);
236 
237  //
238  stdair::BaseGenerator_T& lSharedGenerator =
239  ioSharedGenerator.getBaseGenerator();
240 
241  // Parse the date period and DoW and generate demand characteristics.
242  const stdair::DatePeriod_T lDateRange = iDemand._dateRange;
243  for (boost::gregorian::day_iterator itDate = lDateRange.begin();
244  itDate != lDateRange.end(); ++itDate) {
245  const stdair::Date_T& currentDate = *itDate;
246 
247  // Retrieve, for the current day, the Day-Of-the-Week (thanks to Boost)
248  const unsigned short currentDoW = currentDate.day_of_week().as_number();
249 
250  // The demand structure stores which Days (-Of-the-Week) are
251  // active within the week. For each day (Mon., Tue., etc.), a boolean
252  // states whether the Flight is active for that day.
253  const stdair::DoWStruct& lDoWList = iDemand._dow;
254  const bool isDoWActive = lDoWList.getStandardDayOfWeek (currentDoW);
255 
256  if (isDoWActive == true) {
257  const DemandStreamKey lDemandStreamKey (iDemand._origin,
258  iDemand._destination,
259  currentDate,
260  iDemand._prefCabin);
261  // DEBUG
262  // STDAIR_LOG_DEBUG ("Demand stream key: " << lDemandStreamKey.describe());
263 
264  //
265  const DemandDistribution lDemandDistribution (iDemand._demandMean,
266  iDemand._demandStdDev);
267 
268  // Seed
269  const stdair::RandomSeed_T& lRequestDateTimeSeed =
270  generateSeed (ioSharedGenerator);
271  const stdair::RandomSeed_T& lDemandCharacteristicsSeed =
272  generateSeed (ioSharedGenerator);
273 
274  // Delegate the call to the dedicated command
275  DemandStream& lDemandStream =
276  createDemandStream (ioSEVMGR_ServicePtr, lDemandStreamKey,
277  iDemand._dtdProbDist, iDemand._posProbDist,
278  iDemand._channelProbDist,
279  iDemand._tripProbDist,
280  iDemand._stayProbDist, iDemand._ffProbDist,
281  iDemand._changeFeeProb,
282  iDemand._changeFeeDisutility,
283  iDemand._nonRefundableProb,
284  iDemand._nonRefundableDisutility,
285  iDemand._prefDepTimeProbDist,
286  iDemand._minWTP,
287  iDemand._timeValueProbDist,
288  lDemandDistribution, lSharedGenerator,
289  lRequestDateTimeSeed,
290  lDemandCharacteristicsSeed,
291  iPOSProbMass);
292 
293  // Calculate the expected total number of events for the current
294  // demand stream
295  const stdair::NbOfRequests_T& lExpectedTotalNbOfEvents =
296  lDemandStream.getMeanNumberOfRequests();
297 
302  ioSEVMGR_ServicePtr->addStatus (stdair::EventType::BKG_REQ,
303  lExpectedTotalNbOfEvents);
304  }
305  }
306  }
307 
308  // ////////////////////////////////////////////////////////////////////
309  stdair::RandomSeed_T DemandManager::
310  generateSeed (stdair::RandomGeneration& ioSharedGenerator) {
311  stdair::RealNumber_T lVariateUnif = ioSharedGenerator() * 1e9;
312  stdair::RandomSeed_T oSeed = static_cast<stdair::RandomSeed_T>(lVariateUnif);
313  return oSeed;
314  }
315 
316  // ////////////////////////////////////////////////////////////////////
317  const bool DemandManager::
318  stillHavingRequestsToBeGenerated (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr,
319  const stdair::DemandStreamKeyStr_T& iKey,
320  stdair::ProgressStatusSet& ioPSS,
321  const stdair::DemandGenerationMethod& iDemandGenerationMethod) {
322  // Sanity check
323  assert (ioSEVMGR_ServicePtr != NULL);
324 
325  // Retrieve the DemandStream which corresponds to the given key.
326  const DemandStream& lDemandStream =
327  ioSEVMGR_ServicePtr->getEventGenerator<DemandStream,stdair::DemandStreamKeyStr_T>(iKey);
328 
329  // Retrieve the progress status of the demand stream.
330  stdair::ProgressStatus
331  lProgressStatus (lDemandStream.getNumberOfRequestsGeneratedSoFar(),
332  lDemandStream.getMeanNumberOfRequests(),
333  lDemandStream.getTotalNumberOfRequestsToBeGenerated());
334  ioPSS.setSpecificGeneratorStatus (lProgressStatus, iKey);
335 
336  return lDemandStream.stillHavingRequestsToBeGenerated (iDemandGenerationMethod);
337  }
338 
339  // ////////////////////////////////////////////////////////////////////
340  stdair::BookingRequestPtr_T DemandManager::
341  generateNextRequest (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr,
342  stdair::RandomGeneration& ioGenerator,
343  const stdair::DemandStreamKeyStr_T& iKey,
344  const stdair::DemandGenerationMethod& iDemandGenerationMethod) {
345  // Sanity check
346  assert (ioSEVMGR_ServicePtr != NULL);
347 
348  // Retrieve the DemandStream which corresponds to the given key.
349  DemandStream& lDemandStream =
350  ioSEVMGR_ServicePtr->getEventGenerator<DemandStream,stdair::DemandStreamKeyStr_T>(iKey);
351 
352  // Generate the next booking request
353  stdair::BookingRequestPtr_T lBookingRequest =
354  lDemandStream.generateNextRequest (ioGenerator,
355  iDemandGenerationMethod);
356 
357  const stdair::DateTime_T& lBookingRequestDateTime =
358  lBookingRequest->getRequestDateTime();
359  const stdair::Date_T& lBookingRequestDate =
360  lBookingRequestDateTime.date();
361  const stdair::Duration_T& lBookingRequestTime =
362  lBookingRequestDateTime.time_of_day();
363  const stdair::Date_T& lPreferedDepartureDate =
364  lBookingRequest->getPreferedDepartureDate();
365  const stdair::Duration_T& lPreferedDepartureTime =
366  lBookingRequest->getPreferredDepartureTime();
367 
368  if ((lPreferedDepartureDate > lBookingRequestDate) ||
369  (lPreferedDepartureDate == lBookingRequestDate &&
370  lPreferedDepartureTime > lBookingRequestTime)) {
371 
372  // Create an event structure
373  stdair::EventStruct lEventStruct (stdair::EventType::BKG_REQ,
374  lBookingRequest);
375 
383  ioSEVMGR_ServicePtr->addEvent (lEventStruct);
384 
385  } else {
386 
387  // Update the expected number of eventss for the given event type (i.e.,
388  // booking request)
389  stdair::Count_T lCurrentBRNumber =
390  ioSEVMGR_ServicePtr->getActualTotalNumberOfEventsToBeGenerated (stdair::EventType::BKG_REQ);
391  lCurrentBRNumber--;
392  ioSEVMGR_ServicePtr->updateStatus (stdair::EventType::BKG_REQ, lCurrentBRNumber);
393 
394  }
395 
396  return lBookingRequest;
397  }
398 
399  // ////////////////////////////////////////////////////////////////////
400  stdair::Count_T DemandManager::
401  generateFirstRequests (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr,
402  stdair::RandomGeneration& ioGenerator,
403  const stdair::DemandGenerationMethod& iDemandGenerationMethod) {
404  // Sanity check
405  assert (ioSEVMGR_ServicePtr != NULL);
406 
407  // Actual total number of events to be generated
408  stdair::NbOfRequests_T lActualTotalNbOfEvents = 0.0;
409 
410  // Retrieve the DemandStream list
411  const DemandStreamList_T& lDemandStreamList =
412  ioSEVMGR_ServicePtr->getEventGeneratorList<DemandStream>();
413 
414  for (DemandStreamList_T::const_iterator itDemandStream =
415  lDemandStreamList.begin();
416  itDemandStream != lDemandStreamList.end(); ++itDemandStream) {
417  DemandStream* lDemandStream_ptr = *itDemandStream;
418  assert (lDemandStream_ptr != NULL);
419 
420  lDemandStream_ptr->setBoolFirstDateTimeRequest(true);
421 
422  // Calculate the expected total number of events for the current
423  // demand stream
424  const stdair::NbOfRequests_T& lActualNbOfEvents =
425  lDemandStream_ptr->getTotalNumberOfRequestsToBeGenerated();
426  lActualTotalNbOfEvents += lActualNbOfEvents;
427 
428  // Retrieve the key of the demand stream
429  const DemandStreamKey& lKey = lDemandStream_ptr->getKey();
430 
431  // Check whether there are still booking requests to be generated
432  const bool stillHavingRequestsToBeGenerated =
433  lDemandStream_ptr->stillHavingRequestsToBeGenerated (iDemandGenerationMethod);
434 
435  if (stillHavingRequestsToBeGenerated) {
436  // Generate the next event (booking request), and insert it
437  // into the event queue
438  generateNextRequest (ioSEVMGR_ServicePtr, ioGenerator,
439  lKey.toString(),
440  iDemandGenerationMethod);
441  }
442  }
443 
444  // Update the progress status for the given event type (i.e.,
445  // booking request)
446  ioSEVMGR_ServicePtr->updateStatus (stdair::EventType::BKG_REQ,
447  lActualTotalNbOfEvents);
448 
449  // Retrieve the actual total number of events to be generated
450  const stdair::Count_T oTotalNbOfEvents = std::floor (lActualTotalNbOfEvents);
451 
452  //
453  return oTotalNbOfEvents;
454  }
455 
456  // ////////////////////////////////////////////////////////////////////
457  void DemandManager::reset (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr,
458  stdair::BaseGenerator_T& ioShareGenerator) {
459  // Sanity check
460  assert (ioSEVMGR_ServicePtr != NULL);
461 
462  // TODO: check whether it is really necessary to destroy the
463  // objects manually. Indeed, FacSupervisor::cleanAll() should
464  // destroy any BOM object.
465 
466  // Reset all the DemandStream objects
467  const DemandStreamList_T& lDemandStreamList =
468  ioSEVMGR_ServicePtr->getEventGeneratorList<DemandStream>();
469  for (DemandStreamList_T::const_iterator itDS = lDemandStreamList.begin();
470  itDS != lDemandStreamList.end(); ++itDS) {
471  DemandStream* lCurrentDS_ptr = *itDS;
472  assert (lCurrentDS_ptr != NULL);
473 
474  lCurrentDS_ptr->reset (ioShareGenerator);
475  }
476 
484  ioSEVMGR_ServicePtr->reset();
485  }
486 
487  // ////////////////////////////////////////////////////////////////////
488  bool DemandManager::
489  generateCancellation (stdair::RandomGeneration& ioGenerator,
490  const stdair::TravelSolutionStruct& iTravelSolution,
491  const stdair::PartySize_T& iPartySize,
492  const stdair::DateTime_T& iRequestTime,
493  const stdair::Date_T& iDepartureDate,
494  stdair::EventStruct& ioEventStruct) {
495 
496  // Draw a random number to decide if we generate a
497  // cancellation. For instance, the probability will be hardcoded.
498  // The cancellation time will be generated uniformly.
499  double lRandomNumber = ioGenerator();
500 
501  if (lRandomNumber >= 0.05) {
502  return false;
503  }
504  lRandomNumber /= 0.05;
505 
506  // Hardcode the latest cancellation time.
507  const stdair::Time_T lMidNight =
508  boost::posix_time::hours (0);
509  const stdair::DateTime_T lDepartureDateTime =
510  boost::posix_time::ptime (iDepartureDate, lMidNight);
511 
512  // Time to departure.
513  const stdair::Duration_T lTimeToDeparture = lDepartureDateTime-iRequestTime;
514 
515  // Cancellation time to departure
516  const long lTimeToDepartureInSeconds = lTimeToDeparture.total_seconds();
517  const long lCancellationTimeToDepartureInSeconds =
518  static_cast<long> (lTimeToDepartureInSeconds * lRandomNumber);
519  const stdair::Duration_T lCancellationTimeToDeparture (0, 0, lCancellationTimeToDepartureInSeconds);
520 
521  // Cancellation time
522  const stdair::DateTime_T lCancellationTime =
523  lDepartureDateTime - lCancellationTimeToDeparture;
524  const stdair::Duration_T lTimeBetweenCancellationAndTheRequest =
525  lCancellationTime - iRequestTime;
526 
527  if (lTimeBetweenCancellationAndTheRequest.is_negative() == true) {
528  return false;
529  }
530 
531  // Build the list of Class ID's.
532  stdair::BookingClassIDList_T lClassIDList;
533 
534  const stdair::ClassObjectIDMapHolder_T& lClassObjectIDMapHolder =
535  iTravelSolution.getClassObjectIDMapHolder();
536  const stdair::FareOptionStruct& lChosenFareOption =
537  iTravelSolution.getChosenFareOption ();
538  const stdair::ClassList_StringList_T& lClassPath =
539  lChosenFareOption.getClassPath();
540  const stdair::SegmentPath_T& lSegmentPath =
541  iTravelSolution.getSegmentPath();
542  stdair::ClassList_StringList_T::const_iterator itClassKeyList =
543  lClassPath.begin();
544  for (stdair::ClassObjectIDMapHolder_T::const_iterator itClassObjectIDMap =
545  lClassObjectIDMapHolder.begin();
546  itClassObjectIDMap != lClassObjectIDMapHolder.end();
547  ++itClassObjectIDMap, ++itClassKeyList) {
548  const stdair::ClassObjectIDMap_T& lClassObjectIDMap = *itClassObjectIDMap;
549 
550  // TODO: Remove this hard-coded part.
551  std::ostringstream ostr;
552  const stdair::ClassList_String_T& lClassList = *itClassKeyList;
553  assert (lClassList.empty() == false);
554 
555  ostr << lClassList.at(0);
556  const stdair::ClassCode_T lClassCode (ostr.str());
557 
558  stdair::ClassObjectIDMap_T::const_iterator itClassID =
559  lClassObjectIDMap.find (lClassCode);
560  assert (itClassID != lClassObjectIDMap.end());
561  const stdair::BookingClassID_T& lClassID = itClassID->second;
562 
563  lClassIDList.push_back (lClassID);
564 
565 
566  }
567 
568  // Create the cancellation.
569  stdair::CancellationStruct lCancellationStruct (lSegmentPath,
570  lClassIDList,
571  iPartySize,
572  lCancellationTime);
573 
574  stdair::CancellationPtr_T lCancellation_ptr =
575  boost::make_shared<stdair::CancellationStruct> (lCancellationStruct);
576 
577  // Create an event structure
578  stdair::EventStruct lEventStruct (stdair::EventType::CX, lCancellation_ptr);
579  ioEventStruct = lEventStruct;
580 
581  return true;
582  }
583 
584  // //////////////////////////////////////////////////////////////////////
585  void DemandManager::
586  buildSampleBom (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr,
587  stdair::RandomGeneration& ioSharedGenerator,
588  const POSProbabilityMass_T& iPOSProbMass) {
589  // Sanity check
590  assert (ioSEVMGR_ServicePtr != NULL);
591 
592  //
594  lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-330,
595  0));
596  lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-150,
597  0.1));
598  lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-92,
599  0.2));
600  lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-55,
601  0.3));
602  lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-34,
603  0.4));
604  lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-21,
605  0.5));
606  lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-12,
607  0.6));
608  lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-6,
609  0.7));
610  lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-3,
611  0.8));
612  lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-1,
613  0.9));
614  lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(0,
615  1.0));
616 
617  //
618  ChannelProbabilityMassFunction_T lChannelProbDist;
619  lChannelProbDist.insert (ChannelProbabilityMassFunction_T::value_type ("DF",
620  0.0));
621  lChannelProbDist.insert (ChannelProbabilityMassFunction_T::value_type ("DN",
622  0.0));
623  lChannelProbDist.insert (ChannelProbabilityMassFunction_T::value_type ("IF",
624  0.0));
625  lChannelProbDist.insert (ChannelProbabilityMassFunction_T::value_type ("IN",
626  1.0));
627 
628  //
629  TripTypeProbabilityMassFunction_T lTripProbDist;
630  lTripProbDist.insert (TripTypeProbabilityMassFunction_T::value_type ("RO",
631  0.0));
632  lTripProbDist.insert (TripTypeProbabilityMassFunction_T::value_type ("RI",
633  0.0));
634  lTripProbDist.insert (TripTypeProbabilityMassFunction_T::value_type ("OW",
635  1.0));
636 
637  //
639  lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(0,
640  0.1));
641  lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(1,
642  0.1));
643  lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(2,
644  .15));
645  lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(3,
646  .15));
647  lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(4,
648  .15));
649  lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(5,
650  .35));
651 
652  //
654  lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("P",
655  0.1));
656  lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("G",
657  0.01));
658  lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("S",
659  0.09));
660  lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("M",
661  0.4));
662  lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("N",
663  0.4));
664 
665  //
666  ValueOfTimeContinuousDistribution_T lTimeValueProbDist;
667  lTimeValueProbDist.insert(ValueOfTimeContinuousDistribution_T::value_type(15,
668  0));
669  lTimeValueProbDist.insert(ValueOfTimeContinuousDistribution_T::value_type(60,
670  1));
671 
672  /*===================================================================================*/
673 
674  // Key of the demand stream
675  const stdair::AirportCode_T lSINOrigin ("SIN");
676  const stdair::AirportCode_T lBKKDestination ("BKK");
677  const stdair::Date_T lDepDate (2010, 2, 8);
678  const stdair::CabinCode_T lCabin ("Y");
679 
680  //
681  const DemandStreamKey lSINBKKDemandStreamKey (lSINOrigin, lBKKDestination, lDepDate,
682  lCabin);
683 
684  // DEBUG
685  // STDAIR_LOG_DEBUG ("Demand stream key: " << lDemandStreamKey.describe());
686 
687  // Distribution for the number of requests
688  const stdair::MeanValue_T lSINBKKDemandMean (60.0);
689  const stdair::StdDevValue_T lSINBKKDemandStdDev (4.0);
690  const DemandDistribution lSINBKKDemandDistribution (lSINBKKDemandMean, lSINBKKDemandStdDev);
691 
692  // Seed
693  const stdair::RandomSeed_T& lSINBKKRequestDateTimeSeed =
694  generateSeed (ioSharedGenerator);
695  const stdair::RandomSeed_T& lSINBKKDemandCharacteristicsSeed =
696  generateSeed (ioSharedGenerator);
697 
698 
699  //
700  POSProbabilityMassFunction_T lSINBKKPOSProbDist;
701  lSINBKKPOSProbDist.insert (POSProbabilityMassFunction_T::value_type ("SIN", 1.0));
702  lSINBKKPOSProbDist.insert (POSProbabilityMassFunction_T::value_type ("BKK", 0.0));
703 
704  //
705  PreferredDepartureTimeContinuousDistribution_T lSINPrefDepTimeProbDist;
706  lSINPrefDepTimeProbDist.
707  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (6 * stdair::HOUR_CONVERTED_IN_SECONDS, 0));
708  lSINPrefDepTimeProbDist.
709  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (8 * stdair::HOUR_CONVERTED_IN_SECONDS,
710  0.7));
711  lSINPrefDepTimeProbDist.
712  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (10 * stdair::HOUR_CONVERTED_IN_SECONDS,
713  0.8));
714  lSINPrefDepTimeProbDist.
715  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (12 * stdair::HOUR_CONVERTED_IN_SECONDS,
716  0.9));
717  lSINPrefDepTimeProbDist.
718  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (14 * stdair::HOUR_CONVERTED_IN_SECONDS,
719  1.0));
720 
721  //
722  const stdair::WTP_T lSINBKKWTP (400.0);
723  const stdair::ChangeFeesRatio_T lChangeFees (0.5);
724  const stdair::Disutility_T lChangeFeeDisutility (50);
725  const stdair::NonRefundableRatio_T lNonRefundable (0.5);
726  const stdair::Disutility_T lNonRefundableDisutility (50);
727 
728 
729  // Delegate the call to the dedicated command
730  DemandStream& lSINBKKDemandStream =
731  createDemandStream (ioSEVMGR_ServicePtr, lSINBKKDemandStreamKey, lDTDProbDist,
732  lSINBKKPOSProbDist, lChannelProbDist, lTripProbDist,
733  lStayProbDist, lFFProbDist,
734  lChangeFees, lChangeFeeDisutility,
735  lNonRefundable, lNonRefundableDisutility,
736  lSINPrefDepTimeProbDist,
737  lSINBKKWTP, lTimeValueProbDist,
738  lSINBKKDemandDistribution,
739  ioSharedGenerator.getBaseGenerator(),
740  lSINBKKRequestDateTimeSeed,
741  lSINBKKDemandCharacteristicsSeed, iPOSProbMass);
742 
743  // Calculate the expected total number of events for the current
744  // demand stream
745  const stdair::NbOfRequests_T& lSINBKKExpectedNbOfEvents =
746  lSINBKKDemandStream.getMeanNumberOfRequests();
747 
748  /*===================================================================================*/
749 
750  // Key of the demand stream
751  const stdair::AirportCode_T lBKKOrigin ("BKK");
752  const stdair::AirportCode_T lHKGDestination ("HKG");
753 
754  //
755  const DemandStreamKey lBKKHKGDemandStreamKey (lBKKOrigin, lHKGDestination, lDepDate,
756  lCabin);
757 
758  // DEBUG
759  // STDAIR_LOG_DEBUG ("Demand stream key: " << lDemandStreamKey.describe());
760 
761  // Distribution for the number of requests
762  const stdair::MeanValue_T lBKKHKGDemandMean (60.0);
763  const stdair::StdDevValue_T lBKKHKGDemandStdDev (4.0);
764  const DemandDistribution lBKKHKGDemandDistribution (lBKKHKGDemandMean, lBKKHKGDemandStdDev);
765 
766  // Seed
767  const stdair::RandomSeed_T& lBKKHKGRequestDateTimeSeed =
768  generateSeed (ioSharedGenerator);
769  const stdair::RandomSeed_T& lBKKHKGDemandCharacteristicsSeed =
770  generateSeed (ioSharedGenerator);
771 
772 
773  //
774  POSProbabilityMassFunction_T lBKKHKGPOSProbDist;
775  lBKKHKGPOSProbDist.insert (POSProbabilityMassFunction_T::value_type ("BKK", 1.0));
776  lBKKHKGPOSProbDist.insert (POSProbabilityMassFunction_T::value_type ("HKG", 0.0));
777 
778  //
779  PreferredDepartureTimeContinuousDistribution_T lBKKPrefDepTimeProbDist;
780  lBKKPrefDepTimeProbDist.
781  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (8 * stdair::HOUR_CONVERTED_IN_SECONDS, 0));
782  lBKKPrefDepTimeProbDist.
783  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (10 * stdair::HOUR_CONVERTED_IN_SECONDS,
784  0.2));
785  lBKKPrefDepTimeProbDist.
786  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (1 * stdair::HOUR_CONVERTED_IN_SECONDS,
787  0.6));
788  lBKKPrefDepTimeProbDist.
789  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (14 * stdair::HOUR_CONVERTED_IN_SECONDS,
790  0.8));
791  lBKKPrefDepTimeProbDist.
792  insert (PreferredDepartureTimeContinuousDistribution_T::value_type (16 * stdair::HOUR_CONVERTED_IN_SECONDS,
793  1.0));
794 
795  //
796  const stdair::WTP_T lBKKHKGWTP (400.0);
797 
798 
799  // Delegate the call to the dedicated command
800  DemandStream& lBKKHKGDemandStream =
801  createDemandStream (ioSEVMGR_ServicePtr, lBKKHKGDemandStreamKey, lDTDProbDist,
802  lBKKHKGPOSProbDist, lChannelProbDist, lTripProbDist,
803  lStayProbDist, lFFProbDist,
804  lChangeFees, lChangeFeeDisutility,
805  lNonRefundable, lNonRefundableDisutility,
806  lBKKPrefDepTimeProbDist,
807  lBKKHKGWTP, lTimeValueProbDist,
808  lBKKHKGDemandDistribution,
809  ioSharedGenerator.getBaseGenerator(),
810  lBKKHKGRequestDateTimeSeed,
811  lBKKHKGDemandCharacteristicsSeed, iPOSProbMass);
812 
813  // Calculate the expected total number of events for the current
814  // demand stream
815  const stdair::NbOfRequests_T& lBKKHKGExpectedNbOfEvents =
816  lBKKHKGDemandStream.getMeanNumberOfRequests();
817 
818  /*===================================================================================*/
819 
820  // Key of the demand stream
821 
822  //
823  const DemandStreamKey lSINHKGDemandStreamKey (lSINOrigin, lHKGDestination, lDepDate,
824  lCabin);
825 
826  // DEBUG
827  // STDAIR_LOG_DEBUG ("Demand stream key: " << lDemandStreamKey.describe());
828 
829  // Distribution for the number of requests
830  const stdair::MeanValue_T lSINHKGDemandMean (60.0);
831  const stdair::StdDevValue_T lSINHKGDemandStdDev (4.0);
832  const DemandDistribution lSINHKGDemandDistribution (lSINHKGDemandMean, lSINHKGDemandStdDev);
833 
834  // Seed
835  const stdair::RandomSeed_T& lSINHKGRequestDateTimeSeed =
836  generateSeed (ioSharedGenerator);
837  const stdair::RandomSeed_T& lSINHKGDemandCharacteristicsSeed =
838  generateSeed (ioSharedGenerator);
839 
840 
841  //
842  POSProbabilityMassFunction_T lSINHKGPOSProbDist;
843  lSINHKGPOSProbDist.insert (POSProbabilityMassFunction_T::value_type ("SIN", 1.0));
844  lSINHKGPOSProbDist.insert (POSProbabilityMassFunction_T::value_type ("HKG", 0.0));
845 
846  //
847  const stdair::WTP_T lSINHKGWTP (750.0);
848 
849 
850  // Delegate the call to the dedicated command
851  DemandStream& lSINHKGDemandStream =
852  createDemandStream (ioSEVMGR_ServicePtr, lSINHKGDemandStreamKey, lDTDProbDist,
853  lSINHKGPOSProbDist, lChannelProbDist, lTripProbDist,
854  lStayProbDist, lFFProbDist,
855  lChangeFees, lChangeFeeDisutility,
856  lNonRefundable, lNonRefundableDisutility,
857  lSINPrefDepTimeProbDist,
858  lSINHKGWTP, lTimeValueProbDist, lSINHKGDemandDistribution,
859  ioSharedGenerator.getBaseGenerator(),
860  lSINHKGRequestDateTimeSeed,
861  lSINHKGDemandCharacteristicsSeed, iPOSProbMass);
862 
863  // Calculate the expected total number of events for the current
864  // demand stream
865  const stdair::NbOfRequests_T& lSINHKGExpectedNbOfEvents =
866  lSINHKGDemandStream.getMeanNumberOfRequests();
867 
868  /*===================================================================================*/
869 
873  const stdair::NbOfRequests_T lExpectedTotalNbOfEvents =
874  lSINBKKExpectedNbOfEvents + lBKKHKGExpectedNbOfEvents + lSINHKGExpectedNbOfEvents;
875  ioSEVMGR_ServicePtr->addStatus (stdair::EventType::BKG_REQ,
876  lExpectedTotalNbOfEvents);
877  }
878 
879 }
880