$treeview $search $mathjax
TraDemGen Logo  1.00.0
$projectbrief
$projectbrief
$searchbox

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