TraDemGen Logo  0.2.2
C++ Simulated Travel Demand Generation Library
DemandStream.cpp
Go to the documentation of this file.
00001 // //////////////////////////////////////////////////////////////////////
00002 // Import section
00003 // //////////////////////////////////////////////////////////////////////
00004 // STL
00005 #include <cassert>
00006 #include <sstream>
00007 #include <cmath>
00008 #include <iomanip>
00009 // Boost
00010 #include <boost/make_shared.hpp>
00011 // StdAir
00012 #include <stdair/basic/BasConst_General.hpp>
00013 #include <stdair/basic/BasConst_Inventory.hpp>
00014 #include <stdair/basic/BasConst_Request.hpp>
00015 #include <stdair/bom/BookingRequestStruct.hpp>
00016 #include <stdair/service/Logger.hpp>
00017 // TraDemGen
00018 #include <trademgen/basic/BasConst_DemandGeneration.hpp>
00019 #include <trademgen/bom/DemandStream.hpp>
00020 
00021 namespace TRADEMGEN {
00022 
00023   // ////////////////////////////////////////////////////////////////////
00024   DemandStream::DemandStream()
00025     : _key (stdair::DEFAULT_ORIGIN, stdair::DEFAULT_DESTINATION,
00026             stdair::DEFAULT_DEPARTURE_DATE, stdair::DEFAULT_CABIN_CODE),
00027       _parent (NULL),
00028       _demandCharacteristics (ArrivalPatternCumulativeDistribution_T(),
00029                               POSProbabilityMassFunction_T(),
00030                               ChannelProbabilityMassFunction_T(),
00031                               TripTypeProbabilityMassFunction_T(),
00032                               StayDurationProbabilityMassFunction_T(),
00033                               FrequentFlyerProbabilityMassFunction_T(),
00034                               PreferredDepartureTimeContinuousDistribution_T(),
00035                               0.0,
00036                               ValueOfTimeContinuousDistribution_T()),
00037       _posProMass (DEFAULT_POS_PROBALILITY_MASS),
00038       _firstDateTimeRequest (true) {
00039     assert (false);
00040   }
00041 
00042   // ////////////////////////////////////////////////////////////////////
00043   DemandStream::DemandStream (const DemandStream&)
00044     : _key (stdair::DEFAULT_ORIGIN, stdair::DEFAULT_DESTINATION,
00045             stdair::DEFAULT_DEPARTURE_DATE, stdair::DEFAULT_CABIN_CODE),
00046       _parent (NULL),
00047       _demandCharacteristics (ArrivalPatternCumulativeDistribution_T(),
00048                               POSProbabilityMassFunction_T(),
00049                               ChannelProbabilityMassFunction_T(),
00050                               TripTypeProbabilityMassFunction_T(),
00051                               StayDurationProbabilityMassFunction_T(),
00052                               FrequentFlyerProbabilityMassFunction_T(),
00053                               PreferredDepartureTimeContinuousDistribution_T(),
00054                               0.0,
00055                               ValueOfTimeContinuousDistribution_T()),
00056       _posProMass (DEFAULT_POS_PROBALILITY_MASS),
00057       _firstDateTimeRequest (true) {
00058     assert (false);
00059   }
00060 
00061   // ////////////////////////////////////////////////////////////////////
00062   DemandStream::DemandStream (const Key_T& iKey) :
00063     _key (iKey) {
00064   }
00065 
00066   // ////////////////////////////////////////////////////////////////////
00067   DemandStream::~DemandStream() {
00068   }
00069 
00070   // ////////////////////////////////////////////////////////////////////
00071   std::string DemandStream::toString() const {
00072     std::ostringstream oStr;
00073     oStr << _key.toString();
00074     return oStr.str();
00075   }
00076 
00077   // ////////////////////////////////////////////////////////////////////
00078   void DemandStream::
00079   setAll (const ArrivalPatternCumulativeDistribution_T& iArrivalPattern,
00080           const POSProbabilityMassFunction_T& iPOSProbMass,
00081           const ChannelProbabilityMassFunction_T& iChannelProbMass,
00082           const TripTypeProbabilityMassFunction_T& iTripTypeProbMass,
00083           const StayDurationProbabilityMassFunction_T& iStayDurationProbMass,
00084           const FrequentFlyerProbabilityMassFunction_T& iFrequentFlyerProbMass,
00085           const PreferredDepartureTimeContinuousDistribution_T& iPreferredDepartureTimeContinuousDistribution,
00086           const stdair::WTP_T& iMinWTP,
00087           const ValueOfTimeContinuousDistribution_T& iValueOfTimeContinuousDistribution,
00088           const DemandDistribution& iDemandDistribution,
00089           stdair::BaseGenerator_T& ioSharedGenerator,
00090           const stdair::RandomSeed_T& iRequestDateTimeSeed,
00091           const stdair::RandomSeed_T& iDemandCharacteristicsSeed,
00092           const POSProbabilityMass_T& iDefaultPOSProbablityMass) {
00093 
00094     setDemandCharacteristics (iArrivalPattern, iPOSProbMass,
00095                               iChannelProbMass, iTripTypeProbMass,
00096                               iStayDurationProbMass, iFrequentFlyerProbMass,
00097                               iPreferredDepartureTimeContinuousDistribution,
00098                               iMinWTP, iValueOfTimeContinuousDistribution);
00099 
00100     setDemandDistribution (iDemandDistribution);
00101     setTotalNumberOfRequestsToBeGenerated (0);
00102     setRequestDateTimeRandomGeneratorSeed (iRequestDateTimeSeed);
00103     setDemandCharacteristicsRandomGeneratorSeed (iDemandCharacteristicsSeed);
00104     setPOSProbabilityMass (iDefaultPOSProbablityMass);
00105 
00106     //
00107     init (ioSharedGenerator);
00108   }
00109 
00110   // ////////////////////////////////////////////////////////////////////
00111   std::string DemandStream::display() const {
00112     std::ostringstream oStr;
00113 
00114     oStr << "Demand stream key: " << _key.toString() << std::endl;
00115 
00116     //
00117     oStr << _demandCharacteristics.describe();
00118 
00119     //
00120     oStr << _demandDistribution.describe() << " => "
00121          << _totalNumberOfRequestsToBeGenerated << " to be generated"
00122          << std::endl;
00123 
00124     //
00125     oStr << "Random generation context: " << _randomGenerationContext
00126          << std::endl;
00127 
00128     //
00129     oStr << "Random generator for date-time: "
00130          << _requestDateTimeRandomGenerator << std::endl;
00131     oStr << "Random generator for demand characteristics: "
00132          << _demandCharacteristicsRandomGenerator << std::endl;
00133 
00134     //
00135     oStr << _posProMass.displayProbabilityMass() << std::endl;
00136 
00137     return oStr.str();
00138   }    
00139 
00140   // ////////////////////////////////////////////////////////////////////
00141   void DemandStream::init (stdair::BaseGenerator_T& ioSharedGenerator) {
00142     
00143     // Generate the number of requests
00144     const stdair::RealNumber_T lMu = _demandDistribution._meanNumberOfRequests;
00145     const stdair::RealNumber_T lSigma =
00146       _demandDistribution._stdDevNumberOfRequests;
00147 
00148     stdair::NormalDistribution_T lDistrib (lMu, lSigma);
00149     stdair::NormalGenerator_T lNormalGen (ioSharedGenerator, lDistrib);
00150     
00151     const stdair::RealNumber_T lRealNumberOfRequestsToBeGenerated =lNormalGen();
00152 
00153     const stdair::NbOfRequests_T lIntegerNumberOfRequestsToBeGenerated = 
00154       std::floor (lRealNumberOfRequestsToBeGenerated + 0.5);
00155     
00156     _totalNumberOfRequestsToBeGenerated = lIntegerNumberOfRequestsToBeGenerated;
00157 
00158     _stillHavingRequestsToBeGenerated = true;
00159     _firstDateTimeRequest = true;
00160   }  
00161 
00162   // ////////////////////////////////////////////////////////////////////
00163   const bool DemandStream::
00164   stillHavingRequestsToBeGenerated (const stdair::DemandGenerationMethod& iDemandGenerationMethod) const {
00165     
00166     const stdair::DemandGenerationMethod::EN_DemandGenerationMethod& lENDemandGenerationMethod =
00167       iDemandGenerationMethod.getMethod();
00168     if (lENDemandGenerationMethod == stdair::DemandGenerationMethod::STA_ORD) {
00169       bool hasStillHavingRequestsToBeGenerated = true;
00170       
00171       // Check whether enough requests have already been generated
00172       const stdair::Count_T lNbOfRequestsGeneratedSoFar =
00173         _randomGenerationContext.getNumberOfRequestsGeneratedSoFar();
00174       
00175       const stdair::Count_T lRemainingNumberOfRequestsToBeGenerated =
00176         _totalNumberOfRequestsToBeGenerated - lNbOfRequestsGeneratedSoFar;
00177       
00178       if (lRemainingNumberOfRequestsToBeGenerated <= 0) {
00179         hasStillHavingRequestsToBeGenerated = false;
00180       }
00181       
00182       return hasStillHavingRequestsToBeGenerated;
00183     } else {
00184       return _stillHavingRequestsToBeGenerated;
00185     }
00186   }
00187 
00188   // ////////////////////////////////////////////////////////////////////
00189   const stdair::DateTime_T DemandStream::generateTimeOfRequestPoissonProcess() {
00190 
00191     // Prepare arrival pattern.
00192     const ContinuousFloatDuration_T& lArrivalPattern =
00193       _demandCharacteristics._arrivalPattern;
00194       
00195     const stdair::Time_T lHardcodedReferenceDepartureTime =
00196       boost::posix_time::hours (8);
00197 
00198     // Prepare departure date time.
00199     const stdair::DateTime_T lDepartureDateTime =
00200       boost::posix_time::ptime (_key.getPreferredDepartureDate(),
00201                                 lHardcodedReferenceDepartureTime);
00202 
00203     // If no request has been generated so far...
00204     if (_firstDateTimeRequest) {
00205       const stdair::Probability_T lProbabilityFirstRequest = 0;
00206 
00207       // Get the lower bound of the arrival pattern (correponding
00208       // to a cumulative probability of 0).
00209       _dateTimeLastRequest =
00210         lArrivalPattern.getValue (lProbabilityFirstRequest);
00211 
00212       _firstDateTimeRequest = false;
00213     }
00214 
00215     // Sanity check.
00216     assert (_firstDateTimeRequest == false);
00217 
00218     // If the date time of the last request is equal to the lower bound of
00219     // the last daily rate interval (default value is -1, meaning one day
00220     // before departure), we stopped generating request by returning a
00221     // request date time after departure date time.
00222     if (_dateTimeLastRequest == DEFAULT_LAST_LOWER_BOUND_ARRIVAL_PATTERN) {
00223       _stillHavingRequestsToBeGenerated = false;
00224 
00225       // Get a positive number of days.
00226       const stdair::Duration_T lDifferenceBetweenDepartureAndThisLowerBound =
00227         convertFloatIntoDuration (-DEFAULT_LAST_LOWER_BOUND_ARRIVAL_PATTERN);
00228 
00229       // Calculate a request date-time after the departure date time to end
00230       // the demand generation algorithm.
00231       const stdair::DateTime_T oDateTimeThisRequest =
00232         lDepartureDateTime + lDifferenceBetweenDepartureAndThisLowerBound;
00233 
00234       return oDateTimeThisRequest;
00235     }
00236     
00237     // Get the upper bound of the current daily rate interval.
00238     stdair::FloatDuration_T lUpperBound =
00239       lArrivalPattern.getUpperBound (_dateTimeLastRequest);
00240 
00241     // Compute the daily rate demand.
00242     double lDailyRate =lArrivalPattern.getDerivativeValue(_dateTimeLastRequest);
00243     // Get the expected average number of requests.
00244     const double lDemandMean = _demandDistribution._meanNumberOfRequests;
00245     // Multiply the daily rate by the expected average number of requests.
00246     lDailyRate *= lDemandMean;
00247 
00248     // Generate an exponential variable.
00249     const stdair::FloatDuration_T lExponentialVariable =
00250       _requestDateTimeRandomGenerator.generateExponential (lDailyRate);
00251 
00252     // Compute the new date time request.
00253     const stdair::FloatDuration_T lDateTimeThisRequest =
00254       _dateTimeLastRequest + lExponentialVariable;
00255 
00256     stdair::DateTime_T oDateTimeThisRequest;
00257 
00258     // Verify if this request is in the given daily rate interval.
00259     if (lDateTimeThisRequest < lUpperBound) {
00260 
00261       // Conversion.
00262       const stdair::Duration_T lDifferenceBetweenDepartureAndThisRequest =
00263         convertFloatIntoDuration (lDateTimeThisRequest);
00264 
00265       // The request date-time is derived from departure date and arrival pattern.
00266       oDateTimeThisRequest = lDepartureDateTime
00267         + lDifferenceBetweenDepartureAndThisRequest;
00268 
00269       // Remember this date time request.
00270       _dateTimeLastRequest = lDateTimeThisRequest;
00271       
00272       // Update the counter of requests generated so far.
00273       incrementGeneratedRequestsCounter();
00274 
00275       const double lRefDateTimeThisRequest = lDateTimeThisRequest + double(28800.001/86400.0);
00276       STDAIR_LOG_NOTIFICATION (boost::gregorian::to_iso_string(_key.getPreferredDepartureDate()) << ";" << std::setprecision(10) << lRefDateTimeThisRequest);
00277     } else {
00278       
00279       // The current request is not in the given daily rate interval.
00280       // Change the daily rate.
00281       _dateTimeLastRequest = lUpperBound;
00282 
00283       // Generate a date time request in the new daily rate interval.
00284       oDateTimeThisRequest = generateTimeOfRequestPoissonProcess ();
00285     }
00286     
00287     return oDateTimeThisRequest;
00288   }
00289 
00290   // ////////////////////////////////////////////////////////////////////
00291   const stdair::DateTime_T DemandStream::generateTimeOfRequestStatisticsOrder() {
00292    
00309     //
00310     // Calculate the result of the formula above step by step.
00311     //
00312     
00313     // 1) Get the number of requests generated so far.
00314     //    (equal to k - 1)
00315     const stdair::Count_T& lNbOfRequestsGeneratedSoFar =
00316       _randomGenerationContext.getNumberOfRequestsGeneratedSoFar();
00317 
00318     // 2) Deduce the number of requests not generated yet.
00319     //    (equal to n - k + 1)
00320     const stdair::Count_T lRemainingNumberOfRequestsToBeGenerated =
00321       _totalNumberOfRequestsToBeGenerated - lNbOfRequestsGeneratedSoFar;
00322 
00323     // Assert that there are still requests to be generated.
00324     assert (lRemainingNumberOfRequestsToBeGenerated > 0);
00325 
00326     // 3) Inverse the number of requests not generated yet.
00327     //    1/(n - k + 1)
00328     const double lRemainingRate =
00329       1.0 / static_cast<double> (lRemainingNumberOfRequestsToBeGenerated);
00330    
00331     // 4) Get the cumulative probality so far and take its complement.
00332     //    (equal to 1 - x(k-1))
00333     const stdair::Probability_T& lCumulativeProbabilitySoFar =
00334       _randomGenerationContext.getCumulativeProbabilitySoFar();
00335     const stdair::Probability_T lComplementOfCumulativeProbabilitySoFar =
00336       1.0 - lCumulativeProbabilitySoFar;
00337 
00338     // 5) Draw a random variable y and calculate the factor equal to 
00339     //    (1 - y)^(1/(n - k + 1)).
00340     const stdair::Probability_T& lVariate = _requestDateTimeRandomGenerator();
00341     double lFactor = std::pow (1.0 - lVariate, lRemainingRate);
00342     if (lFactor >= 1.0 - 1e-6){
00343       lFactor = 1.0 - 1e-6;
00344     }
00345 
00346     // 6) Apply the whole formula above to calculate the cumulative probability
00347     //    of the new request.
00348     //    (equal to 1 - (1 - x(k-1))(1 - y)^(1/(n - k + 1)))
00349     const stdair::Probability_T lCumulativeProbabilityThisRequest =
00350       1.0 - lComplementOfCumulativeProbabilitySoFar * lFactor;
00351     
00352     // Now that the cumulative proportion of events generated has been
00353     // calculated, we deduce from the arrival pattern the arrival time of the
00354     // k-th event.
00355     const stdair::FloatDuration_T lNumberOfDaysBetweenDepartureAndThisRequest =
00356       _demandCharacteristics._arrivalPattern.getValue (lCumulativeProbabilityThisRequest);
00357     
00358     const stdair::Duration_T lDifferenceBetweenDepartureAndThisRequest =
00359       convertFloatIntoDuration (lNumberOfDaysBetweenDepartureAndThisRequest);
00360 
00361     const stdair::Time_T lHardcodedReferenceDepartureTime =
00362       boost::posix_time::hours (8);
00363     
00364     const stdair::DateTime_T lDepartureDateTime =
00365       boost::posix_time::ptime (_key.getPreferredDepartureDate(),
00366                                 lHardcodedReferenceDepartureTime);
00367 
00368     // The request date-time is derived from departure date and arrival pattern.
00369     const stdair::DateTime_T oDateTimeThisRequest =
00370       lDepartureDateTime + lDifferenceBetweenDepartureAndThisRequest;
00371     
00372     // Update random generation context
00373     _randomGenerationContext.setCumulativeProbabilitySoFar (lCumulativeProbabilityThisRequest);
00374 
00375     // Update the counter of requests generated so far.
00376     incrementGeneratedRequestsCounter();
00377 
00378     // DEBUG
00379     // STDAIR_LOG_DEBUG (lCumulativeProbabilityThisRequest << "; "
00380     //                   << lNumberOfDaysBetweenDepartureAndThisRequest);
00381 
00382     // NOTIFICATION
00383     double lRefNumberOfDaysBetweenDepartureAndThisRequest =
00384       lNumberOfDaysBetweenDepartureAndThisRequest + double(1.0/3.0);
00385     STDAIR_LOG_NOTIFICATION (boost::gregorian::to_iso_string(_key.getPreferredDepartureDate()) << ";" << std::setprecision(10) << lRefNumberOfDaysBetweenDepartureAndThisRequest);
00386     
00387     return oDateTimeThisRequest;
00388   }
00389 
00390   // ////////////////////////////////////////////////////////////////////
00391 
00392   const stdair::Duration_T DemandStream::
00393   convertFloatIntoDuration (const stdair::FloatDuration_T iNumberOfDays) {
00394     
00395     // Convert the number of days in number of seconds + number of milliseconds
00396     const stdair::FloatDuration_T lNumberOfSeconds =
00397       iNumberOfDays * stdair::SECONDS_IN_ONE_DAY;
00398     
00399     // Get the number of seconds.
00400     const stdair::IntDuration_T lIntNumberOfSeconds =
00401       std::floor (lNumberOfSeconds);
00402     
00403     // Get the number of milliseconds.
00404     const stdair::FloatDuration_T lNumberOfMilliseconds =
00405       (lNumberOfSeconds - lIntNumberOfSeconds)
00406       * stdair::MILLISECONDS_IN_ONE_SECOND;
00407 
00408     // +1 is a trick to ensure that the next Event is strictly later
00409     // than the current one
00410     const stdair::IntDuration_T lIntNumberOfMilliseconds =
00411       std::floor (lNumberOfMilliseconds) + 1;
00412 
00413     // Convert the number of seconds and milliseconds into a duration.
00414     const stdair::Duration_T lDifferenceBetweenDepartureAndThisRequest =
00415       boost::posix_time::seconds (lIntNumberOfSeconds)
00416       + boost::posix_time::millisec (lIntNumberOfMilliseconds);
00417 
00418     return lDifferenceBetweenDepartureAndThisRequest;
00419   }
00420 
00421   // ////////////////////////////////////////////////////////////////////
00422   const stdair::AirportCode_T DemandStream::generatePOS() {
00423     
00424     // Generate a random number between 0 and 1.
00425     const stdair::Probability_T& lVariate = _demandCharacteristicsRandomGenerator();
00426     const stdair::AirportCode_T& oPOS = _demandCharacteristics.getPOSValue (lVariate);
00427 
00428     return oPOS;
00429   }
00430 
00431   // ////////////////////////////////////////////////////////////////////
00432   const stdair::ChannelLabel_T DemandStream::generateChannel() {
00433     // Generate a random number between 0 and 1.
00434     const stdair::Probability_T lVariate =
00435       _demandCharacteristicsRandomGenerator();
00436 
00437     return _demandCharacteristics._channelProbabilityMass.getValue (lVariate);
00438   }
00439 
00440   // ////////////////////////////////////////////////////////////////////
00441   const stdair::TripType_T DemandStream::generateTripType() {
00442     // Generate a random number between 0 and 1.
00443     const stdair::Probability_T lVariate =
00444       _demandCharacteristicsRandomGenerator(); 
00445 
00446     return _demandCharacteristics._tripTypeProbabilityMass.getValue (lVariate);
00447   }
00448 
00449   // ////////////////////////////////////////////////////////////////////
00450   const stdair::DayDuration_T DemandStream::generateStayDuration() {
00451     // Generate a random number between 0 and 1.
00452     const stdair::Probability_T lVariate =
00453       _demandCharacteristicsRandomGenerator();    
00454 
00455     return _demandCharacteristics._stayDurationProbabilityMass.getValue (lVariate);
00456   }
00457   
00458   // ////////////////////////////////////////////////////////////////////
00459   const stdair::FrequentFlyer_T DemandStream::generateFrequentFlyer() {
00460     // Generate a random number between 0 and 1.
00461     const stdair::Probability_T lVariate =
00462       _demandCharacteristicsRandomGenerator();       
00463 
00464     return _demandCharacteristics._frequentFlyerProbabilityMass.getValue (lVariate);
00465   }
00466 
00467   // ////////////////////////////////////////////////////////////////////
00468   const stdair::Duration_T DemandStream::generatePreferredDepartureTime() {
00469     // Generate a random number between 0 and 1.
00470     const stdair::Probability_T lVariate =
00471       _demandCharacteristicsRandomGenerator();     
00472     const stdair::IntDuration_T lNbOfSeconds = _demandCharacteristics.
00473       _preferredDepartureTimeCumulativeDistribution.getValue (lVariate);
00474 
00475     const stdair::Duration_T oTime = boost::posix_time::seconds (lNbOfSeconds);
00476 
00477     return oTime;
00478   }
00479 
00480   // ////////////////////////////////////////////////////////////////////
00481   const stdair::WTP_T DemandStream::
00482   generateWTP (stdair::RandomGeneration& ioGenerator,
00483                const stdair::Date_T& iDepartureDate,
00484                const stdair::DateTime_T& iDateTimeThisRequest,
00485                const stdair::DayDuration_T& iDurationOfStay) {
00486     const stdair::Date_T lDateThisRequest = iDateTimeThisRequest.date();
00487     const stdair::DateOffset_T lAP = iDepartureDate - lDateThisRequest;
00488     const stdair::DayDuration_T lAPInDays = lAP.days();
00489 
00490     stdair::RealNumber_T lProb = -lAPInDays;
00491       //1 - lAPInDays / DEFAULT_MAX_ADVANCE_PURCHASE;
00492     if (lProb < 0.0) { lProb = 0.0; }
00493     stdair::RealNumber_T lFrat5Coef =
00494       _demandCharacteristics._frat5Pattern.getValue (lProb);
00495 
00496     const stdair::WTP_T lWTP =  _demandCharacteristics._minWTP
00497       * (1.0 + (lFrat5Coef - 1.0) * log(ioGenerator()) / log(0.5));
00498     
00499     return lWTP;
00500   }
00501 
00502   // ////////////////////////////////////////////////////////////////////
00503   const stdair::PriceValue_T DemandStream::generateValueOfTime() {
00504     // Generate a random number between 0 and 1.
00505     const stdair::Probability_T lVariate =
00506       _demandCharacteristicsRandomGenerator();    
00507 
00508     return _demandCharacteristics._valueOfTimeCumulativeDistribution.getValue (lVariate);
00509   }
00510   
00511   // ////////////////////////////////////////////////////////////////////
00512   stdair::BookingRequestPtr_T DemandStream::
00513   generateNextRequest (stdair::RandomGeneration& ioGenerator,
00514                        const stdair::DemandGenerationMethod& iDemandGenerationMethod) {
00515 
00516     // Origin
00517     const stdair::AirportCode_T& lOrigin = _key.getOrigin();
00518     // Destination
00519     const stdair::AirportCode_T& lDestination = _key.getDestination();
00520     // Preferred departure date
00521     const stdair::Date_T& lPreferredDepartureDate = 
00522       _key.getPreferredDepartureDate();
00523     // Preferred cabin
00524     const stdair::CabinCode_T& lPreferredCabin = _key.getPreferredCabin();
00525     // Party size
00526     const stdair::NbOfSeats_T lPartySize = stdair::DEFAULT_PARTY_SIZE;
00527     // POS
00528     const stdair::AirportCode_T lPOS = generatePOS();
00529     
00530     // Compute the request date time with the correct algorithm.
00531     stdair::DateTime_T lDateTimeThisRequest;
00532     const stdair::DemandGenerationMethod::EN_DemandGenerationMethod& lENDemandGenerationMethod =
00533       iDemandGenerationMethod.getMethod();
00534     switch(lENDemandGenerationMethod) {
00535     case stdair::DemandGenerationMethod::POI_PRO:
00536       lDateTimeThisRequest = generateTimeOfRequestPoissonProcess(); break;
00537     case stdair::DemandGenerationMethod::STA_ORD:
00538       lDateTimeThisRequest = generateTimeOfRequestStatisticsOrder(); break;
00539     default: assert (false); break;
00540     }
00541     
00542     // Booking channel.
00543     const stdair::ChannelLabel_T lChannelLabel = generateChannel();
00544     // Trip type.
00545     const stdair::TripType_T lTripType = generateTripType();
00546     // Stay duration.
00547     const stdair::DayDuration_T lStayDuration = generateStayDuration();
00548     // Frequet flyer type.
00549     const stdair::FrequentFlyer_T lFrequentFlyer = generateFrequentFlyer();
00550     // Preferred departure time.
00551     const stdair::Duration_T lPreferredDepartureTime =
00552       generatePreferredDepartureTime();
00553     // Value of time
00554     const stdair::PriceValue_T lValueOfTime = generateValueOfTime();
00555     // WTP
00556     const stdair::WTP_T lWTP = generateWTP (ioGenerator,lPreferredDepartureDate,
00557                                             lDateTimeThisRequest,lStayDuration);
00558 
00559     // TODO 1: understand why the following form does not work, knowing
00560     // that:
00561     // typedef boost::shared_ptr<stdair::BookingRequestStruct> stdair::BookingRequestPtr_T
00562     // stdair::BookingRequestPtr_T oBookingRequest_ptr =
00563     //   boost::make_shared<stdair::BookingRequestStruct> ();
00564 
00565 
00566     // TODO 2: move the creation of the structure out of the BOM layer
00567     //  (into the command layer, e.g., within the DemandManager command).
00568     
00569     // Create the booking request
00570     stdair::BookingRequestPtr_T oBookingRequest_ptr =
00571       stdair::BookingRequestPtr_T
00572       (new stdair::BookingRequestStruct (describeKey(), lOrigin,
00573                                          lDestination, lPOS,
00574                                          lPreferredDepartureDate,
00575                                          lDateTimeThisRequest,
00576                                          lPreferredCabin, lPartySize,
00577                                          lChannelLabel, lTripType,
00578                                          lStayDuration, lFrequentFlyer,
00579                                          lPreferredDepartureTime,
00580                                          lWTP, lValueOfTime));
00581     
00582     // DEBUG
00583     // STDAIR_LOG_DEBUG ("\n[BKG] " << oBookingRequest_ptr->describe());
00584     
00585     return oBookingRequest_ptr;
00586   }
00587 
00588   // ////////////////////////////////////////////////////////////////////
00589   void DemandStream::reset (stdair::BaseGenerator_T& ioSharedGenerator) {
00590     _randomGenerationContext.reset();
00591     init (ioSharedGenerator);
00592   }
00593 
00594 }