$treeview $search $mathjax
00001 // ////////////////////////////////////////////////////////////////////// 00002 // Import section 00003 // ////////////////////////////////////////////////////////////////////// 00004 // STL 00005 #include <cassert> 00006 // Boost 00007 #include <boost/make_shared.hpp> 00008 // StdAir 00009 #include <stdair/basic/ProgressStatusSet.hpp> 00010 #include <stdair/basic/BasConst_Request.hpp> 00011 #include <stdair/bom/BomManager.hpp> 00012 #include <stdair/bom/EventStruct.hpp> 00013 #include <stdair/bom/BookingRequestStruct.hpp> 00014 #include <stdair/bom/TravelSolutionStruct.hpp> 00015 #include <stdair/bom/CancellationStruct.hpp> 00016 #include <stdair/factory/FacBom.hpp> 00017 #include <stdair/factory/FacBomManager.hpp> 00018 #include <stdair/service/Logger.hpp> 00019 // SEvMgr 00020 #include <sevmgr/SEVMGR_Service.hpp> 00021 // TraDemGen 00022 #include <trademgen/basic/DemandCharacteristics.hpp> 00023 #include <trademgen/basic/DemandDistribution.hpp> 00024 #include <trademgen/bom/DemandStruct.hpp> 00025 #include <trademgen/bom/DemandStream.hpp> 00026 #include <trademgen/command/DemandManager.hpp> 00027 00028 namespace TRADEMGEN { 00029 00030 // ////////////////////////////////////////////////////////////////////// 00031 void DemandManager:: 00032 buildSampleBomStd (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr, 00033 stdair::RandomGeneration& ioSharedGenerator, 00034 const POSProbabilityMass_T& iPOSProbMass) { 00035 // Sanity check 00036 assert (ioSEVMGR_ServicePtr != NULL); 00037 00038 // Key of the demand stream 00039 const stdair::AirportCode_T lOrigin ("SIN"); 00040 const stdair::AirportCode_T lDestination ("BKK"); 00041 const stdair::Date_T lDepDate (2011, 2, 14); 00042 const stdair::CabinCode_T lCabin ("Y"); 00043 00044 // 00045 const DemandStreamKey lDemandStreamKey (lOrigin, lDestination, lDepDate, 00046 lCabin); 00047 00048 // DEBUG 00049 // STDAIR_LOG_DEBUG ("Demand stream key: " << lDemandStreamKey.describe()); 00050 00051 // Distribution for the number of requests 00052 const stdair::MeanValue_T lDemandMean (10.0); 00053 const stdair::StdDevValue_T lDemandStdDev (1.0); 00054 const DemandDistribution lDemandDistribution (lDemandMean, lDemandStdDev); 00055 00056 // Seed 00057 const stdair::RandomSeed_T& lRequestDateTimeSeed = 00058 generateSeed (ioSharedGenerator); 00059 const stdair::RandomSeed_T& lDemandCharacteristicsSeed = 00060 generateSeed (ioSharedGenerator); 00061 00062 // 00063 ArrivalPatternCumulativeDistribution_T lDTDProbDist; 00064 lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-330, 00065 0)); 00066 lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-40, 00067 0.2)); 00068 lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-20, 00069 0.6)); 00070 lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-1, 00071 1.0)); 00072 // 00073 POSProbabilityMassFunction_T lPOSProbDist; 00074 lPOSProbDist.insert (POSProbabilityMassFunction_T::value_type ("BKK", 0.3)); 00075 lPOSProbDist.insert (POSProbabilityMassFunction_T::value_type ("SIN", 0.7)); 00076 // 00077 ChannelProbabilityMassFunction_T lChannelProbDist; 00078 lChannelProbDist.insert (ChannelProbabilityMassFunction_T::value_type ("DF", 00079 0.1)); 00080 lChannelProbDist.insert (ChannelProbabilityMassFunction_T::value_type ("DN", 00081 0.3)); 00082 lChannelProbDist.insert (ChannelProbabilityMassFunction_T::value_type ("IF", 00083 0.4)); 00084 lChannelProbDist.insert (ChannelProbabilityMassFunction_T::value_type ("IN", 00085 0.2)); 00086 // 00087 TripTypeProbabilityMassFunction_T lTripProbDist; 00088 lTripProbDist.insert (TripTypeProbabilityMassFunction_T::value_type ("RO", 00089 0.6)); 00090 lTripProbDist.insert (TripTypeProbabilityMassFunction_T::value_type ("RI", 00091 0.2)); 00092 lTripProbDist.insert (TripTypeProbabilityMassFunction_T::value_type ("OW", 00093 0.2)); 00094 // 00095 StayDurationProbabilityMassFunction_T lStayProbDist; 00096 lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(0, 00097 0.1)); 00098 lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(1, 00099 0.1)); 00100 lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(2, 00101 .15)); 00102 lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(3, 00103 .15)); 00104 lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(4, 00105 .15)); 00106 lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(5, 00107 .35)); 00108 // 00109 FrequentFlyerProbabilityMassFunction_T lFFProbDist; 00110 lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("P", 00111 0.01)); 00112 lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("G", 00113 0.05)); 00114 lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("S", 00115 0.15)); 00116 lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("M", 00117 0.3)); 00118 lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("N", 00119 0.49)); 00120 // 00121 PreferredDepartureTimeContinuousDistribution_T lPrefDepTimeProbDist; 00122 lPrefDepTimeProbDist. 00123 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (6 * stdair::HOUR_CONVERTED_IN_SECONDS, 0)); 00124 lPrefDepTimeProbDist. 00125 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (7 * stdair::HOUR_CONVERTED_IN_SECONDS, 00126 0.1)); 00127 lPrefDepTimeProbDist. 00128 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (9 * stdair::HOUR_CONVERTED_IN_SECONDS, 00129 0.3)); 00130 lPrefDepTimeProbDist. 00131 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (17 * stdair::HOUR_CONVERTED_IN_SECONDS, 00132 0.4)); 00133 lPrefDepTimeProbDist. 00134 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (19 * stdair::HOUR_CONVERTED_IN_SECONDS, 00135 0.80)); 00136 lPrefDepTimeProbDist. 00137 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (20 * stdair::HOUR_CONVERTED_IN_SECONDS, 00138 0.95)); 00139 lPrefDepTimeProbDist. 00140 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (22 * stdair::HOUR_CONVERTED_IN_SECONDS, 00141 1)); 00142 // 00143 ValueOfTimeContinuousDistribution_T lTimeValueProbDist; 00144 lTimeValueProbDist.insert(ValueOfTimeContinuousDistribution_T::value_type(15, 00145 0)); 00146 lTimeValueProbDist.insert(ValueOfTimeContinuousDistribution_T::value_type(60, 00147 1)); 00148 00149 // 00150 const stdair::WTP_T lWTP (1000.0); 00151 const stdair::ChangeFeesRatio_T lChangeFees (0.5); 00152 const stdair::Disutility_T lChangeFeeDisutility (50); 00153 const stdair::NonRefundableRatio_T lNonRefundable (0.5); 00154 const stdair::Disutility_T lNonRefundableDisutility (50); 00155 00156 00157 // Delegate the call to the dedicated command 00158 DemandStream& lDemandStream = 00159 createDemandStream (ioSEVMGR_ServicePtr, lDemandStreamKey, lDTDProbDist, 00160 lPOSProbDist, lChannelProbDist, lTripProbDist, 00161 lStayProbDist, lFFProbDist, 00162 lChangeFees, lChangeFeeDisutility, 00163 lNonRefundable, lNonRefundableDisutility, 00164 lPrefDepTimeProbDist, 00165 lWTP, lTimeValueProbDist, lDemandDistribution, 00166 ioSharedGenerator.getBaseGenerator(), 00167 lRequestDateTimeSeed, 00168 lDemandCharacteristicsSeed, iPOSProbMass); 00169 00170 // Calculate the expected total number of events for the current 00171 // demand stream 00172 const stdair::NbOfRequests_T& lExpectedTotalNbOfEvents = 00173 lDemandStream.getMeanNumberOfRequests(); 00174 00178 ioSEVMGR_ServicePtr->addStatus (stdair::EventType::BKG_REQ, 00179 lExpectedTotalNbOfEvents); 00180 } 00181 00182 // ////////////////////////////////////////////////////////////////////// 00183 DemandStream& DemandManager::createDemandStream 00184 (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr, 00185 const DemandStreamKey& iKey, 00186 const ArrivalPatternCumulativeDistribution_T& iArrivalPattern, 00187 const POSProbabilityMassFunction_T& iPOSProbMass, 00188 const ChannelProbabilityMassFunction_T& iChannelProbMass, 00189 const TripTypeProbabilityMassFunction_T& iTripTypeProbMass, 00190 const StayDurationProbabilityMassFunction_T& iStayDurationProbMass, 00191 const FrequentFlyerProbabilityMassFunction_T& iFrequentFlyerProbMass, 00192 const stdair::ChangeFeesRatio_T& iChangeFeeProb, 00193 const stdair::Disutility_T& iChangeFeeDisutility, 00194 const stdair::NonRefundableRatio_T& iNonRefundableProb, 00195 const stdair::Disutility_T& iNonRefundableDisutility, 00196 const PreferredDepartureTimeContinuousDistribution_T& iPreferredDepartureTimeContinuousDistribution, 00197 const stdair::WTP_T& iMinWTP, 00198 const ValueOfTimeContinuousDistribution_T& iValueOfTimeContinuousDistribution, 00199 const DemandDistribution& iDemandDistribution, 00200 stdair::BaseGenerator_T& ioSharedGenerator, 00201 const stdair::RandomSeed_T& iRequestDateTimeSeed, 00202 const stdair::RandomSeed_T& iDemandCharacteristicsSeed, 00203 const POSProbabilityMass_T& iDefaultPOSProbablityMass) { 00204 00205 // Sanity check 00206 assert (ioSEVMGR_ServicePtr != NULL); 00207 00208 // 00209 DemandStream& oDemandStream = 00210 stdair::FacBom<DemandStream>::instance().create (iKey); 00211 00212 oDemandStream.setAll (iArrivalPattern, iPOSProbMass, 00213 iChannelProbMass, iTripTypeProbMass, 00214 iStayDurationProbMass, iFrequentFlyerProbMass, 00215 iChangeFeeProb, iChangeFeeDisutility, 00216 iNonRefundableProb, iNonRefundableDisutility, 00217 iPreferredDepartureTimeContinuousDistribution, 00218 iMinWTP, iValueOfTimeContinuousDistribution, 00219 iDemandDistribution, ioSharedGenerator, 00220 iRequestDateTimeSeed, iDemandCharacteristicsSeed, 00221 iDefaultPOSProbablityMass); 00222 00223 ioSEVMGR_ServicePtr->addEventGenerator (oDemandStream); 00224 00225 return oDemandStream; 00226 } 00227 00228 // ////////////////////////////////////////////////////////////////////// 00229 void DemandManager:: 00230 createDemandCharacteristics (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr, 00231 stdair::RandomGeneration& ioSharedGenerator, 00232 const POSProbabilityMass_T& iPOSProbMass, 00233 const DemandStruct& iDemand) { 00234 // Sanity check 00235 assert (ioSEVMGR_ServicePtr != NULL); 00236 00237 // 00238 stdair::BaseGenerator_T& lSharedGenerator = 00239 ioSharedGenerator.getBaseGenerator(); 00240 00241 // Parse the date period and DoW and generate demand characteristics. 00242 const stdair::DatePeriod_T lDateRange = iDemand._dateRange; 00243 for (boost::gregorian::day_iterator itDate = lDateRange.begin(); 00244 itDate != lDateRange.end(); ++itDate) { 00245 const stdair::Date_T& currentDate = *itDate; 00246 00247 // Retrieve, for the current day, the Day-Of-the-Week (thanks to Boost) 00248 const unsigned short currentDoW = currentDate.day_of_week().as_number(); 00249 00250 // The demand structure stores which Days (-Of-the-Week) are 00251 // active within the week. For each day (Mon., Tue., etc.), a boolean 00252 // states whether the Flight is active for that day. 00253 const stdair::DoWStruct& lDoWList = iDemand._dow; 00254 const bool isDoWActive = lDoWList.getStandardDayOfWeek (currentDoW); 00255 00256 if (isDoWActive == true) { 00257 const DemandStreamKey lDemandStreamKey (iDemand._origin, 00258 iDemand._destination, 00259 currentDate, 00260 iDemand._prefCabin); 00261 // DEBUG 00262 // STDAIR_LOG_DEBUG ("Demand stream key: " << lDemandStreamKey.describe()); 00263 00264 // 00265 const DemandDistribution lDemandDistribution (iDemand._demandMean, 00266 iDemand._demandStdDev); 00267 00268 // Seed 00269 const stdair::RandomSeed_T& lRequestDateTimeSeed = 00270 generateSeed (ioSharedGenerator); 00271 const stdair::RandomSeed_T& lDemandCharacteristicsSeed = 00272 generateSeed (ioSharedGenerator); 00273 00274 // Delegate the call to the dedicated command 00275 DemandStream& lDemandStream = 00276 createDemandStream (ioSEVMGR_ServicePtr, lDemandStreamKey, 00277 iDemand._dtdProbDist, iDemand._posProbDist, 00278 iDemand._channelProbDist, 00279 iDemand._tripProbDist, 00280 iDemand._stayProbDist, iDemand._ffProbDist, 00281 iDemand._changeFeeProb, 00282 iDemand._changeFeeDisutility, 00283 iDemand._nonRefundableProb, 00284 iDemand._nonRefundableDisutility, 00285 iDemand._prefDepTimeProbDist, 00286 iDemand._minWTP, 00287 iDemand._timeValueProbDist, 00288 lDemandDistribution, lSharedGenerator, 00289 lRequestDateTimeSeed, 00290 lDemandCharacteristicsSeed, 00291 iPOSProbMass); 00292 00293 // Calculate the expected total number of events for the current 00294 // demand stream 00295 const stdair::NbOfRequests_T& lExpectedTotalNbOfEvents = 00296 lDemandStream.getMeanNumberOfRequests(); 00297 00302 ioSEVMGR_ServicePtr->addStatus (stdair::EventType::BKG_REQ, 00303 lExpectedTotalNbOfEvents); 00304 } 00305 } 00306 } 00307 00308 // //////////////////////////////////////////////////////////////////// 00309 stdair::RandomSeed_T DemandManager:: 00310 generateSeed (stdair::RandomGeneration& ioSharedGenerator) { 00311 stdair::RealNumber_T lVariateUnif = ioSharedGenerator() * 1e9; 00312 stdair::RandomSeed_T oSeed = static_cast<stdair::RandomSeed_T>(lVariateUnif); 00313 return oSeed; 00314 } 00315 00316 // //////////////////////////////////////////////////////////////////// 00317 const bool DemandManager:: 00318 stillHavingRequestsToBeGenerated (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr, 00319 const stdair::DemandStreamKeyStr_T& iKey, 00320 stdair::ProgressStatusSet& ioPSS, 00321 const stdair::DemandGenerationMethod& iDemandGenerationMethod) { 00322 // Sanity check 00323 assert (ioSEVMGR_ServicePtr != NULL); 00324 00325 // Retrieve the DemandStream which corresponds to the given key. 00326 const DemandStream& lDemandStream = 00327 ioSEVMGR_ServicePtr->getEventGenerator<DemandStream,stdair::DemandStreamKeyStr_T>(iKey); 00328 00329 // Retrieve the progress status of the demand stream. 00330 stdair::ProgressStatus 00331 lProgressStatus (lDemandStream.getNumberOfRequestsGeneratedSoFar(), 00332 lDemandStream.getMeanNumberOfRequests(), 00333 lDemandStream.getTotalNumberOfRequestsToBeGenerated()); 00334 ioPSS.setSpecificGeneratorStatus (lProgressStatus, iKey); 00335 00336 return lDemandStream.stillHavingRequestsToBeGenerated (iDemandGenerationMethod); 00337 } 00338 00339 // //////////////////////////////////////////////////////////////////// 00340 stdair::BookingRequestPtr_T DemandManager:: 00341 generateNextRequest (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr, 00342 stdair::RandomGeneration& ioGenerator, 00343 const stdair::DemandStreamKeyStr_T& iKey, 00344 const stdair::DemandGenerationMethod& iDemandGenerationMethod) { 00345 // Sanity check 00346 assert (ioSEVMGR_ServicePtr != NULL); 00347 00348 // Retrieve the DemandStream which corresponds to the given key. 00349 DemandStream& lDemandStream = 00350 ioSEVMGR_ServicePtr->getEventGenerator<DemandStream,stdair::DemandStreamKeyStr_T>(iKey); 00351 00352 // Generate the next booking request 00353 stdair::BookingRequestPtr_T lBookingRequest = 00354 lDemandStream.generateNextRequest (ioGenerator, 00355 iDemandGenerationMethod); 00356 00357 const stdair::DateTime_T& lBookingRequestDateTime = 00358 lBookingRequest->getRequestDateTime(); 00359 const stdair::Date_T& lBookingRequestDate = 00360 lBookingRequestDateTime.date(); 00361 const stdair::Duration_T& lBookingRequestTime = 00362 lBookingRequestDateTime.time_of_day(); 00363 const stdair::Date_T& lPreferedDepartureDate = 00364 lBookingRequest->getPreferedDepartureDate(); 00365 const stdair::Duration_T& lPreferedDepartureTime = 00366 lBookingRequest->getPreferredDepartureTime(); 00367 00368 if ((lPreferedDepartureDate > lBookingRequestDate) || 00369 (lPreferedDepartureDate == lBookingRequestDate && 00370 lPreferedDepartureTime > lBookingRequestTime)) { 00371 00372 // Create an event structure 00373 stdair::EventStruct lEventStruct (stdair::EventType::BKG_REQ, 00374 lBookingRequest); 00375 00383 ioSEVMGR_ServicePtr->addEvent (lEventStruct); 00384 00385 } else { 00386 00387 // Update the expected number of eventss for the given event type (i.e., 00388 // booking request) 00389 stdair::Count_T lCurrentBRNumber = 00390 ioSEVMGR_ServicePtr->getActualTotalNumberOfEventsToBeGenerated (stdair::EventType::BKG_REQ); 00391 lCurrentBRNumber--; 00392 ioSEVMGR_ServicePtr->updateStatus (stdair::EventType::BKG_REQ, lCurrentBRNumber); 00393 00394 } 00395 00396 return lBookingRequest; 00397 } 00398 00399 // //////////////////////////////////////////////////////////////////// 00400 stdair::Count_T DemandManager:: 00401 generateFirstRequests (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr, 00402 stdair::RandomGeneration& ioGenerator, 00403 const stdair::DemandGenerationMethod& iDemandGenerationMethod) { 00404 // Sanity check 00405 assert (ioSEVMGR_ServicePtr != NULL); 00406 00407 // Actual total number of events to be generated 00408 stdair::NbOfRequests_T lActualTotalNbOfEvents = 0.0; 00409 00410 // Retrieve the DemandStream list 00411 const DemandStreamList_T& lDemandStreamList = 00412 ioSEVMGR_ServicePtr->getEventGeneratorList<DemandStream>(); 00413 00414 for (DemandStreamList_T::const_iterator itDemandStream = 00415 lDemandStreamList.begin(); 00416 itDemandStream != lDemandStreamList.end(); ++itDemandStream) { 00417 DemandStream* lDemandStream_ptr = *itDemandStream; 00418 assert (lDemandStream_ptr != NULL); 00419 00420 lDemandStream_ptr->setBoolFirstDateTimeRequest(true); 00421 00422 // Calculate the expected total number of events for the current 00423 // demand stream 00424 const stdair::NbOfRequests_T& lActualNbOfEvents = 00425 lDemandStream_ptr->getTotalNumberOfRequestsToBeGenerated(); 00426 lActualTotalNbOfEvents += lActualNbOfEvents; 00427 00428 // Retrieve the key of the demand stream 00429 const DemandStreamKey& lKey = lDemandStream_ptr->getKey(); 00430 00431 // Check whether there are still booking requests to be generated 00432 const bool stillHavingRequestsToBeGenerated = 00433 lDemandStream_ptr->stillHavingRequestsToBeGenerated (iDemandGenerationMethod); 00434 00435 if (stillHavingRequestsToBeGenerated) { 00436 // Generate the next event (booking request), and insert it 00437 // into the event queue 00438 generateNextRequest (ioSEVMGR_ServicePtr, ioGenerator, 00439 lKey.toString(), 00440 iDemandGenerationMethod); 00441 } 00442 } 00443 00444 // Update the progress status for the given event type (i.e., 00445 // booking request) 00446 ioSEVMGR_ServicePtr->updateStatus (stdair::EventType::BKG_REQ, 00447 lActualTotalNbOfEvents); 00448 00449 // Retrieve the actual total number of events to be generated 00450 const stdair::Count_T oTotalNbOfEvents = std::floor (lActualTotalNbOfEvents); 00451 00452 // 00453 return oTotalNbOfEvents; 00454 } 00455 00456 // //////////////////////////////////////////////////////////////////// 00457 void DemandManager::reset (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr, 00458 stdair::BaseGenerator_T& ioShareGenerator) { 00459 // Sanity check 00460 assert (ioSEVMGR_ServicePtr != NULL); 00461 00462 // TODO: check whether it is really necessary to destroy the 00463 // objects manually. Indeed, FacSupervisor::cleanAll() should 00464 // destroy any BOM object. 00465 00466 // Reset all the DemandStream objects 00467 const DemandStreamList_T& lDemandStreamList = 00468 ioSEVMGR_ServicePtr->getEventGeneratorList<DemandStream>(); 00469 for (DemandStreamList_T::const_iterator itDS = lDemandStreamList.begin(); 00470 itDS != lDemandStreamList.end(); ++itDS) { 00471 DemandStream* lCurrentDS_ptr = *itDS; 00472 assert (lCurrentDS_ptr != NULL); 00473 00474 lCurrentDS_ptr->reset (ioShareGenerator); 00475 } 00476 00484 ioSEVMGR_ServicePtr->reset(); 00485 } 00486 00487 // //////////////////////////////////////////////////////////////////// 00488 bool DemandManager:: 00489 generateCancellation (stdair::RandomGeneration& ioGenerator, 00490 const stdair::TravelSolutionStruct& iTravelSolution, 00491 const stdair::PartySize_T& iPartySize, 00492 const stdair::DateTime_T& iRequestTime, 00493 const stdair::Date_T& iDepartureDate, 00494 stdair::EventStruct& ioEventStruct) { 00495 00496 // Draw a random number to decide if we generate a 00497 // cancellation. For instance, the probability will be hardcoded. 00498 // The cancellation time will be generated uniformly. 00499 double lRandomNumber = ioGenerator(); 00500 00501 if (lRandomNumber >= 0.05) { 00502 return false; 00503 } 00504 lRandomNumber /= 0.05; 00505 00506 // Hardcode the latest cancellation time. 00507 const stdair::Time_T lMidNight = 00508 boost::posix_time::hours (0); 00509 const stdair::DateTime_T lDepartureDateTime = 00510 boost::posix_time::ptime (iDepartureDate, lMidNight); 00511 00512 // Time to departure. 00513 const stdair::Duration_T lTimeToDeparture = lDepartureDateTime-iRequestTime; 00514 00515 // Cancellation time to departure 00516 const long lTimeToDepartureInSeconds = lTimeToDeparture.total_seconds(); 00517 const long lCancellationTimeToDepartureInSeconds = 00518 static_cast<long> (lTimeToDepartureInSeconds * lRandomNumber); 00519 const stdair::Duration_T lCancellationTimeToDeparture (0, 0, lCancellationTimeToDepartureInSeconds); 00520 00521 // Cancellation time 00522 const stdair::DateTime_T lCancellationTime = 00523 lDepartureDateTime - lCancellationTimeToDeparture; 00524 const stdair::Duration_T lTimeBetweenCancellationAndTheRequest = 00525 lCancellationTime - iRequestTime; 00526 00527 if (lTimeBetweenCancellationAndTheRequest.is_negative() == true) { 00528 return false; 00529 } 00530 00531 // Build the list of Class ID's. 00532 stdair::BookingClassIDList_T lClassIDList; 00533 00534 const stdair::ClassObjectIDMapHolder_T& lClassObjectIDMapHolder = 00535 iTravelSolution.getClassObjectIDMapHolder(); 00536 const stdair::FareOptionStruct& lChosenFareOption = 00537 iTravelSolution.getChosenFareOption (); 00538 const stdair::ClassList_StringList_T& lClassPath = 00539 lChosenFareOption.getClassPath(); 00540 const stdair::SegmentPath_T& lSegmentPath = 00541 iTravelSolution.getSegmentPath(); 00542 stdair::ClassList_StringList_T::const_iterator itClassKeyList = 00543 lClassPath.begin(); 00544 for (stdair::ClassObjectIDMapHolder_T::const_iterator itClassObjectIDMap = 00545 lClassObjectIDMapHolder.begin(); 00546 itClassObjectIDMap != lClassObjectIDMapHolder.end(); 00547 ++itClassObjectIDMap, ++itClassKeyList) { 00548 const stdair::ClassObjectIDMap_T& lClassObjectIDMap = *itClassObjectIDMap; 00549 00550 // TODO: Remove this hard-coded part. 00551 std::ostringstream ostr; 00552 const stdair::ClassList_String_T& lClassList = *itClassKeyList; 00553 assert (lClassList.empty() == false); 00554 00555 ostr << lClassList.at(0); 00556 const stdair::ClassCode_T lClassCode (ostr.str()); 00557 00558 stdair::ClassObjectIDMap_T::const_iterator itClassID = 00559 lClassObjectIDMap.find (lClassCode); 00560 assert (itClassID != lClassObjectIDMap.end()); 00561 const stdair::BookingClassID_T& lClassID = itClassID->second; 00562 00563 lClassIDList.push_back (lClassID); 00564 00565 00566 } 00567 00568 // Create the cancellation. 00569 stdair::CancellationStruct lCancellationStruct (lSegmentPath, 00570 lClassIDList, 00571 iPartySize, 00572 lCancellationTime); 00573 00574 stdair::CancellationPtr_T lCancellation_ptr = 00575 boost::make_shared<stdair::CancellationStruct> (lCancellationStruct); 00576 00577 // Create an event structure 00578 stdair::EventStruct lEventStruct (stdair::EventType::CX, lCancellation_ptr); 00579 ioEventStruct = lEventStruct; 00580 00581 return true; 00582 } 00583 00584 // ////////////////////////////////////////////////////////////////////// 00585 void DemandManager:: 00586 buildSampleBom (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr, 00587 stdair::RandomGeneration& ioSharedGenerator, 00588 const POSProbabilityMass_T& iPOSProbMass) { 00589 // Sanity check 00590 assert (ioSEVMGR_ServicePtr != NULL); 00591 00592 // 00593 ArrivalPatternCumulativeDistribution_T lDTDProbDist; 00594 lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-330, 00595 0)); 00596 lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-150, 00597 0.1)); 00598 lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-92, 00599 0.2)); 00600 lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-55, 00601 0.3)); 00602 lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-34, 00603 0.4)); 00604 lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-21, 00605 0.5)); 00606 lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-12, 00607 0.6)); 00608 lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-6, 00609 0.7)); 00610 lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-3, 00611 0.8)); 00612 lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(-1, 00613 0.9)); 00614 lDTDProbDist.insert(ArrivalPatternCumulativeDistribution_T::value_type(0, 00615 1.0)); 00616 00617 // 00618 ChannelProbabilityMassFunction_T lChannelProbDist; 00619 lChannelProbDist.insert (ChannelProbabilityMassFunction_T::value_type ("DF", 00620 0.0)); 00621 lChannelProbDist.insert (ChannelProbabilityMassFunction_T::value_type ("DN", 00622 0.0)); 00623 lChannelProbDist.insert (ChannelProbabilityMassFunction_T::value_type ("IF", 00624 0.0)); 00625 lChannelProbDist.insert (ChannelProbabilityMassFunction_T::value_type ("IN", 00626 1.0)); 00627 00628 // 00629 TripTypeProbabilityMassFunction_T lTripProbDist; 00630 lTripProbDist.insert (TripTypeProbabilityMassFunction_T::value_type ("RO", 00631 0.0)); 00632 lTripProbDist.insert (TripTypeProbabilityMassFunction_T::value_type ("RI", 00633 0.0)); 00634 lTripProbDist.insert (TripTypeProbabilityMassFunction_T::value_type ("OW", 00635 1.0)); 00636 00637 // 00638 StayDurationProbabilityMassFunction_T lStayProbDist; 00639 lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(0, 00640 0.1)); 00641 lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(1, 00642 0.1)); 00643 lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(2, 00644 .15)); 00645 lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(3, 00646 .15)); 00647 lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(4, 00648 .15)); 00649 lStayProbDist.insert(StayDurationProbabilityMassFunction_T::value_type(5, 00650 .35)); 00651 00652 // 00653 FrequentFlyerProbabilityMassFunction_T lFFProbDist; 00654 lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("P", 00655 0.1)); 00656 lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("G", 00657 0.01)); 00658 lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("S", 00659 0.09)); 00660 lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("M", 00661 0.4)); 00662 lFFProbDist.insert(FrequentFlyerProbabilityMassFunction_T::value_type("N", 00663 0.4)); 00664 00665 // 00666 ValueOfTimeContinuousDistribution_T lTimeValueProbDist; 00667 lTimeValueProbDist.insert(ValueOfTimeContinuousDistribution_T::value_type(15, 00668 0)); 00669 lTimeValueProbDist.insert(ValueOfTimeContinuousDistribution_T::value_type(60, 00670 1)); 00671 00672 /*===================================================================================*/ 00673 00674 // Key of the demand stream 00675 const stdair::AirportCode_T lSINOrigin ("SIN"); 00676 const stdair::AirportCode_T lBKKDestination ("BKK"); 00677 const stdair::Date_T lDepDate (2010, 2, 8); 00678 const stdair::CabinCode_T lCabin ("Y"); 00679 00680 // 00681 const DemandStreamKey lSINBKKDemandStreamKey (lSINOrigin, lBKKDestination, lDepDate, 00682 lCabin); 00683 00684 // DEBUG 00685 // STDAIR_LOG_DEBUG ("Demand stream key: " << lDemandStreamKey.describe()); 00686 00687 // Distribution for the number of requests 00688 const stdair::MeanValue_T lSINBKKDemandMean (60.0); 00689 const stdair::StdDevValue_T lSINBKKDemandStdDev (4.0); 00690 const DemandDistribution lSINBKKDemandDistribution (lSINBKKDemandMean, lSINBKKDemandStdDev); 00691 00692 // Seed 00693 const stdair::RandomSeed_T& lSINBKKRequestDateTimeSeed = 00694 generateSeed (ioSharedGenerator); 00695 const stdair::RandomSeed_T& lSINBKKDemandCharacteristicsSeed = 00696 generateSeed (ioSharedGenerator); 00697 00698 00699 // 00700 POSProbabilityMassFunction_T lSINBKKPOSProbDist; 00701 lSINBKKPOSProbDist.insert (POSProbabilityMassFunction_T::value_type ("SIN", 1.0)); 00702 lSINBKKPOSProbDist.insert (POSProbabilityMassFunction_T::value_type ("BKK", 0.0)); 00703 00704 // 00705 PreferredDepartureTimeContinuousDistribution_T lSINPrefDepTimeProbDist; 00706 lSINPrefDepTimeProbDist. 00707 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (6 * stdair::HOUR_CONVERTED_IN_SECONDS, 0)); 00708 lSINPrefDepTimeProbDist. 00709 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (8 * stdair::HOUR_CONVERTED_IN_SECONDS, 00710 0.7)); 00711 lSINPrefDepTimeProbDist. 00712 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (10 * stdair::HOUR_CONVERTED_IN_SECONDS, 00713 0.8)); 00714 lSINPrefDepTimeProbDist. 00715 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (12 * stdair::HOUR_CONVERTED_IN_SECONDS, 00716 0.9)); 00717 lSINPrefDepTimeProbDist. 00718 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (14 * stdair::HOUR_CONVERTED_IN_SECONDS, 00719 1.0)); 00720 00721 // 00722 const stdair::WTP_T lSINBKKWTP (400.0); 00723 const stdair::ChangeFeesRatio_T lChangeFees (0.5); 00724 const stdair::Disutility_T lChangeFeeDisutility (50); 00725 const stdair::NonRefundableRatio_T lNonRefundable (0.5); 00726 const stdair::Disutility_T lNonRefundableDisutility (50); 00727 00728 00729 // Delegate the call to the dedicated command 00730 DemandStream& lSINBKKDemandStream = 00731 createDemandStream (ioSEVMGR_ServicePtr, lSINBKKDemandStreamKey, lDTDProbDist, 00732 lSINBKKPOSProbDist, lChannelProbDist, lTripProbDist, 00733 lStayProbDist, lFFProbDist, 00734 lChangeFees, lChangeFeeDisutility, 00735 lNonRefundable, lNonRefundableDisutility, 00736 lSINPrefDepTimeProbDist, 00737 lSINBKKWTP, lTimeValueProbDist, 00738 lSINBKKDemandDistribution, 00739 ioSharedGenerator.getBaseGenerator(), 00740 lSINBKKRequestDateTimeSeed, 00741 lSINBKKDemandCharacteristicsSeed, iPOSProbMass); 00742 00743 // Calculate the expected total number of events for the current 00744 // demand stream 00745 const stdair::NbOfRequests_T& lSINBKKExpectedNbOfEvents = 00746 lSINBKKDemandStream.getMeanNumberOfRequests(); 00747 00748 /*===================================================================================*/ 00749 00750 // Key of the demand stream 00751 const stdair::AirportCode_T lBKKOrigin ("BKK"); 00752 const stdair::AirportCode_T lHKGDestination ("HKG"); 00753 00754 // 00755 const DemandStreamKey lBKKHKGDemandStreamKey (lBKKOrigin, lHKGDestination, lDepDate, 00756 lCabin); 00757 00758 // DEBUG 00759 // STDAIR_LOG_DEBUG ("Demand stream key: " << lDemandStreamKey.describe()); 00760 00761 // Distribution for the number of requests 00762 const stdair::MeanValue_T lBKKHKGDemandMean (60.0); 00763 const stdair::StdDevValue_T lBKKHKGDemandStdDev (4.0); 00764 const DemandDistribution lBKKHKGDemandDistribution (lBKKHKGDemandMean, lBKKHKGDemandStdDev); 00765 00766 // Seed 00767 const stdair::RandomSeed_T& lBKKHKGRequestDateTimeSeed = 00768 generateSeed (ioSharedGenerator); 00769 const stdair::RandomSeed_T& lBKKHKGDemandCharacteristicsSeed = 00770 generateSeed (ioSharedGenerator); 00771 00772 00773 // 00774 POSProbabilityMassFunction_T lBKKHKGPOSProbDist; 00775 lBKKHKGPOSProbDist.insert (POSProbabilityMassFunction_T::value_type ("BKK", 1.0)); 00776 lBKKHKGPOSProbDist.insert (POSProbabilityMassFunction_T::value_type ("HKG", 0.0)); 00777 00778 // 00779 PreferredDepartureTimeContinuousDistribution_T lBKKPrefDepTimeProbDist; 00780 lBKKPrefDepTimeProbDist. 00781 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (8 * stdair::HOUR_CONVERTED_IN_SECONDS, 0)); 00782 lBKKPrefDepTimeProbDist. 00783 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (10 * stdair::HOUR_CONVERTED_IN_SECONDS, 00784 0.2)); 00785 lBKKPrefDepTimeProbDist. 00786 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (1 * stdair::HOUR_CONVERTED_IN_SECONDS, 00787 0.6)); 00788 lBKKPrefDepTimeProbDist. 00789 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (14 * stdair::HOUR_CONVERTED_IN_SECONDS, 00790 0.8)); 00791 lBKKPrefDepTimeProbDist. 00792 insert (PreferredDepartureTimeContinuousDistribution_T::value_type (16 * stdair::HOUR_CONVERTED_IN_SECONDS, 00793 1.0)); 00794 00795 // 00796 const stdair::WTP_T lBKKHKGWTP (400.0); 00797 00798 00799 // Delegate the call to the dedicated command 00800 DemandStream& lBKKHKGDemandStream = 00801 createDemandStream (ioSEVMGR_ServicePtr, lBKKHKGDemandStreamKey, lDTDProbDist, 00802 lBKKHKGPOSProbDist, lChannelProbDist, lTripProbDist, 00803 lStayProbDist, lFFProbDist, 00804 lChangeFees, lChangeFeeDisutility, 00805 lNonRefundable, lNonRefundableDisutility, 00806 lBKKPrefDepTimeProbDist, 00807 lBKKHKGWTP, lTimeValueProbDist, 00808 lBKKHKGDemandDistribution, 00809 ioSharedGenerator.getBaseGenerator(), 00810 lBKKHKGRequestDateTimeSeed, 00811 lBKKHKGDemandCharacteristicsSeed, iPOSProbMass); 00812 00813 // Calculate the expected total number of events for the current 00814 // demand stream 00815 const stdair::NbOfRequests_T& lBKKHKGExpectedNbOfEvents = 00816 lBKKHKGDemandStream.getMeanNumberOfRequests(); 00817 00818 /*===================================================================================*/ 00819 00820 // Key of the demand stream 00821 00822 // 00823 const DemandStreamKey lSINHKGDemandStreamKey (lSINOrigin, lHKGDestination, lDepDate, 00824 lCabin); 00825 00826 // DEBUG 00827 // STDAIR_LOG_DEBUG ("Demand stream key: " << lDemandStreamKey.describe()); 00828 00829 // Distribution for the number of requests 00830 const stdair::MeanValue_T lSINHKGDemandMean (60.0); 00831 const stdair::StdDevValue_T lSINHKGDemandStdDev (4.0); 00832 const DemandDistribution lSINHKGDemandDistribution (lSINHKGDemandMean, lSINHKGDemandStdDev); 00833 00834 // Seed 00835 const stdair::RandomSeed_T& lSINHKGRequestDateTimeSeed = 00836 generateSeed (ioSharedGenerator); 00837 const stdair::RandomSeed_T& lSINHKGDemandCharacteristicsSeed = 00838 generateSeed (ioSharedGenerator); 00839 00840 00841 // 00842 POSProbabilityMassFunction_T lSINHKGPOSProbDist; 00843 lSINHKGPOSProbDist.insert (POSProbabilityMassFunction_T::value_type ("SIN", 1.0)); 00844 lSINHKGPOSProbDist.insert (POSProbabilityMassFunction_T::value_type ("HKG", 0.0)); 00845 00846 // 00847 const stdair::WTP_T lSINHKGWTP (750.0); 00848 00849 00850 // Delegate the call to the dedicated command 00851 DemandStream& lSINHKGDemandStream = 00852 createDemandStream (ioSEVMGR_ServicePtr, lSINHKGDemandStreamKey, lDTDProbDist, 00853 lSINHKGPOSProbDist, lChannelProbDist, lTripProbDist, 00854 lStayProbDist, lFFProbDist, 00855 lChangeFees, lChangeFeeDisutility, 00856 lNonRefundable, lNonRefundableDisutility, 00857 lSINPrefDepTimeProbDist, 00858 lSINHKGWTP, lTimeValueProbDist, lSINHKGDemandDistribution, 00859 ioSharedGenerator.getBaseGenerator(), 00860 lSINHKGRequestDateTimeSeed, 00861 lSINHKGDemandCharacteristicsSeed, iPOSProbMass); 00862 00863 // Calculate the expected total number of events for the current 00864 // demand stream 00865 const stdair::NbOfRequests_T& lSINHKGExpectedNbOfEvents = 00866 lSINHKGDemandStream.getMeanNumberOfRequests(); 00867 00868 /*===================================================================================*/ 00869 00873 const stdair::NbOfRequests_T lExpectedTotalNbOfEvents = 00874 lSINBKKExpectedNbOfEvents + lBKKHKGExpectedNbOfEvents + lSINHKGExpectedNbOfEvents; 00875 ioSEVMGR_ServicePtr->addStatus (stdair::EventType::BKG_REQ, 00876 lExpectedTotalNbOfEvents); 00877 } 00878 00879 } 00880