$treeview $search $mathjax
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 }