$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/stdair_inventory_types.hpp> 00010 #include <stdair/basic/BasChronometer.hpp> 00011 #include <stdair/basic/ContinuousAttributeLite.hpp> 00012 #include <stdair/bom/BomManager.hpp> 00013 #include <stdair/bom/BomRetriever.hpp> 00014 #include <stdair/bom/BomRoot.hpp> 00015 #include <stdair/bom/Inventory.hpp> 00016 #include <stdair/bom/FlightDate.hpp> 00017 #include <stdair/bom/LegCabin.hpp> 00018 #include <stdair/bom/LegDate.hpp> 00019 #include <stdair/bom/YieldFeatures.hpp> 00020 #include <stdair/bom/AirportPair.hpp> 00021 #include <stdair/bom/PosChannel.hpp> 00022 #include <stdair/bom/DatePeriod.hpp> 00023 #include <stdair/bom/TimePeriod.hpp> 00024 #include <stdair/bom/AirlineClassList.hpp> 00025 #include <stdair/basic/BasConst_Request.hpp> 00026 #include <stdair/basic/BasConst_Inventory.hpp> 00027 #include <stdair/bom/Inventory.hpp> 00028 #include <stdair/bom/FlightDate.hpp> 00029 #include <stdair/bom/SegmentDate.hpp> 00030 #include <stdair/bom/SegmentCabin.hpp> 00031 #include <stdair/bom/BookingClass.hpp> 00032 #include <stdair/bom/OnDDate.hpp> 00033 #include <stdair/bom/OnDDateTypes.hpp> 00034 #include <stdair/command/CmdBomManager.hpp> 00035 #include <stdair/service/Logger.hpp> 00036 #include <stdair/STDAIR_Service.hpp> 00037 // RMOL 00038 #include <rmol/basic/BasConst_RMOL_Service.hpp> 00039 #include <rmol/factory/FacRmolServiceContext.hpp> 00040 #include <rmol/command/InventoryParser.hpp> 00041 #include <rmol/command/Optimiser.hpp> 00042 #include <rmol/command/PreOptimiser.hpp> 00043 #include <rmol/command/Forecaster.hpp> 00044 #include <rmol/service/RMOL_ServiceContext.hpp> 00045 #include <rmol/RMOL_Service.hpp> 00046 00047 namespace RMOL { 00048 00049 // //////////////////////////////////////////////////////////////////// 00050 RMOL_Service::RMOL_Service() 00051 : _rmolServiceContext (NULL), 00052 _previousForecastDate (stdair::Date_T (2000, 1, 1)) { 00053 assert (false); 00054 } 00055 00056 // //////////////////////////////////////////////////////////////////// 00057 RMOL_Service::RMOL_Service (const RMOL_Service& iService) : 00058 _rmolServiceContext (NULL), 00059 _previousForecastDate (stdair::Date_T (2000, 1, 1)) { 00060 assert (false); 00061 } 00062 00063 // //////////////////////////////////////////////////////////////////// 00064 RMOL_Service::RMOL_Service (const stdair::BasLogParams& iLogParams) : 00065 _rmolServiceContext (NULL), 00066 _previousForecastDate (stdair::Date_T (2000, 1, 1)) { 00067 00068 // Initialise the STDAIR service handler 00069 stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr = 00070 initStdAirService (iLogParams); 00071 00072 // Initialise the service context 00073 initServiceContext(); 00074 00075 // Add the StdAir service context to the RMOL service context 00076 // \note RMOL owns the STDAIR service resources here. 00077 const bool ownStdairService = true; 00078 addStdAirService (lSTDAIR_Service_ptr, ownStdairService); 00079 00080 // Initialise the (remaining of the) context 00081 initRmolService(); 00082 } 00083 00084 // //////////////////////////////////////////////////////////////////// 00085 RMOL_Service::RMOL_Service (const stdair::BasLogParams& iLogParams, 00086 const stdair::BasDBParams& iDBParams) : 00087 _rmolServiceContext (NULL), 00088 _previousForecastDate (stdair::Date_T (2000, 1, 1)) { 00089 00090 // Initialise the STDAIR service handler 00091 stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr = 00092 initStdAirService (iLogParams, iDBParams); 00093 00094 // Initialise the service context 00095 initServiceContext(); 00096 00097 // Add the StdAir service context to the RMOL service context 00098 // \note RMOL owns the STDAIR service resources here. 00099 const bool ownStdairService = true; 00100 addStdAirService (lSTDAIR_Service_ptr, ownStdairService); 00101 00102 // Initialise the (remaining of the) context 00103 initRmolService(); 00104 } 00105 00106 // //////////////////////////////////////////////////////////////////// 00107 RMOL_Service::RMOL_Service (stdair::STDAIR_ServicePtr_T ioSTDAIRServicePtr) 00108 : _rmolServiceContext (NULL), 00109 _previousForecastDate (stdair::Date_T (2000, 1, 1)) { 00110 00111 // Initialise the context 00112 initServiceContext(); 00113 00114 // Add the StdAir service context to the RMOL service context. 00115 // \note RMOL does not own the STDAIR service resources here. 00116 const bool doesNotOwnStdairService = false; 00117 addStdAirService (ioSTDAIRServicePtr, doesNotOwnStdairService); 00118 00119 // Initialise the (remaining of the) context 00120 initRmolService(); 00121 } 00122 00123 // //////////////////////////////////////////////////////////////////// 00124 RMOL_Service::~RMOL_Service() { 00125 // Delete/Clean all the objects from memory 00126 finalise(); 00127 } 00128 00129 // //////////////////////////////////////////////////////////////////// 00130 void RMOL_Service::finalise() { 00131 assert (_rmolServiceContext != NULL); 00132 // Reset the (Boost.)Smart pointer pointing on the STDAIR_Service object. 00133 _rmolServiceContext->reset(); 00134 } 00135 00136 // //////////////////////////////////////////////////////////////////// 00137 void RMOL_Service::initServiceContext() { 00138 // Initialise the service context 00139 RMOL_ServiceContext& lRMOL_ServiceContext = 00140 FacRmolServiceContext::instance().create(); 00141 _rmolServiceContext = &lRMOL_ServiceContext; 00142 } 00143 00144 // //////////////////////////////////////////////////////////////////// 00145 void RMOL_Service:: 00146 addStdAirService (stdair::STDAIR_ServicePtr_T ioSTDAIR_Service_ptr, 00147 const bool iOwnStdairService) { 00148 00149 // Retrieve the RMOL service context 00150 assert (_rmolServiceContext != NULL); 00151 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 00152 00153 // Store the STDAIR service object within the (AIRINV) service context 00154 lRMOL_ServiceContext.setSTDAIR_Service (ioSTDAIR_Service_ptr, 00155 iOwnStdairService); 00156 } 00157 00158 // //////////////////////////////////////////////////////////////////// 00159 stdair::STDAIR_ServicePtr_T RMOL_Service:: 00160 initStdAirService (const stdair::BasLogParams& iLogParams) { 00161 00169 stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr = 00170 boost::make_shared<stdair::STDAIR_Service> (iLogParams); 00171 00172 return lSTDAIR_Service_ptr; 00173 } 00174 00175 // ////////////////////////////////////////////////////////////////////// 00176 stdair::STDAIR_ServicePtr_T RMOL_Service:: 00177 initStdAirService (const stdair::BasLogParams& iLogParams, 00178 const stdair::BasDBParams& iDBParams) { 00179 00187 stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr = 00188 boost::make_shared<stdair::STDAIR_Service> (iLogParams, iDBParams); 00189 00190 return lSTDAIR_Service_ptr; 00191 } 00192 00193 // //////////////////////////////////////////////////////////////////// 00194 void RMOL_Service::initRmolService() { 00195 // Do nothing at this stage. A sample BOM tree may be built by 00196 // calling the buildSampleBom() method 00197 } 00198 00199 // //////////////////////////////////////////////////////////////////// 00200 void RMOL_Service:: 00201 parseAndLoad (const stdair::CabinCapacity_T& iCabinCapacity, 00202 const stdair::Filename_T& iInputFileName) { 00203 00204 // Retrieve the RMOL service context 00205 if (_rmolServiceContext == NULL) { 00206 throw stdair::NonInitialisedServiceException ("The RMOL service has not" 00207 " been initialised"); 00208 } 00209 assert (_rmolServiceContext != NULL); 00210 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 00211 const bool doesOwnStdairService = 00212 lRMOL_ServiceContext.getOwnStdairServiceFlag(); 00213 00214 // Retrieve the StdAir service object from the (RMOL) service context 00215 stdair::STDAIR_Service& lSTDAIR_Service = 00216 lRMOL_ServiceContext.getSTDAIR_Service(); 00217 stdair::BomRoot& lPersistentBomRoot = 00218 lSTDAIR_Service.getPersistentBomRoot(); 00219 00223 lSTDAIR_Service.buildDummyInventory (iCabinCapacity); 00224 00228 InventoryParser::parseInputFileAndBuildBom (iInputFileName, 00229 lPersistentBomRoot); 00230 00246 buildComplementaryLinks (lPersistentBomRoot); 00247 00252 if (doesOwnStdairService == true) { 00253 00254 // 00255 clonePersistentBom (); 00256 } 00257 } 00258 00259 // //////////////////////////////////////////////////////////////////// 00260 void RMOL_Service::buildSampleBom() { 00261 00262 // Retrieve the RMOL service context 00263 if (_rmolServiceContext == NULL) { 00264 throw stdair::NonInitialisedServiceException ("The RMOL service has not" 00265 " been initialised"); 00266 } 00267 assert (_rmolServiceContext != NULL); 00268 00269 // Retrieve the RMOL service context and whether it owns the Stdair 00270 // service 00271 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 00272 const bool doesOwnStdairService = 00273 lRMOL_ServiceContext.getOwnStdairServiceFlag(); 00274 00275 // Retrieve the StdAir service object from the (RMOL) service context 00276 stdair::STDAIR_Service& lSTDAIR_Service = 00277 lRMOL_ServiceContext.getSTDAIR_Service(); 00278 stdair::BomRoot& lPersistentBomRoot = 00279 lSTDAIR_Service.getPersistentBomRoot(); 00280 00285 if (doesOwnStdairService == true) { 00286 // 00287 lSTDAIR_Service.buildSampleBom(); 00288 } 00289 00305 buildComplementaryLinks (lPersistentBomRoot); 00306 00311 if (doesOwnStdairService == true) { 00312 00313 // 00314 clonePersistentBom (); 00315 } 00316 } 00317 00318 // //////////////////////////////////////////////////////////////////// 00319 void RMOL_Service::clonePersistentBom () { 00320 00321 // Retrieve the RMOL service context 00322 if (_rmolServiceContext == NULL) { 00323 throw stdair::NonInitialisedServiceException("The RMOL service has not " 00324 "been initialised"); 00325 } 00326 assert (_rmolServiceContext != NULL); 00327 00328 // Retrieve the RMOL service context and whether it owns the Stdair 00329 // service 00330 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 00331 const bool doesOwnStdairService = 00332 lRMOL_ServiceContext.getOwnStdairServiceFlag(); 00333 00334 // Retrieve the StdAir service object from the (RMOL) service context 00335 stdair::STDAIR_Service& lSTDAIR_Service = 00336 lRMOL_ServiceContext.getSTDAIR_Service(); 00337 00342 if (doesOwnStdairService == true) { 00343 00344 // 00345 lSTDAIR_Service.clonePersistentBom (); 00346 } 00347 00351 stdair::BomRoot& lBomRoot = 00352 lSTDAIR_Service.getBomRoot(); 00353 buildComplementaryLinks (lBomRoot); 00354 } 00355 00356 // //////////////////////////////////////////////////////////////////// 00357 void RMOL_Service::buildComplementaryLinks (stdair::BomRoot& ioBomRoot) { 00358 00359 // Retrieve the RMOL service context 00360 if (_rmolServiceContext == NULL) { 00361 throw stdair::NonInitialisedServiceException("The RMOL service has not " 00362 "been initialised"); 00363 } 00364 assert (_rmolServiceContext != NULL); 00365 00366 // Retrieve the RMOL service context and whether it owns the Stdair 00367 // service 00368 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 00369 00370 // Retrieve the StdAir service object from the (RMOL) service context 00371 stdair::STDAIR_Service& lSTDAIR_Service = 00372 lRMOL_ServiceContext.getSTDAIR_Service(); 00373 00378 lSTDAIR_Service.buildDummyLegSegmentAccesses (ioBomRoot); 00379 } 00380 00381 // //////////////////////////////////////////////////////////////////// 00382 void RMOL_Service::optimalOptimisationByMCIntegration (const int K) { 00383 assert (_rmolServiceContext != NULL); 00384 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 00385 00386 // Retrieve the StdAir service 00387 stdair::STDAIR_Service& lSTDAIR_Service = 00388 lRMOL_ServiceContext.getSTDAIR_Service(); 00389 // TODO: gsabatier 00390 // Replace the getPersistentBomRoot method by the getBomRoot method, 00391 // in order to work on the clone Bom root instead of the persistent one. 00392 // Does not work for now because virtual classes are not cloned. 00393 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getPersistentBomRoot(); 00394 00395 // 00396 stdair::LegCabin& lLegCabin = 00397 stdair::BomRetriever::retrieveDummyLegCabin (lBomRoot); 00398 00399 stdair::BasChronometer lOptimisationChronometer; 00400 lOptimisationChronometer.start(); 00401 00402 Optimiser::optimalOptimisationByMCIntegration (K, lLegCabin); 00403 00404 const double lOptimisationMeasure = lOptimisationChronometer.elapsed(); 00405 00406 // DEBUG 00407 STDAIR_LOG_DEBUG ("Optimisation by Monte-Carlo performed in " 00408 << lOptimisationMeasure); 00409 STDAIR_LOG_DEBUG ("Result: " << lLegCabin.displayVirtualClassList()); 00410 00411 std::ostringstream logStream; 00412 stdair::BidPriceVector_T lBidPriceVector = lLegCabin.getBidPriceVector(); 00413 logStream << "Bid-Price Vector (BPV): "; 00414 const unsigned int size = lBidPriceVector.size(); 00415 00416 for (unsigned int i = 0; i < size - 1; ++i) { 00417 const double bidPrice = lBidPriceVector.at(i); 00418 logStream << std::fixed << std::setprecision (2) << bidPrice << ", "; 00419 } 00420 const double bidPrice = lBidPriceVector.at(size -1); 00421 logStream << std::fixed << std::setprecision (2) << bidPrice; 00422 STDAIR_LOG_DEBUG (logStream.str()); 00423 } 00424 00425 // //////////////////////////////////////////////////////////////////// 00426 void RMOL_Service::optimalOptimisationByDP() { 00427 } 00428 00429 // //////////////////////////////////////////////////////////////////// 00430 void RMOL_Service::heuristicOptimisationByEmsr() { 00431 assert (_rmolServiceContext != NULL); 00432 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 00433 00434 // Retrieve the StdAir service 00435 stdair::STDAIR_Service& lSTDAIR_Service = 00436 lRMOL_ServiceContext.getSTDAIR_Service(); 00437 // TODO: gsabatier 00438 // Replace the getPersistentBomRoot method by the getBomRoot method, 00439 // in order to work on the clone Bom root instead of the persistent one. 00440 // Does not work for now because virtual classes are not cloned. 00441 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getPersistentBomRoot(); 00442 00443 // 00444 stdair::LegCabin& lLegCabin = 00445 stdair::BomRetriever::retrieveDummyLegCabin (lBomRoot); 00446 00447 stdair::BasChronometer lOptimisationChronometer; 00448 lOptimisationChronometer.start(); 00449 00450 Optimiser::heuristicOptimisationByEmsr (lLegCabin); 00451 00452 const double lOptimisationMeasure = lOptimisationChronometer.elapsed(); 00453 // DEBUG 00454 STDAIR_LOG_DEBUG ("Optimisation EMSR performed in " 00455 << lOptimisationMeasure); 00456 STDAIR_LOG_DEBUG ("Result: " << lLegCabin.displayVirtualClassList()); 00457 00458 stdair::BidPriceVector_T lBidPriceVector = lLegCabin.getBidPriceVector(); 00459 std::ostringstream logStream; 00460 logStream << "Bid-Price Vector (BPV): "; 00461 stdair::UnsignedIndex_T idx = 0; 00462 for (stdair::BidPriceVector_T::const_iterator itBP = lBidPriceVector.begin(); 00463 itBP != lBidPriceVector.end(); ++itBP) { 00464 if (idx != 0) { 00465 logStream << ", "; 00466 } 00467 const stdair::BidPrice_T& lBidPrice = *itBP; 00468 logStream << std::fixed << std::setprecision (2) << lBidPrice; 00469 } 00470 // DEBUG 00471 STDAIR_LOG_DEBUG (logStream.str()); 00472 } 00473 00474 // //////////////////////////////////////////////////////////////////// 00475 void RMOL_Service::heuristicOptimisationByEmsrA() { 00476 assert (_rmolServiceContext != NULL); 00477 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 00478 00479 // Retrieve the StdAir service 00480 stdair::STDAIR_Service& lSTDAIR_Service = 00481 lRMOL_ServiceContext.getSTDAIR_Service(); 00482 // TODO: gsabatier 00483 // Replace the getPersistentBomRoot method by the getBomRoot method, 00484 // in order to work on the clone Bom root instead of the persistent one. 00485 // Does not work for now because virtual classes are not cloned. 00486 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getPersistentBomRoot(); 00487 00488 // 00489 stdair::LegCabin& lLegCabin = 00490 stdair::BomRetriever::retrieveDummyLegCabin (lBomRoot); 00491 00492 Optimiser::heuristicOptimisationByEmsrA (lLegCabin); 00493 00494 // DEBUG 00495 STDAIR_LOG_DEBUG ("Result: " << lLegCabin.displayVirtualClassList()); 00496 00497 } 00498 00499 // //////////////////////////////////////////////////////////////////// 00500 void RMOL_Service::heuristicOptimisationByEmsrB() { 00501 assert (_rmolServiceContext != NULL); 00502 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 00503 00504 // Retrieve the StdAir service 00505 stdair::STDAIR_Service& lSTDAIR_Service = 00506 lRMOL_ServiceContext.getSTDAIR_Service(); 00507 // TODO: gsabatier 00508 // Replace the getPersistentBomRoot method by the getBomRoot method, 00509 // in order to work on the clone Bom root instead of the persistent one. 00510 // Does not work for now because virtual classes are not cloned. 00511 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getPersistentBomRoot(); 00512 00513 // 00514 stdair::LegCabin& lLegCabin = 00515 stdair::BomRetriever::retrieveDummyLegCabin (lBomRoot); 00516 00517 Optimiser::heuristicOptimisationByEmsrB (lLegCabin); 00518 00519 // DEBUG 00520 STDAIR_LOG_DEBUG ("Result: " << lLegCabin.displayVirtualClassList()); 00521 } 00522 00523 // //////////////////////////////////////////////////////////////////// 00524 const stdair::SegmentCabin& RMOL_Service:: 00525 retrieveDummySegmentCabin(const bool isForFareFamilies) { 00526 assert (_rmolServiceContext != NULL); 00527 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 00528 00529 // Retrieve the StdAir service 00530 stdair::STDAIR_Service& lSTDAIR_Service = 00531 lRMOL_ServiceContext.getSTDAIR_Service(); 00532 // TODO: gsabatier 00533 // Replace the getPersistentBomRoot method by the getBomRoot method, 00534 // in order to work on the clone Bom root instead of the persistent one. 00535 // Does not work for now because virtual classes are not cloned. 00536 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getPersistentBomRoot(); 00537 00538 const stdair::SegmentCabin& lSegmentCabin = 00539 stdair::BomRetriever::retrieveDummySegmentCabin(lBomRoot, 00540 isForFareFamilies); 00541 return lSegmentCabin; 00542 00543 } 00544 00545 // //////////////////////////////////////////////////////////////////// 00546 bool RMOL_Service:: 00547 optimise (stdair::FlightDate& ioFlightDate, 00548 const stdair::DateTime_T& iRMEventTime, 00549 const stdair::UnconstrainingMethod& iUnconstrainingMethod, 00550 const stdair::ForecastingMethod& iForecastingMethod, 00551 const stdair::PreOptimisationMethod& iPreOptimisationMethod, 00552 const stdair::OptimisationMethod& iOptimisationMethod, 00553 const stdair::PartnershipTechnique& iPartnershipTechnique) { 00554 00555 00556 STDAIR_LOG_DEBUG ("Forecast & Optimisation"); 00557 00558 const stdair::PartnershipTechnique::EN_PartnershipTechnique& lPartnershipTechnique = 00559 iPartnershipTechnique.getTechnique(); 00560 00561 switch (lPartnershipTechnique) { 00562 case stdair::PartnershipTechnique::NONE:{ 00563 // DEBUG 00564 STDAIR_LOG_DEBUG ("Forecast"); 00565 00566 // 1. Forecasting 00567 const bool isForecasted = Forecaster::forecast (ioFlightDate, 00568 iRMEventTime, 00569 iUnconstrainingMethod, 00570 iForecastingMethod); 00571 // DEBUG 00572 STDAIR_LOG_DEBUG ("Forecast successful: " << isForecasted); 00573 00574 if (isForecasted == true) { 00575 // 2a. MRT or FA 00576 // DEBUG 00577 STDAIR_LOG_DEBUG ("Pre-optimise"); 00578 00579 const bool isPreOptimised = 00580 PreOptimiser::preOptimise (ioFlightDate, iPreOptimisationMethod); 00581 00582 // DEBUG 00583 STDAIR_LOG_DEBUG ("Pre-Optimise successful: " << isPreOptimised); 00584 00585 if (isPreOptimised == true) { 00586 // 2b. Optimisation 00587 // DEBUG 00588 STDAIR_LOG_DEBUG ("Optimise"); 00589 const bool optimiseSucceeded = 00590 Optimiser::optimise (ioFlightDate, iOptimisationMethod); 00591 // DEBUG 00592 STDAIR_LOG_DEBUG ("Optimise successful: " << optimiseSucceeded); 00593 return optimiseSucceeded ; 00594 } 00595 } 00596 break; 00597 } 00598 case stdair::PartnershipTechnique::RAE_DA: 00599 case stdair::PartnershipTechnique::IBP_DA:{ 00600 if (_previousForecastDate < iRMEventTime.date()) { 00601 forecastOnD (iRMEventTime); 00602 resetDemandInformation (iRMEventTime); 00603 projectAggregatedDemandOnLegCabins (iRMEventTime); 00604 optimiseOnD (iRMEventTime); 00605 } 00606 break; 00607 } 00608 case stdair::PartnershipTechnique::RAE_YP: 00609 case stdair::PartnershipTechnique::IBP_YP: 00610 case stdair::PartnershipTechnique::IBP_YP_U:{ 00611 if (_previousForecastDate < iRMEventTime.date()) { 00612 forecastOnD (iRMEventTime); 00613 resetDemandInformation (iRMEventTime); 00614 projectOnDDemandOnLegCabinsUsingYP (iRMEventTime); 00615 optimiseOnD (iRMEventTime); 00616 } 00617 break; 00618 } 00619 case stdair::PartnershipTechnique::RMC:{ 00620 if (_previousForecastDate < iRMEventTime.date()) { 00621 forecastOnD (iRMEventTime); 00622 resetDemandInformation (iRMEventTime); 00623 updateBidPrice (iRMEventTime); 00624 projectOnDDemandOnLegCabinsUsingDYP (iRMEventTime); 00625 optimiseOnDUsingRMCooperation (iRMEventTime); 00626 } 00627 break; 00628 } 00629 case stdair::PartnershipTechnique::A_RMC:{ 00630 if (_previousForecastDate < iRMEventTime.date()) { 00631 forecastOnD (iRMEventTime); 00632 resetDemandInformation (iRMEventTime); 00633 updateBidPrice (iRMEventTime); 00634 projectOnDDemandOnLegCabinsUsingDYP (iRMEventTime); 00635 optimiseOnDUsingAdvancedRMCooperation (iRMEventTime); 00636 } 00637 break; 00638 } 00639 default:{ 00640 assert (false); 00641 break; 00642 } 00643 } 00644 return false; 00645 } 00646 00647 // //////////////////////////////////////////////////////////////////// 00648 void RMOL_Service::forecastOnD (const stdair::DateTime_T& iRMEventTime) { 00649 00650 if (_rmolServiceContext == NULL) { 00651 throw stdair::NonInitialisedServiceException ("The Rmol service " 00652 "has not been initialised"); 00653 } 00654 assert (_rmolServiceContext != NULL); 00655 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 00656 00657 // Retrieve the bom root 00658 stdair::STDAIR_Service& lSTDAIR_Service = 00659 lRMOL_ServiceContext.getSTDAIR_Service(); 00660 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot(); 00661 00662 // Retrieve the date from the RM event 00663 const stdair::Date_T lDate = iRMEventTime.date(); 00664 00665 _previousForecastDate = lDate; 00666 00667 const stdair::InventoryList_T& lInventoryList = 00668 stdair::BomManager::getList<stdair::Inventory> (lBomRoot); 00669 assert (!lInventoryList.empty()); 00670 for (stdair::InventoryList_T::const_iterator itInv = lInventoryList.begin(); 00671 itInv != lInventoryList.end(); ++itInv) { 00672 const stdair::Inventory* lInventory_ptr = *itInv; 00673 assert (lInventory_ptr != NULL); 00674 const bool hasOnDDateList = 00675 stdair::BomManager::hasList<stdair::OnDDate> (*lInventory_ptr); 00676 if (hasOnDDateList == true) { 00677 const stdair::OnDDateList_T lOnDDateList = 00678 stdair::BomManager::getList<stdair::OnDDate> (*lInventory_ptr); 00679 00680 for (stdair::OnDDateList_T::const_iterator itOD = lOnDDateList.begin(); 00681 itOD != lOnDDateList.end(); ++itOD) { 00682 stdair::OnDDate* lOnDDate_ptr = *itOD; 00683 assert (lOnDDate_ptr != NULL); 00684 00685 const stdair::Date_T& lDepartureDate = lOnDDate_ptr->getDate(); 00686 stdair::DateOffset_T lDateOffset = lDepartureDate - lDate; 00687 stdair::DTD_T lDTD = short (lDateOffset.days()); 00688 00689 stdair::DCPList_T::const_iterator itDCP = 00690 std::find (stdair::DEFAULT_DCP_LIST.begin(), 00691 stdair::DEFAULT_DCP_LIST.end(), lDTD); 00692 // Check if the forecast for this O&D date needs to be forecasted. 00693 if (itDCP != stdair::DEFAULT_DCP_LIST.end()) { 00694 // Retrieve the total forecast map. 00695 const stdair::CabinForecastMap_T& lTotalForecastMap = 00696 lOnDDate_ptr->getTotalForecastMap(); 00697 00698 // Browse the map and make a forecast for every cabin. 00699 for (stdair::CabinForecastMap_T::const_iterator itCF = 00700 lTotalForecastMap.begin(); 00701 itCF != lTotalForecastMap.end(); ++itCF) { 00702 const stdair::CabinCode_T lCabinCode = itCF->first; 00703 stdair::YieldFeatures* lYieldFeatures_ptr = 00704 getYieldFeatures(*lOnDDate_ptr, lCabinCode, lBomRoot); 00705 if (lYieldFeatures_ptr == NULL) { 00706 STDAIR_LOG_ERROR ("Cannot find yield corresponding to " 00707 << "the O&D date" 00708 << lOnDDate_ptr->toString() 00709 << " Cabin " << lCabinCode); 00710 assert (false); 00711 } 00712 forecastOnD (*lYieldFeatures_ptr, *lOnDDate_ptr, lCabinCode, lDTD, 00713 lBomRoot); 00714 } 00715 } 00716 } 00717 } 00718 } 00719 } 00720 00721 // /////////////////////////////////////////////////////////////////// 00722 stdair::YieldFeatures* RMOL_Service:: 00723 getYieldFeatures(const stdair::OnDDate& iOnDDate, 00724 const stdair::CabinCode_T& iCabinCode, 00725 stdair::BomRoot& iBomRoot) { 00726 00727 const stdair::AirportCode_T& lOrigin = iOnDDate.getOrigin(); 00728 const stdair::AirportCode_T& lDestination = iOnDDate.getDestination(); 00729 00730 const stdair::Date_T& lDepartureDate = iOnDDate.getDate(); 00731 00732 // Build the airport pair key out of O&D and get the airport pair object 00733 const stdair::AirportPairKey lAirportPairKey(lOrigin, lDestination); 00734 stdair::AirportPair* lAirportPair_ptr = stdair::BomManager:: 00735 getObjectPtr<stdair::AirportPair> (iBomRoot, 00736 lAirportPairKey.toString()); 00737 if (lAirportPair_ptr == NULL) { 00738 STDAIR_LOG_ERROR ("Cannot find yield corresponding to the airport " 00739 << "pair: " << lAirportPairKey.toString()); 00740 assert (false); 00741 } 00742 00743 // Retrieve the corresponding date period to lDepartureDate. 00744 const stdair::DatePeriodList_T lDatePeriodList = 00745 stdair::BomManager::getList<stdair::DatePeriod> (*lAirportPair_ptr); 00746 for (stdair::DatePeriodList_T::const_iterator itDatePeriod = 00747 lDatePeriodList.begin(); 00748 itDatePeriod != lDatePeriodList.end(); ++itDatePeriod) { 00749 const stdair::DatePeriod* lDatePeriod_ptr = *itDatePeriod; 00750 assert (lDatePeriod_ptr != NULL); 00751 00752 const bool isDepartureDateValid = 00753 lDatePeriod_ptr->isDepartureDateValid (lDepartureDate); 00754 00755 if (isDepartureDateValid == true) { 00756 // Retrieve the PoS-Channel. 00757 // TODO: Use POS and Channel from demand instead of default 00758 const stdair::PosChannelKey lPosChannelKey (stdair::DEFAULT_POS, 00759 stdair::DEFAULT_CHANNEL); 00760 stdair::PosChannel* lPosChannel_ptr = stdair::BomManager:: 00761 getObjectPtr<stdair::PosChannel> (*lDatePeriod_ptr, 00762 lPosChannelKey.toString()); 00763 if (lPosChannel_ptr == NULL) { 00764 STDAIR_LOG_ERROR ("Cannot find yield corresponding to the PoS-" 00765 << "Channel: " << lPosChannelKey.toString()); 00766 assert (false); 00767 } 00768 // Retrieve the yield features. 00769 const stdair::TimePeriodList_T lTimePeriodList = stdair:: 00770 BomManager::getList<stdair::TimePeriod> (*lPosChannel_ptr); 00771 for (stdair::TimePeriodList_T::const_iterator itTimePeriod = 00772 lTimePeriodList.begin(); 00773 itTimePeriod != lTimePeriodList.end(); ++itTimePeriod) { 00774 const stdair::TimePeriod* lTimePeriod_ptr = *itTimePeriod; 00775 assert (lTimePeriod_ptr != NULL); 00776 00777 // TODO: Use trip type from demand instead of default value. 00778 const stdair::YieldFeaturesKey lYieldFeaturesKey (stdair::TRIP_TYPE_ONE_WAY, 00779 iCabinCode); 00780 stdair::YieldFeatures* oYieldFeatures_ptr = stdair::BomManager:: 00781 getObjectPtr<stdair::YieldFeatures>(*lTimePeriod_ptr, 00782 lYieldFeaturesKey.toString()); 00783 if (oYieldFeatures_ptr != NULL) { 00784 return oYieldFeatures_ptr; 00785 } 00786 } 00787 } 00788 } 00789 return NULL; 00790 00791 } 00792 00793 00794 // /////////////////////////////////////////////////////////////////// 00795 void RMOL_Service:: 00796 forecastOnD (const stdair::YieldFeatures& iYieldFeatures, 00797 stdair::OnDDate& iOnDDate, 00798 const stdair::CabinCode_T& iCabinCode, 00799 const stdair::DTD_T& iDTD, 00800 stdair::BomRoot& iBomRoot) { 00801 00802 const stdair::AirlineClassListList_T lAirlineClassListList = 00803 stdair::BomManager::getList<stdair::AirlineClassList> (iYieldFeatures); 00804 assert (lAirlineClassListList.begin() != lAirlineClassListList.end()); 00805 00806 // Yield order check 00807 stdair::AirlineClassListList_T::const_iterator itACL = 00808 lAirlineClassListList.begin(); 00809 stdair::Yield_T lPreviousYield((*itACL)->getYield()); 00810 ++itACL; 00811 for (; itACL != lAirlineClassListList.end(); ++itACL) { 00812 const stdair::AirlineClassList* lAirlineClassList = *itACL; 00813 const stdair::Yield_T& lYield = lAirlineClassList->getYield(); 00814 if (lYield <= lPreviousYield) { 00815 lPreviousYield = lYield; 00816 } 00817 else{ 00818 STDAIR_LOG_ERROR ("Yields should be given in a descendant order" 00819 << " in the yield input file") ; 00820 assert (false); 00821 } 00822 } 00823 // Proportion factor list initialisation 00824 // Each element corresponds to a yield rule 00825 stdair::ProportionFactorList_T lProportionFactorList; 00826 stdair::ProportionFactor_T lPreviousProportionFactor = 0; 00827 00828 // Retrieve the minimal willingness to pay associated to the demand 00829 const stdair::WTPDemandPair_T& lTotalForecast = 00830 iOnDDate.getTotalForecast (iCabinCode); 00831 const stdair::WTP_T& lMinWTP = lTotalForecast.first; 00832 00833 // Retrieve the remaining percentage of booking requests 00834 const stdair::ContinuousAttributeLite<stdair::FloatDuration_T> 00835 lArrivalPattern (stdair::DEFAULT_DTD_PROB_MAP); 00836 00837 STDAIR_LOG_DEBUG (lArrivalPattern.displayCumulativeDistribution()); 00838 const stdair::Probability_T lRemainingProportion = 00839 lArrivalPattern.getRemainingProportion(-float(iDTD)); 00840 00841 // Compute the characteristics (mean and std dev) of the total 00842 // forecast demand to come 00843 const stdair::MeanStdDevPair_T lForecatsMeanStdDevPair = 00844 lTotalForecast.second; 00845 const stdair::MeanValue_T& lMeanValue = 00846 lForecatsMeanStdDevPair.first; 00847 const stdair::MeanValue_T& lRemainingMeanValue = 00848 lRemainingProportion*lMeanValue; 00849 const stdair::StdDevValue_T& lStdDevValue = 00850 lForecatsMeanStdDevPair.second; 00851 const stdair::StdDevValue_T& lRemainingStdDevValue = 00852 lRemainingProportion*lStdDevValue; 00853 00854 // Retrieve the frat5 coef corresponding to the input dtd 00855 stdair::DTDFratMap_T::const_iterator itDFC = 00856 stdair::DEFAULT_DTD_FRAT5COEF_MAP.find(iDTD); 00857 if (itDFC == stdair::DEFAULT_DTD_FRAT5COEF_MAP.end()) { 00858 STDAIR_LOG_ERROR ("Cannot find frat5 coef for DTD = " << iDTD ); 00859 assert (false); 00860 } 00861 stdair::RealNumber_T lFrat5Coef = 00862 stdair::DEFAULT_DTD_FRAT5COEF_MAP.at(iDTD); 00863 00864 STDAIR_LOG_DEBUG ("Remaining proportion " << lRemainingProportion 00865 << " Total " << lMeanValue 00866 << " StdDev " << lStdDevValue 00867 << "Frat5 Coef " << lFrat5Coef); 00868 00869 std::ostringstream oStr; 00870 // Compute the "forecast demand to come" proportion by class 00871 itACL = lAirlineClassListList.begin(); 00872 for (; itACL != lAirlineClassListList.end(); ++itACL) { 00873 const stdair::AirlineClassList* lAirlineClassList_ptr = *itACL; 00874 const stdair::Yield_T& lYield = lAirlineClassList_ptr->getYield(); 00875 stdair::ProportionFactor_T lProportionFactor = 00876 exp ((lYield - lMinWTP)*log(0.5)/(lMinWTP*(lFrat5Coef-1.0))); 00877 // If the yield is smaller than minimal WTP, the factor is greater than 1. 00878 // In that case it should be modified and put to 1. 00879 lProportionFactor = std::min (lProportionFactor, 1.0); 00880 lProportionFactorList.push_back(lProportionFactor - lPreviousProportionFactor); 00881 lPreviousProportionFactor = lProportionFactor; 00882 oStr << lAirlineClassList_ptr->toString() << lProportionFactor << " "; 00883 } 00884 00885 STDAIR_LOG_DEBUG (oStr.str()); 00886 00887 // Sanity check 00888 assert (lAirlineClassListList.size() == lProportionFactorList.size()); 00889 00890 STDAIR_LOG_DEBUG ("Forecast for " << iOnDDate.describeKey() 00891 << " " << iDTD << " days to departure"); 00892 00893 // store the forecast demand to come characteristics in the booking classes 00894 stdair::ProportionFactorList_T::const_iterator itPF = 00895 lProportionFactorList.begin(); 00896 itACL = lAirlineClassListList.begin(); 00897 for (; itACL != lAirlineClassListList.end(); ++itACL, ++itPF) { 00898 const stdair::AirlineClassList* lAirlineClassList_ptr = *itACL; 00899 const stdair::ProportionFactor_T& lProportionFactor = *itPF; 00900 stdair::MeanValue_T lMeanValue = lProportionFactor*lRemainingMeanValue; 00901 stdair::StdDevValue_T lStdDevValue = 00902 lProportionFactor*lRemainingStdDevValue; 00903 setOnDForecast(*lAirlineClassList_ptr, lMeanValue, lStdDevValue, 00904 iOnDDate, iCabinCode, iBomRoot); 00905 } 00906 00907 } 00908 00909 // /////////////////////////////////////////////////////////////////// 00910 void RMOL_Service:: 00911 setOnDForecast (const stdair::AirlineClassList& iAirlineClassList, 00912 const stdair::MeanValue_T& iMeanValue, 00913 const stdair::StdDevValue_T& iStdDevValue, 00914 stdair::OnDDate& iOnDDate, 00915 const stdair::CabinCode_T& iCabinCode, 00916 stdair::BomRoot& iBomRoot) { 00917 00918 const stdair::AirportCode_T& lOrigin = iOnDDate.getOrigin(); 00919 const stdair::AirportCode_T& lDestination = iOnDDate.getDestination(); 00920 00921 const stdair::Date_T& lDepartureDate = iOnDDate.getDate(); 00922 00923 const stdair::AirlineCodeList_T& lAirlineCodeList = 00924 iAirlineClassList.getAirlineCodeList(); 00925 00926 // Retrieve the class list (one class per airline) 00927 const stdair::ClassList_StringList_T& lClassList_StringList = 00928 iAirlineClassList.getClassCodeList(); 00929 assert (!lClassList_StringList.empty()); 00930 stdair::ClassCodeList_T lClassCodeList; 00931 for (stdair::ClassList_StringList_T::const_iterator itCL = 00932 lClassList_StringList.begin(); 00933 itCL != lClassList_StringList.end(); ++itCL){ 00934 const stdair::ClassList_String_T& lClassList_String = *itCL; 00935 assert (lClassList_String.size() > 0); 00936 stdair::ClassCode_T lFirstClass; 00937 lFirstClass.append (lClassList_String, 0, 1); 00938 lClassCodeList.push_back(lFirstClass); 00939 } 00940 00941 // Sanity check 00942 assert (lAirlineCodeList.size() == lClassCodeList.size()); 00943 assert (!lAirlineCodeList.empty()); 00944 00945 if (lAirlineCodeList.size() == 1) { 00946 // Store the forecast information in the case of a single segment 00947 stdair::AirlineCode_T lAirlineCode = lAirlineCodeList.front(); 00948 stdair::ClassCode_T lClassCode = lClassCodeList.front(); 00949 stdair::Yield_T lYield = iAirlineClassList.getYield(); 00950 setOnDForecast(lAirlineCode, lDepartureDate, lOrigin, 00951 lDestination, iCabinCode, lClassCode, 00952 iMeanValue, iStdDevValue, lYield, iBomRoot); 00953 } else { 00954 // Store the forecast information in the case of a multiple segment 00955 00956 stdair::Yield_T lYield = iAirlineClassList.getYield(); 00957 for (stdair::AirlineCodeList_T::const_iterator itAC = 00958 lAirlineCodeList.begin(); 00959 itAC != lAirlineCodeList.end(); ++itAC) { 00960 const stdair::AirlineCode_T& lAirlineCode = *itAC; 00961 setOnDForecast(lAirlineCodeList, lAirlineCode, lDepartureDate, lOrigin, 00962 lDestination, iCabinCode, lClassCodeList, 00963 iMeanValue, iStdDevValue, lYield, iBomRoot); 00964 } 00965 } 00966 } 00967 00968 // /////////////////////////////////////////////////////////////////// 00969 void RMOL_Service:: 00970 setOnDForecast (const stdair::AirlineCode_T& iAirlineCode, 00971 const stdair::Date_T& iDepartureDate, 00972 const stdair::AirportCode_T& iOrigin, 00973 const stdair::AirportCode_T& iDestination, 00974 const stdair::CabinCode_T& iCabinCode, 00975 const stdair::ClassCode_T& iClassCode, 00976 const stdair::MeanValue_T& iMeanValue, 00977 const stdair::StdDevValue_T& iStdDevValue, 00978 const stdair::Yield_T& iYield, 00979 stdair::BomRoot& iBomRoot) { 00980 stdair::Inventory* lInventory_ptr = iBomRoot.getInventory(iAirlineCode); 00981 if (lInventory_ptr == NULL) { 00982 STDAIR_LOG_ERROR ("Cannot find the inventory corresponding" 00983 << " to the airline" << iAirlineCode) ; 00984 assert(false); 00985 } 00986 const stdair::OnDDateList_T lOnDDateList = 00987 stdair::BomManager::getList<stdair::OnDDate> (*lInventory_ptr); 00988 assert (!lOnDDateList.empty()); 00989 bool lFoundOnDDate = false; 00990 for (stdair::OnDDateList_T::const_iterator itOD = lOnDDateList.begin(); 00991 itOD != lOnDDateList.end(); ++itOD) { 00992 stdair::OnDDate* lOnDDate_ptr = *itOD; 00993 assert (lOnDDate_ptr != NULL); 00994 const stdair::Date_T& lDepartureDate = lOnDDate_ptr->getDate(); 00995 const stdair::AirportCode_T& lOrigin = lOnDDate_ptr->getOrigin(); 00996 const stdair::AirportCode_T& lDestination = lOnDDate_ptr->getDestination(); 00997 const bool hasSegmentDateList = 00998 stdair::BomManager::hasList<stdair::SegmentDate> (*lOnDDate_ptr); 00999 if (hasSegmentDateList == false) { 01000 STDAIR_LOG_ERROR ("The O&D date " << lOnDDate_ptr->describeKey() 01001 << "has not been correctly initialized : SegmentDate list is missing"); 01002 assert (false); 01003 } 01004 const stdair::SegmentDateList_T& lSegmentDateList = 01005 stdair::BomManager::getList<stdair::SegmentDate> (*lOnDDate_ptr); 01006 // Check if the the O&D date is the one we are looking for 01007 if (lDepartureDate == iDepartureDate && lOrigin == iOrigin && 01008 lDestination == iDestination && lSegmentDateList.size() == 1) { 01009 stdair::CabinClassPair_T lCabinClassPair (iCabinCode, iClassCode); 01010 stdair::CabinClassPairList_T lCabinClassPairList; 01011 lCabinClassPairList.push_back(lCabinClassPair); 01012 const stdair::MeanStdDevPair_T lMeanStdDevPair (iMeanValue, iStdDevValue); 01013 const stdair::WTPDemandPair_T lWTPDemandPair (iYield, lMeanStdDevPair); 01014 lOnDDate_ptr->setDemandInformation(lCabinClassPairList, lWTPDemandPair); 01015 lFoundOnDDate = true; 01016 STDAIR_LOG_DEBUG (iAirlineCode << " Class " << iClassCode 01017 << " Mean " << iMeanValue 01018 << " Std Dev " << iStdDevValue); 01019 break; 01020 } 01021 } 01022 01023 if (!lFoundOnDDate) { 01024 STDAIR_LOG_ERROR ("Cannot find class " << iClassCode << " in cabin " 01025 << iCabinCode << " for the segment " 01026 << iOrigin << "-" << iDestination << " with" 01027 << " the airline " << iAirlineCode); 01028 assert(false); 01029 } 01030 } 01031 01032 // /////////////////////////////////////////////////////////////////// 01033 void RMOL_Service:: 01034 setOnDForecast (const stdair::AirlineCodeList_T& iAirlineCodeList, 01035 const stdair::AirlineCode_T& iAirlineCode, 01036 const stdair::Date_T& iDepartureDate, 01037 const stdair::AirportCode_T& iOrigin, 01038 const stdair::AirportCode_T& iDestination, 01039 const stdair::CabinCode_T& iCabinCode, 01040 const stdair::ClassCodeList_T& iClassCodeList, 01041 const stdair::MeanValue_T& iMeanValue, 01042 const stdair::StdDevValue_T& iStdDevValue, 01043 const stdair::Yield_T& iYield, 01044 stdair::BomRoot& iBomRoot) { 01045 stdair::Inventory* lInventory_ptr = iBomRoot.getInventory(iAirlineCode); 01046 if (lInventory_ptr == NULL) { 01047 STDAIR_LOG_ERROR ("Cannot find the inventory corresponding" 01048 << " to the airline" << iAirlineCode) ; 01049 assert(false); 01050 } 01051 const stdair::OnDDateList_T lOnDDateList = 01052 stdair::BomManager::getList<stdair::OnDDate> (*lInventory_ptr); 01053 assert (!lOnDDateList.empty()); 01054 bool lFoundOnDDate = false; 01055 for (stdair::OnDDateList_T::const_iterator itOD = lOnDDateList.begin(); 01056 itOD != lOnDDateList.end(); ++itOD) { 01057 stdair::OnDDate* lOnDDate_ptr = *itOD; 01058 assert (lOnDDate_ptr != NULL); 01059 const stdair::Date_T& lDepartureDate = lOnDDate_ptr->getDate(); 01060 const stdair::AirportCode_T& lOrigin = lOnDDate_ptr->getOrigin(); 01061 const stdair::AirportCode_T& lDestination = lOnDDate_ptr->getDestination(); 01062 const bool hasSegmentDateList = 01063 stdair::BomManager::hasList<stdair::SegmentDate> (*lOnDDate_ptr); 01064 if (hasSegmentDateList == false) { 01065 STDAIR_LOG_ERROR ("The O&D date " << lOnDDate_ptr->describeKey() 01066 << "has not been correctly initialized : SegmentDate list is missing"); 01067 assert (false); 01068 } 01069 const stdair::SegmentDateList_T& lSegmentDateList = 01070 stdair::BomManager::getList<stdair::SegmentDate> (*lOnDDate_ptr); 01071 // Check if the O&D date might be the one we are looking for. 01072 // There still is a test to go through to see if the combination of airlines is right. 01073 if (lDepartureDate == iDepartureDate && lOrigin == iOrigin && 01074 lDestination == iDestination && lSegmentDateList.size() == iAirlineCodeList.size()) { 01075 const stdair::SegmentDateList_T& lSegmentDateList = 01076 stdair::BomManager::getList<stdair::SegmentDate> (*lOnDDate_ptr); 01077 stdair::AirlineCodeList_T::const_iterator itAC = iAirlineCodeList.begin(); 01078 stdair::SegmentDateList_T::const_iterator itSD = lSegmentDateList.begin(); 01079 for (;itAC != iAirlineCodeList.end(); ++itAC, ++itSD) { 01080 const stdair::AirlineCode_T lForecastAirlineCode = *itAC; 01081 const stdair::SegmentDate* lSegmentDate_ptr = *itSD; 01082 // Check if the operating airline is a different one and check if it 01083 // is the airline that we are looking for. 01084 const stdair::SegmentDate* lOperatingSegmentDate_ptr = 01085 lSegmentDate_ptr->getOperatingSegmentDate (); 01086 if (lOperatingSegmentDate_ptr != NULL) { 01087 const stdair::FlightDate* lOperatingFD_ptr = 01088 stdair::BomManager::getParentPtr<stdair::FlightDate>(*lOperatingSegmentDate_ptr); 01089 const stdair::AirlineCode_T lOperatingAirlineCode = 01090 lOperatingFD_ptr->getAirlineCode(); 01091 if (lOperatingAirlineCode != lForecastAirlineCode) { 01092 break; 01093 } 01094 } else { 01095 const stdair::AirlineCode_T lOperatingAirlineCode = 01096 lOnDDate_ptr->getAirlineCode(); 01097 if (lOperatingAirlineCode != lForecastAirlineCode) { 01098 break; 01099 } 01100 } 01101 } 01102 if (itAC == iAirlineCodeList.end()) {lFoundOnDDate = true;} 01103 } 01104 if (lFoundOnDDate) { 01105 stdair::CabinClassPairList_T lCabinClassPairList; 01106 for (stdair::ClassCodeList_T::const_iterator itCC = iClassCodeList.begin(); 01107 itCC != iClassCodeList.end(); ++itCC) { 01108 const stdair::ClassCode_T lClassCode = *itCC; 01109 stdair::CabinClassPair_T lCabinClassPair (iCabinCode, lClassCode); 01110 lCabinClassPairList.push_back(lCabinClassPair); 01111 } 01112 const stdair::MeanStdDevPair_T lMeanStdDevPair (iMeanValue, iStdDevValue); 01113 const stdair::YieldDemandPair_T lYieldDemandPair (iYield, lMeanStdDevPair); 01114 lOnDDate_ptr->setDemandInformation(lCabinClassPairList, lYieldDemandPair); 01115 lFoundOnDDate = true; 01116 std::ostringstream oACStr; 01117 for (stdair::AirlineCodeList_T::const_iterator itAC = iAirlineCodeList.begin(); 01118 itAC != iAirlineCodeList.end(); ++itAC) { 01119 if (itAC == iAirlineCodeList.begin()) { 01120 oACStr << *itAC; 01121 } 01122 else { 01123 oACStr << "-" << *itAC; 01124 } 01125 } 01126 std::ostringstream oCCStr; 01127 for (stdair::ClassCodeList_T::const_iterator itCC = iClassCodeList.begin(); 01128 itCC != iClassCodeList.end(); ++itCC) { 01129 if (itCC == iClassCodeList.begin()) { 01130 oCCStr << *itCC; 01131 } 01132 else { 01133 oCCStr << "-" << *itCC; 01134 } 01135 } 01136 01137 STDAIR_LOG_DEBUG (oACStr.str() << " Classes " << oCCStr.str() 01138 << " Mean " << iMeanValue << " Std Dev " << iStdDevValue); 01139 break; 01140 } 01141 } 01142 if (!lFoundOnDDate) { 01143 STDAIR_LOG_ERROR ("Cannot find the required multi-segment O&D date: " 01144 << iOrigin << "-" << iDestination << " " << iDepartureDate); 01145 assert(false); 01146 } 01147 } 01148 01149 // /////////////////////////////////////////////////////////////////// 01150 void RMOL_Service:: 01151 resetDemandInformation (const stdair::DateTime_T& iRMEventTime) { 01152 if (_rmolServiceContext == NULL) { 01153 throw stdair::NonInitialisedServiceException ("The Rmol service " 01154 "has not been initialised"); 01155 } 01156 assert (_rmolServiceContext != NULL); 01157 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 01158 01159 // Retrieve the bom root 01160 stdair::STDAIR_Service& lSTDAIR_Service = 01161 lRMOL_ServiceContext.getSTDAIR_Service(); 01162 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot(); 01163 01164 const stdair::InventoryList_T lInventoryList = 01165 stdair::BomManager::getList<stdair::Inventory> (lBomRoot); 01166 assert (!lInventoryList.empty()); 01167 for (stdair::InventoryList_T::const_iterator itInv = lInventoryList.begin(); 01168 itInv != lInventoryList.end(); ++itInv) { 01169 const stdair::Inventory* lInventory_ptr = *itInv; 01170 assert (lInventory_ptr != NULL); 01171 resetDemandInformation (iRMEventTime, *lInventory_ptr); 01172 } 01173 } 01174 01175 // /////////////////////////////////////////////////////////////////// 01176 void RMOL_Service:: 01177 resetDemandInformation (const stdair::DateTime_T& iRMEventTime, 01178 const stdair::Inventory& iInventory) { 01179 01180 const stdair::FlightDateList_T lFlightDateList = 01181 stdair::BomManager::getList<stdair::FlightDate> (iInventory); 01182 assert (!lFlightDateList.empty()); 01183 for (stdair::FlightDateList_T::const_iterator itFD = lFlightDateList.begin(); 01184 itFD != lFlightDateList.end(); ++itFD) { 01185 const stdair::FlightDate* lFlightDate_ptr = *itFD; 01186 assert (lFlightDate_ptr != NULL); 01187 01188 // Retrieve the date from the RM event 01189 const stdair::Date_T lDate = iRMEventTime.date(); 01190 01191 const stdair::Date_T& lDepartureDate = lFlightDate_ptr->getDepartureDate(); 01192 stdair::DateOffset_T lDateOffset = lDepartureDate - lDate; 01193 stdair::DTD_T lDTD = short (lDateOffset.days()); 01194 01195 stdair::DCPList_T::const_iterator itDCP = 01196 std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD); 01197 // Check if the demand forecast info corresponding to this flight date needs to be reset. 01198 if (itDCP != stdair::DEFAULT_DCP_LIST.end()) { 01199 // Check if the flight date holds a list of leg dates. 01200 // If so, find all leg cabin and reset the forecast they are holding. 01201 const bool hasLegDateList = 01202 stdair::BomManager::hasList<stdair::LegDate> (*lFlightDate_ptr); 01203 if (hasLegDateList == true) { 01204 const stdair::LegDateList_T lLegDateList = 01205 stdair::BomManager::getList<stdair::LegDate> (*lFlightDate_ptr); 01206 assert (!lLegDateList.empty()); 01207 for (stdair::LegDateList_T::const_iterator itLD = lLegDateList.begin(); 01208 itLD != lLegDateList.end(); ++itLD) { 01209 const stdair::LegDate* lLegDate_ptr = *itLD; 01210 assert (lLegDate_ptr != NULL); 01211 const stdair::LegCabinList_T lLegCabinList = 01212 stdair::BomManager::getList<stdair::LegCabin> (*lLegDate_ptr); 01213 assert (!lLegCabinList.empty()); 01214 for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin(); 01215 itLC != lLegCabinList.end(); ++itLC) { 01216 stdair::LegCabin* lLegCabin_ptr = *itLC; 01217 assert (lLegCabin_ptr != NULL); 01218 lLegCabin_ptr->emptyYieldLevelDemandMap(); 01219 } 01220 } 01221 } 01222 } 01223 } 01224 } 01225 01226 // /////////////////////////////////////////////////////////////////// 01227 void RMOL_Service::projectAggregatedDemandOnLegCabins(const stdair::DateTime_T& iRMEventTime) { 01228 01229 if (_rmolServiceContext == NULL) { 01230 throw stdair::NonInitialisedServiceException ("The Rmol service " 01231 "has not been initialised"); 01232 } 01233 assert (_rmolServiceContext != NULL); 01234 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 01235 01236 // Retrieve the bom root 01237 stdair::STDAIR_Service& lSTDAIR_Service = 01238 lRMOL_ServiceContext.getSTDAIR_Service(); 01239 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot(); 01240 01241 // Retrieve the date from the RM event 01242 const stdair::Date_T lDate = iRMEventTime.date(); 01243 01244 const stdair::InventoryList_T lInventoryList = 01245 stdair::BomManager::getList<stdair::Inventory> (lBomRoot); 01246 assert (!lInventoryList.empty()); 01247 for (stdair::InventoryList_T::const_iterator itInv = lInventoryList.begin(); 01248 itInv != lInventoryList.end(); ++itInv) { 01249 const stdair::Inventory* lInventory_ptr = *itInv; 01250 assert (lInventory_ptr != NULL); 01251 const stdair::OnDDateList_T lOnDDateList = 01252 stdair::BomManager::getList<stdair::OnDDate> (*lInventory_ptr); 01253 assert (!lOnDDateList.empty()); 01254 for (stdair::OnDDateList_T::const_iterator itOD = lOnDDateList.begin(); 01255 itOD != lOnDDateList.end(); ++itOD) { 01256 stdair::OnDDate* lOnDDate_ptr = *itOD; 01257 assert (lOnDDate_ptr != NULL); 01258 01259 const stdair::Date_T& lDepartureDate = lOnDDate_ptr->getDate(); 01260 stdair::DateOffset_T lDateOffset = lDepartureDate - lDate; 01261 stdair::DTD_T lDTD = short (lDateOffset.days()); 01262 01263 stdair::DCPList_T::const_iterator itDCP = 01264 std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD); 01265 // Check if the forecast for this O&D date needs to be projected. 01266 if (itDCP != stdair::DEFAULT_DCP_LIST.end()) { 01267 01268 // Browse the demand info map. 01269 const stdair::StringDemandStructMap_T& lStringDemandStructMap = 01270 lOnDDate_ptr->getDemandInfoMap (); 01271 for (stdair::StringDemandStructMap_T::const_iterator itStrDS = lStringDemandStructMap.begin(); 01272 itStrDS != lStringDemandStructMap.end(); ++itStrDS) { 01273 std::string lCabinClassPath = itStrDS->first; 01274 const stdair::YieldDemandPair_T& lYieldDemandPair = 01275 itStrDS->second; 01276 const stdair::CabinClassPairList_T& lCabinClassPairList = 01277 lOnDDate_ptr->getCabinClassPairList(lCabinClassPath); 01278 const stdair::NbOfSegments_T& lNbOfSegments = lOnDDate_ptr->getNbOfSegments(); 01279 // Sanity check 01280 assert (lCabinClassPairList.size() == lNbOfSegments); 01281 01282 const stdair::SegmentDateList_T lOnDSegmentDateList = 01283 stdair::BomManager::getList<stdair::SegmentDate> (*lOnDDate_ptr); 01284 // Sanity check 01285 assert (lOnDSegmentDateList.size() == lNbOfSegments); 01286 stdair::CabinClassPairList_T::const_iterator itCCP = lCabinClassPairList.begin(); 01287 stdair::SegmentDateList_T::const_iterator itSD = lOnDSegmentDateList.begin(); 01288 for (; itSD != lOnDSegmentDateList.end(); ++itCCP, ++itSD) { 01289 const stdair::SegmentDate* lSegmentDate_ptr = *itSD; 01290 const stdair::SegmentDate* lOperatingSegmentDate_ptr = 01291 lSegmentDate_ptr->getOperatingSegmentDate (); 01292 assert (lSegmentDate_ptr != NULL); 01293 // Only operated legs receive the demand information. 01294 if (lOperatingSegmentDate_ptr == NULL) { 01295 const stdair::CabinCode_T lCabinCode = itCCP->first; 01296 const stdair::ClassCode_T lClassCode = itCCP->second; 01297 const stdair::SegmentCabin* lSegmentCabin_ptr = 01298 stdair::BomManager::getObjectPtr<stdair::SegmentCabin> (*lSegmentDate_ptr, 01299 lCabinCode); 01300 assert (lSegmentCabin_ptr != NULL); 01301 // Retrieve the booking class (level of aggregation of demand). 01302 // The yield of the class is assigned to all types of demand for it. 01303 const stdair::BookingClass* lBookingClass_ptr = 01304 stdair::BomManager::getObjectPtr<stdair::BookingClass> (*lSegmentCabin_ptr, 01305 lClassCode); 01306 assert (lBookingClass_ptr != NULL); 01307 const stdair::LegCabinList_T lLegCabinList = 01308 stdair::BomManager::getList<stdair::LegCabin> (*lSegmentCabin_ptr); 01309 assert (!lLegCabinList.empty()); 01310 const int lNbOfLegs = lLegCabinList.size(); 01311 // Determine the yield (equally distributed over legs). 01312 const stdair::Yield_T& lYield = lBookingClass_ptr->getYield()/lNbOfLegs; 01313 const stdair::MeanStdDevPair_T& lMeanStdDevPair = 01314 lYieldDemandPair.second; 01315 const stdair::MeanValue_T& lMeanValue = lMeanStdDevPair.first; 01316 const stdair::StdDevValue_T& lStdDevValue = lMeanStdDevPair.second; 01317 for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin(); 01318 itLC != lLegCabinList.end(); ++itLC) { 01319 stdair::LegCabin* lLegCabin_ptr = *itLC; 01320 assert (lLegCabin_ptr != NULL); 01321 lLegCabin_ptr->addDemandInformation (lYield, lMeanValue, lStdDevValue); 01322 } 01323 } 01324 } 01325 } 01326 } 01327 } 01328 } 01329 } 01330 01331 // /////////////////////////////////////////////////////////////////// 01332 void RMOL_Service::projectOnDDemandOnLegCabinsUsingYP(const stdair::DateTime_T& iRMEventTime) { 01333 01334 if (_rmolServiceContext == NULL) { 01335 throw stdair::NonInitialisedServiceException ("The Rmol service " 01336 "has not been initialised"); 01337 } 01338 assert (_rmolServiceContext != NULL); 01339 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 01340 01341 // Retrieve the bom root 01342 stdair::STDAIR_Service& lSTDAIR_Service = 01343 lRMOL_ServiceContext.getSTDAIR_Service(); 01344 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot(); 01345 01346 // Retrieve the date from the RM event 01347 const stdair::Date_T lDate = iRMEventTime.date(); 01348 01349 const stdair::InventoryList_T lInventoryList = 01350 stdair::BomManager::getList<stdair::Inventory> (lBomRoot); 01351 assert (!lInventoryList.empty()); 01352 for (stdair::InventoryList_T::const_iterator itInv = lInventoryList.begin(); 01353 itInv != lInventoryList.end(); ++itInv) { 01354 const stdair::Inventory* lInventory_ptr = *itInv; 01355 assert (lInventory_ptr != NULL); 01356 const stdair::OnDDateList_T lOnDDateList = 01357 stdair::BomManager::getList<stdair::OnDDate> (*lInventory_ptr); 01358 assert (!lOnDDateList.empty()); 01359 for (stdair::OnDDateList_T::const_iterator itOD = lOnDDateList.begin(); 01360 itOD != lOnDDateList.end(); ++itOD) { 01361 stdair::OnDDate* lOnDDate_ptr = *itOD; 01362 assert (lOnDDate_ptr != NULL); 01363 01364 const stdair::Date_T& lDepartureDate = lOnDDate_ptr->getDate(); 01365 stdair::DateOffset_T lDateOffset = lDepartureDate - lDate; 01366 stdair::DTD_T lDTD = short (lDateOffset.days()); 01367 01368 stdair::DCPList_T::const_iterator itDCP = 01369 std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD); 01370 // Check if the forecast for this O&D date needs to be projected. 01371 if (itDCP != stdair::DEFAULT_DCP_LIST.end()) { 01372 01373 // Browse the demand info map. 01374 const stdair::StringDemandStructMap_T& lStringDemandStructMap = 01375 lOnDDate_ptr->getDemandInfoMap (); 01376 for (stdair::StringDemandStructMap_T::const_iterator itStrDS = lStringDemandStructMap.begin(); 01377 itStrDS != lStringDemandStructMap.end(); ++itStrDS) { 01378 std::string lCabinClassPath = itStrDS->first; 01379 const stdair::YieldDemandPair_T& lYieldDemandPair = 01380 itStrDS->second; 01381 const stdair::CabinClassPairList_T& lCabinClassPairList = 01382 lOnDDate_ptr->getCabinClassPairList(lCabinClassPath); 01383 const stdair::NbOfSegments_T& lNbOfSegments = lOnDDate_ptr->getNbOfSegments(); 01384 // Sanity check 01385 assert (lCabinClassPairList.size() == lNbOfSegments); 01386 01387 const stdair::SegmentDateList_T lOnDSegmentDateList = 01388 stdair::BomManager::getList<stdair::SegmentDate> (*lOnDDate_ptr); 01389 // Sanity check 01390 assert (lOnDSegmentDateList.size() == lNbOfSegments); 01391 stdair::CabinClassPairList_T::const_iterator itCCP = lCabinClassPairList.begin(); 01392 stdair::SegmentDateList_T::const_iterator itSD = lOnDSegmentDateList.begin(); 01393 for (; itSD != lOnDSegmentDateList.end(); ++itCCP, ++itSD) { 01394 const stdair::SegmentDate* lSegmentDate_ptr = *itSD; 01395 assert (lSegmentDate_ptr != NULL); 01396 const stdair::SegmentDate* lOperatingSegmentDate_ptr = 01397 lSegmentDate_ptr->getOperatingSegmentDate (); 01398 // Only operated legs receive the demand information. 01399 if (lOperatingSegmentDate_ptr == NULL) { 01400 const stdair::CabinCode_T lCabinCode = itCCP->first; 01401 const stdair::ClassCode_T lClassCode = itCCP->second; 01402 const stdair::SegmentCabin* lSegmentCabin_ptr = 01403 stdair::BomManager::getObjectPtr<stdair::SegmentCabin> (*lSegmentDate_ptr, 01404 lCabinCode); 01405 assert (lSegmentCabin_ptr != NULL); 01406 const stdair::LegCabinList_T lLegCabinList = 01407 stdair::BomManager::getList<stdair::LegCabin> (*lSegmentCabin_ptr); 01408 assert (!lLegCabinList.empty()); 01409 const int lNbOfLegs = lLegCabinList.size(); 01410 // Determine the yield (equally distributed over segments and then legs). 01411 const stdair::MeanStdDevPair_T& lMeanStdDevPair = 01412 lYieldDemandPair.second; 01413 const stdair::Yield_T& lYield = lYieldDemandPair.first/(lNbOfLegs*lNbOfSegments); 01414 const stdair::MeanValue_T& lMeanValue = lMeanStdDevPair.first; 01415 const stdair::StdDevValue_T& lStdDevValue = lMeanStdDevPair.second; 01416 for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin(); 01417 itLC != lLegCabinList.end(); ++itLC) { 01418 stdair::LegCabin* lLegCabin_ptr = *itLC; 01419 assert (lLegCabin_ptr != NULL); 01420 lLegCabin_ptr->addDemandInformation (lYield, lMeanValue, lStdDevValue); 01421 } 01422 } 01423 } 01424 } 01425 } 01426 } 01427 } 01428 } 01429 01430 // /////////////////////////////////////////////////////////////////// 01431 void RMOL_Service::optimiseOnD (const stdair::DateTime_T& iRMEventTime) { 01432 01433 if (_rmolServiceContext == NULL) { 01434 throw stdair::NonInitialisedServiceException ("The Rmol service " 01435 "has not been initialised"); 01436 } 01437 assert (_rmolServiceContext != NULL); 01438 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 01439 01440 // Retrieve the bom root 01441 stdair::STDAIR_Service& lSTDAIR_Service = 01442 lRMOL_ServiceContext.getSTDAIR_Service(); 01443 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot(); 01444 01445 // Retrieve the date from the RM event 01446 const stdair::Date_T lDate = iRMEventTime.date(); 01447 01448 const stdair::InventoryList_T& lInvList = 01449 stdair::BomManager::getList<stdair::Inventory> (lBomRoot); 01450 for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin(); 01451 itInv != lInvList.end(); ++itInv) { 01452 stdair::Inventory* lCurrentInv_ptr = *itInv; 01453 assert (lCurrentInv_ptr != NULL); 01454 01455 const stdair::FlightDateList_T& lFlightDateList = 01456 stdair::BomManager::getList<stdair::FlightDate> (*lCurrentInv_ptr); 01457 for (stdair::FlightDateList_T::const_iterator itFlightDate = 01458 lFlightDateList.begin(); 01459 itFlightDate != lFlightDateList.end(); ++itFlightDate) { 01460 stdair::FlightDate* lCurrentFlightDate_ptr = *itFlightDate; 01461 assert (lCurrentFlightDate_ptr != NULL); 01462 01463 const stdair::Date_T& lCurrentDepartureDate = lCurrentFlightDate_ptr->getDepartureDate(); 01464 stdair::DateOffset_T lDateOffset = lCurrentDepartureDate - lDate; 01465 stdair::DTD_T lDTD = short (lDateOffset.days()); 01466 01467 stdair::DCPList_T::const_iterator itDCP = 01468 std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD); 01469 // Check if the optimisation is needed. 01470 if (itDCP != stdair::DEFAULT_DCP_LIST.end()) { 01471 STDAIR_LOG_DEBUG ("Optimisation using O&D forecast: " << lCurrentInv_ptr->getAirlineCode() 01472 << " Departure " << lCurrentDepartureDate << " DTD " << lDTD); 01473 Optimiser::optimiseUsingOnDForecast (*lCurrentFlightDate_ptr); 01474 } 01475 } 01476 } 01477 } 01478 01479 // /////////////////////////////////////////////////////////////////// 01480 void RMOL_Service::updateBidPrice (const stdair::DateTime_T& iRMEventTime) { 01481 01482 if (_rmolServiceContext == NULL) { 01483 throw stdair::NonInitialisedServiceException ("The Rmol service " 01484 "has not been initialised"); 01485 } 01486 assert (_rmolServiceContext != NULL); 01487 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 01488 01489 // Retrieve the bom root 01490 stdair::STDAIR_Service& lSTDAIR_Service = 01491 lRMOL_ServiceContext.getSTDAIR_Service(); 01492 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot(); 01493 01494 // Retrieve the date from the RM event 01495 const stdair::Date_T lDate = iRMEventTime.date(); 01496 01497 const stdair::InventoryList_T& lInvList = 01498 stdair::BomManager::getList<stdair::Inventory> (lBomRoot); 01499 01500 for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin(); 01501 itInv != lInvList.end(); ++itInv) { 01502 stdair::Inventory* lCurrentInv_ptr = *itInv; 01503 assert (lCurrentInv_ptr != NULL); 01504 01505 const stdair::FlightDateList_T& lFlightDateList = 01506 stdair::BomManager::getList<stdair::FlightDate> (*lCurrentInv_ptr); 01507 for (stdair::FlightDateList_T::const_iterator itFlightDate = 01508 lFlightDateList.begin(); 01509 itFlightDate != lFlightDateList.end(); ++itFlightDate) { 01510 stdair::FlightDate* lCurrentFlightDate_ptr = *itFlightDate; 01511 assert (lCurrentFlightDate_ptr != NULL); 01512 01513 const stdair::Date_T& lCurrentDepartureDate = lCurrentFlightDate_ptr->getDepartureDate(); 01514 stdair::DateOffset_T lDateOffset = lCurrentDepartureDate - lDate; 01515 stdair::DTD_T lDTD = short (lDateOffset.days()); 01516 01517 stdair::DCPList_T::const_iterator itDCP = 01518 std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD); 01519 // Check if the operation is needed. 01520 if (itDCP != stdair::DEFAULT_DCP_LIST.end()) { 01521 updateBidPrice (*lCurrentFlightDate_ptr, lBomRoot); 01522 } 01523 } 01524 } 01525 } 01526 01527 // /////////////////////////////////////////////////////////////////// 01528 void RMOL_Service::updateBidPrice (const stdair::FlightDate& iFlightDate, 01529 stdair::BomRoot& iBomRoot) { 01530 const stdair::SegmentDateList_T& lSegmentDateList = 01531 stdair::BomManager::getList<stdair::SegmentDate> (iFlightDate); 01532 const stdair::AirlineCode_T& lOptAC = iFlightDate.getAirlineCode(); 01533 const std::string lFDKeyStr = iFlightDate.describeKey(); 01534 01535 for (stdair::SegmentDateList_T::const_iterator itSegmentDate = lSegmentDateList.begin(); 01536 itSegmentDate != lSegmentDateList.end(); ++itSegmentDate) { 01537 stdair::SegmentDate* lSegmentDate_ptr = *itSegmentDate; 01538 assert (lSegmentDate_ptr != NULL); 01539 const bool hasSegmentDateList = 01540 stdair::BomManager::hasList<stdair::SegmentDate>(*lSegmentDate_ptr); 01541 if (hasSegmentDateList == true) { 01542 const stdair::LegDateList_T& lLegDateList = 01543 stdair::BomManager::getList<stdair::LegDate>(*lSegmentDate_ptr); 01544 // Get the list of marketing carriers segments. 01545 // These are part of maketing partners inventories images held by the operating airline. 01546 const stdair::SegmentDateList_T& lMktSegmentDateList = 01547 stdair::BomManager::getList<stdair::SegmentDate>(*lSegmentDate_ptr); 01548 for (stdair::SegmentDateList_T::const_iterator itMktSD = lMktSegmentDateList.begin(); 01549 itMktSD != lMktSegmentDateList.end(); ++itMktSD) { 01550 // Get the marketing airline code. 01551 stdair::SegmentDate* lMktSD_ptr = *itMktSD; 01552 assert (lMktSD_ptr != NULL); 01553 stdair::FlightDate* lMktFD_ptr = 01554 stdair::BomManager::getParentPtr<stdair::FlightDate>(*lMktSD_ptr); 01555 assert (lMktFD_ptr != NULL); 01556 const stdair::AirlineCode_T& lMktAC = lMktFD_ptr->getAirlineCode(); 01557 // Get the (real) marketer inventory. 01558 const stdair::Inventory* lMktInv_ptr = 01559 stdair::BomManager::getObjectPtr<stdair::Inventory>(iBomRoot,lMktAC); 01560 assert (lMktInv_ptr != NULL); 01561 // Get the image of the operating airline inventory held by the marketer. 01562 const stdair::Inventory* lOptInv_ptr = 01563 stdair::BomManager::getObjectPtr<stdair::Inventory>(*lMktInv_ptr,lOptAC); 01564 assert (lOptInv_ptr != NULL); 01565 // Find the image of the concerned flight date. 01566 const stdair::FlightDate* lOptFD_ptr = 01567 stdair::BomManager::getObjectPtr<stdair::FlightDate>(*lOptInv_ptr,lFDKeyStr); 01568 assert (lOptFD_ptr != NULL); 01569 // Browse the list of leg dates in the real operating inventory. 01570 // Retrieve the image of each leg date. 01571 for (stdair::LegDateList_T::const_iterator itLD = lLegDateList.begin(); 01572 itLD != lLegDateList.end(); ++itLD) { 01573 const stdair::LegDate* lLD_ptr = *itLD; 01574 assert (lLD_ptr != NULL); 01575 const std::string lLDKeyStr = lLD_ptr->describeKey(); 01576 stdair::LegDate* lOptLD_ptr = 01577 stdair::BomManager::getObjectPtr<stdair::LegDate>(*lOptFD_ptr,lLDKeyStr); 01578 assert (lOptLD_ptr != NULL); 01579 const stdair::LegCabinList_T& lLegCabinList_T = 01580 stdair::BomManager::getList<stdair::LegCabin>(*lLD_ptr); 01581 // Browse the list of leg cabins in the real operating inventory. 01582 // Retrieve the image of each leg cabin and update the bid price of the real and send it to the image. 01583 for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList_T.begin(); 01584 itLC != lLegCabinList_T.end(); ++itLC) { 01585 stdair::LegCabin* lLC_ptr = *itLC; 01586 assert (lLC_ptr != NULL); 01587 const std::string lLCKeyStr = lLC_ptr->describeKey(); 01588 stdair::LegCabin* lOptLC_ptr = 01589 stdair::BomManager::getObjectPtr<stdair::LegCabin>(*lOptLD_ptr, lLCKeyStr); 01590 assert (lOptLC_ptr != NULL); 01591 // Update the current bid price of the real leg. 01592 lLC_ptr->updateCurrentBidPrice(); 01593 // Update the previous bid price (store the current). 01594 lOptLC_ptr->updatePreviousBidPrice(); 01595 // Update the current bid price. 01596 lOptLC_ptr->setCurrentBidPrice (lLC_ptr->getCurrentBidPrice()); 01597 01598 STDAIR_LOG_DEBUG ("Update bid price of " << lLC_ptr->getFullerKey() 01599 << " : " << lOptLC_ptr->getCurrentBidPrice() 01600 << " Availability pool " << lLC_ptr->getAvailabilityPool()); 01601 } 01602 } 01603 } 01604 } 01605 } 01606 } 01607 01608 // /////////////////////////////////////////////////////////////////// 01609 void RMOL_Service::projectOnDDemandOnLegCabinsUsingDA(const stdair::DateTime_T& iRMEventTime) { 01610 01611 if (_rmolServiceContext == NULL) { 01612 throw stdair::NonInitialisedServiceException ("The Rmol service " 01613 "has not been initialised"); 01614 } 01615 assert (_rmolServiceContext != NULL); 01616 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 01617 01618 // Retrieve the bom root 01619 stdair::STDAIR_Service& lSTDAIR_Service = 01620 lRMOL_ServiceContext.getSTDAIR_Service(); 01621 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot(); 01622 01623 // Retrieve the date from the RM event 01624 const stdair::Date_T lDate = iRMEventTime.date(); 01625 01626 const stdair::InventoryList_T lInventoryList = 01627 stdair::BomManager::getList<stdair::Inventory> (lBomRoot); 01628 assert (!lInventoryList.empty()); 01629 for (stdair::InventoryList_T::const_iterator itInv = lInventoryList.begin(); 01630 itInv != lInventoryList.end(); ++itInv) { 01631 const stdair::Inventory* lInventory_ptr = *itInv; 01632 assert (lInventory_ptr != NULL); 01633 const stdair::OnDDateList_T lOnDDateList = 01634 stdair::BomManager::getList<stdair::OnDDate> (*lInventory_ptr); 01635 assert (!lOnDDateList.empty()); 01636 for (stdair::OnDDateList_T::const_iterator itOD = lOnDDateList.begin(); 01637 itOD != lOnDDateList.end(); ++itOD) { 01638 stdair::OnDDate* lOnDDate_ptr = *itOD; 01639 assert (lOnDDate_ptr != NULL); 01640 01641 const stdair::Date_T& lDepartureDate = lOnDDate_ptr->getDate(); 01642 stdair::DateOffset_T lDateOffset = lDepartureDate - lDate; 01643 stdair::DTD_T lDTD = short (lDateOffset.days()); 01644 01645 stdair::DCPList_T::const_iterator itDCP = 01646 std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD); 01647 // Check if the forecast for this O&D date needs to be projected. 01648 if (itDCP != stdair::DEFAULT_DCP_LIST.end()) { 01649 01650 // Browse the demand info map. 01651 const stdair::StringDemandStructMap_T& lStringDemandStructMap = 01652 lOnDDate_ptr->getDemandInfoMap (); 01653 for (stdair::StringDemandStructMap_T::const_iterator itStrDS = lStringDemandStructMap.begin(); 01654 itStrDS != lStringDemandStructMap.end(); ++itStrDS) { 01655 std::string lCabinClassPath = itStrDS->first; 01656 const stdair::YieldDemandPair_T& lYieldDemandPair = itStrDS->second; 01657 const stdair::CabinClassPairList_T& lCabinClassPairList = 01658 lOnDDate_ptr->getCabinClassPairList(lCabinClassPath); 01659 const stdair::NbOfSegments_T& lNbOfSegments = lOnDDate_ptr->getNbOfSegments(); 01660 // Sanity check 01661 assert (lCabinClassPairList.size() == lNbOfSegments); 01662 01663 // 01664 const stdair::SegmentDateList_T lOnDSegmentDateList = 01665 stdair::BomManager::getList<stdair::SegmentDate> (*lOnDDate_ptr); 01666 // Sanity check 01667 assert (lOnDSegmentDateList.size() == lNbOfSegments); 01668 stdair::CabinClassPairList_T::const_iterator itCCP = lCabinClassPairList.begin(); 01669 stdair::SegmentDateList_T::const_iterator itSD = lOnDSegmentDateList.begin(); 01670 // List of bid prices that will be used to easily compute displacement-ajusted yields. 01671 std::list<stdair::BidPrice_T> lBidPriceList; 01672 // The sum of bid prices that will be stored in the list above. 01673 stdair::BidPrice_T lTotalBidPrice = 0; 01674 // Retrieve the bid prices 01675 for (; itSD != lOnDSegmentDateList.end(); ++itCCP, ++itSD) { 01676 // Get the operating segment cabin (it holds the bid price information). 01677 const stdair::SegmentDate* lSegmentDate_ptr = *itSD; 01678 assert (lSegmentDate_ptr != NULL); 01679 // Get the operating airline code and check if it is the airline we are looking for. 01680 const stdair::SegmentDate* lOperatingSegmentDate_ptr = 01681 lSegmentDate_ptr->getOperatingSegmentDate (); 01682 if (lOperatingSegmentDate_ptr != NULL) { 01683 lSegmentDate_ptr = lOperatingSegmentDate_ptr; 01684 } 01685 const stdair::CabinCode_T lCabinCode = itCCP->first; 01686 const stdair::SegmentCabin* lSegmentCabin_ptr = 01687 stdair::BomManager::getObjectPtr<stdair::SegmentCabin> (*lSegmentDate_ptr, 01688 lCabinCode); 01689 assert (lSegmentCabin_ptr != NULL); 01690 stdair::BidPrice_T lBidPrice = 0; 01691 const stdair::LegCabinList_T lLegCabinList = 01692 stdair::BomManager::getList<stdair::LegCabin>(*lSegmentCabin_ptr); 01693 for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin(); 01694 itLC != lLegCabinList.end(); ++itLC) { 01695 const stdair::LegCabin* lLegCabin_ptr = *itLC; 01696 assert (lLegCabin_ptr != NULL); 01697 lBidPrice += lLegCabin_ptr->getCurrentBidPrice(); 01698 } 01699 lBidPriceList.push_back (lBidPrice); 01700 lTotalBidPrice += lBidPrice; 01701 } 01702 01703 01704 itCCP = lCabinClassPairList.begin(); 01705 itSD = lOnDSegmentDateList.begin(); 01706 std::list<stdair::BidPrice_T>::const_iterator itBP = lBidPriceList.begin(); 01707 for (; itSD != lOnDSegmentDateList.end(); ++itCCP, ++itSD, ++itBP) { 01708 stdair::BidPrice_T lBidPrice = *itBP; 01709 stdair::BidPrice_T lComplementaryBidPrice = lTotalBidPrice - lBidPrice; 01710 const stdair::SegmentDate* lSegmentDate_ptr = *itSD; 01711 assert (lSegmentDate_ptr != NULL); 01712 const stdair::SegmentDate* lOperatingSegmentDate_ptr = 01713 lSegmentDate_ptr->getOperatingSegmentDate (); 01714 // Only operated legs receive the demand information. 01715 if (lOperatingSegmentDate_ptr == NULL) { 01716 const stdair::CabinCode_T lCabinCode = itCCP->first; 01717 const stdair::ClassCode_T lClassCode = itCCP->second; 01718 const stdair::SegmentCabin* lSegmentCabin_ptr = 01719 stdair::BomManager::getObjectPtr<stdair::SegmentCabin> (*lSegmentDate_ptr, 01720 lCabinCode); 01721 assert (lSegmentCabin_ptr != NULL); 01722 const stdair::LegCabinList_T lLegCabinList = 01723 stdair::BomManager::getList<stdair::LegCabin> (*lSegmentCabin_ptr); 01724 assert (!lLegCabinList.empty()); 01725 // Determine the displacement-adjusted yield. 01726 // It is set to 100 (positive small value), if the computed value is negative. 01727 const stdair::Yield_T& lDAYield = 01728 std::max(100., lYieldDemandPair.first - lComplementaryBidPrice); 01729 01730 01731 stdair::Yield_T lYield = lDAYield; 01732 // In order to be protected against important variations of partners' bid price, 01733 // the displacement adjusted yield is noy allowed to get out of a certain range. 01734 // This range is here chosen to be from 80% to 100% of the (static rule) prorated yield. 01735 /* 01736 const int lNbOfLegs = lLegCabinList.size(); 01737 const stdair::Yield_T& lStaticProrationYield = 01738 lDemandStruct.getYield()/(lNbOfLegs*lNbOfSegments); 01739 if (lDAYield < 0.8*lStaticProrationYield){ 01740 lYield = 0.8*lStaticProrationYield; 01741 } 01742 if (lDAYield > lStaticProrationYield) { 01743 lYield = lStaticProrationYield; 01744 } 01745 */ 01746 const stdair::MeanStdDevPair_T& lMeanStdDevPair = 01747 lYieldDemandPair.second; 01748 const stdair::MeanValue_T& lMeanValue = lMeanStdDevPair.first; 01749 const stdair::StdDevValue_T& lStdDevValue = lMeanStdDevPair.second; 01750 for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin(); 01751 itLC != lLegCabinList.end(); ++itLC) { 01752 stdair::LegCabin* lLegCabin_ptr = *itLC; 01753 assert (lLegCabin_ptr != NULL); 01754 lLegCabin_ptr->addDemandInformation (lYield, lMeanValue, lStdDevValue); 01755 } 01756 } 01757 } 01758 } 01759 } 01760 } 01761 } 01762 } 01763 01764 // /////////////////////////////////////////////////////////////////// 01765 void RMOL_Service::projectOnDDemandOnLegCabinsUsingDYP(const stdair::DateTime_T& iRMEventTime) { 01766 01767 if (_rmolServiceContext == NULL) { 01768 throw stdair::NonInitialisedServiceException ("The Rmol service " 01769 "has not been initialised"); 01770 } 01771 assert (_rmolServiceContext != NULL); 01772 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 01773 01774 // Retrieve the bom root 01775 stdair::STDAIR_Service& lSTDAIR_Service = 01776 lRMOL_ServiceContext.getSTDAIR_Service(); 01777 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot(); 01778 01779 const stdair::InventoryList_T lInventoryList = 01780 stdair::BomManager::getList<stdair::Inventory> (lBomRoot); 01781 assert (!lInventoryList.empty()); 01782 for (stdair::InventoryList_T::const_iterator itInv = lInventoryList.begin(); 01783 itInv != lInventoryList.end(); ++itInv) { 01784 const stdair::Inventory* lInventory_ptr = *itInv; 01785 assert (lInventory_ptr != NULL); 01786 projectOnDDemandOnLegCabinsUsingDYP (iRMEventTime, *lInventory_ptr); 01787 } 01788 } 01789 01790 // /////////////////////////////////////////////////////////////////// 01791 void RMOL_Service::projectOnDDemandOnLegCabinsUsingDYP(const stdair::DateTime_T& iRMEventTime, 01792 const stdair::Inventory& iInventory) { 01793 01794 const stdair::OnDDateList_T lOnDDateList = 01795 stdair::BomManager::getList<stdair::OnDDate> (iInventory); 01796 assert (!lOnDDateList.empty()); 01797 for (stdair::OnDDateList_T::const_iterator itOD = lOnDDateList.begin(); 01798 itOD != lOnDDateList.end(); ++itOD) { 01799 stdair::OnDDate* lOnDDate_ptr = *itOD; 01800 assert (lOnDDate_ptr != NULL); 01801 01802 // Retrieve the date from the RM event 01803 const stdair::Date_T lDate = iRMEventTime.date(); 01804 01805 const stdair::Date_T& lDepartureDate = lOnDDate_ptr->getDate(); 01806 stdair::DateOffset_T lDateOffset = lDepartureDate - lDate; 01807 stdair::DTD_T lDTD = short (lDateOffset.days()); 01808 01809 stdair::DCPList_T::const_iterator itDCP = 01810 std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD); 01811 // Check if the forecast for this O&D date needs to be projected. 01812 if (itDCP != stdair::DEFAULT_DCP_LIST.end()) { 01813 01814 // Browse the demand info map. 01815 const stdair::StringDemandStructMap_T& lStringDemandStructMap = 01816 lOnDDate_ptr->getDemandInfoMap (); 01817 for (stdair::StringDemandStructMap_T::const_iterator itStrDS = lStringDemandStructMap.begin(); 01818 itStrDS != lStringDemandStructMap.end(); ++itStrDS) { 01819 std::string lCabinClassPath = itStrDS->first; 01820 const stdair::YieldDemandPair_T& lYieldDemandPair = itStrDS->second; 01821 const stdair::CabinClassPairList_T& lCabinClassPairList = 01822 lOnDDate_ptr->getCabinClassPairList(lCabinClassPath); 01823 const stdair::NbOfSegments_T& lNbOfSegments = lOnDDate_ptr->getNbOfSegments(); 01824 // Sanity check 01825 assert (lCabinClassPairList.size() == lNbOfSegments); 01826 01827 // 01828 const stdair::SegmentDateList_T lOnDSegmentDateList = 01829 stdair::BomManager::getList<stdair::SegmentDate> (*lOnDDate_ptr); 01830 // Sanity check 01831 assert (lOnDSegmentDateList.size() == lNbOfSegments); 01832 stdair::CabinClassPairList_T::const_iterator itCCP = lCabinClassPairList.begin(); 01833 stdair::SegmentDateList_T::const_iterator itSD = lOnDSegmentDateList.begin(); 01834 // The sum of bid prices of all cabins. 01835 stdair::BidPrice_T lTotalBidPrice = 0; 01836 for (; itSD != lOnDSegmentDateList.end(); ++itCCP, ++itSD) { 01837 // Get the operating segment cabin (it holds the bid price information). 01838 const stdair::SegmentDate* lSegmentDate_ptr = *itSD; 01839 assert (lSegmentDate_ptr != NULL); 01840 // Get the operating airline code and check if it is the airline we are looking for. 01841 const stdair::SegmentDate* lOperatingSegmentDate_ptr = 01842 lSegmentDate_ptr->getOperatingSegmentDate (); 01843 if (lOperatingSegmentDate_ptr != NULL) { 01844 lSegmentDate_ptr = lOperatingSegmentDate_ptr; 01845 } 01846 const stdair::CabinCode_T lCabinCode = itCCP->first; 01847 const stdair::SegmentCabin* lSegmentCabin_ptr = 01848 stdair::BomManager::getObjectPtr<stdair::SegmentCabin> (*lSegmentDate_ptr, 01849 lCabinCode); 01850 assert (lSegmentCabin_ptr != NULL); 01851 const stdair::LegCabinList_T lLegCabinList = 01852 stdair::BomManager::getList<stdair::LegCabin>(*lSegmentCabin_ptr); 01853 for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin(); 01854 itLC != lLegCabinList.end(); ++itLC) { 01855 const stdair::LegCabin* lLegCabin_ptr = *itLC; 01856 assert (lLegCabin_ptr != NULL); 01857 lTotalBidPrice += lLegCabin_ptr->getCurrentBidPrice(); 01858 } 01859 } 01860 01861 01862 itCCP = lCabinClassPairList.begin(); 01863 itSD = lOnDSegmentDateList.begin(); 01864 for (; itSD != lOnDSegmentDateList.end(); ++itCCP, ++itSD) { 01865 const stdair::SegmentDate* lSegmentDate_ptr = *itSD; 01866 assert (lSegmentDate_ptr != NULL); 01867 const stdair::SegmentDate* lOperatingSegmentDate_ptr = 01868 lSegmentDate_ptr->getOperatingSegmentDate (); 01869 // Only operated legs receive the demand information. 01870 if (lOperatingSegmentDate_ptr == NULL) { 01871 const stdair::CabinCode_T lCabinCode = itCCP->first; 01872 const stdair::ClassCode_T lClassCode = itCCP->second; 01873 const stdair::SegmentCabin* lSegmentCabin_ptr = 01874 stdair::BomManager::getObjectPtr<stdair::SegmentCabin> (*lSegmentDate_ptr, 01875 lCabinCode); 01876 assert (lSegmentCabin_ptr != NULL); 01877 const stdair::LegCabinList_T lLegCabinList = 01878 stdair::BomManager::getList<stdair::LegCabin> (*lSegmentCabin_ptr); 01879 assert (!lLegCabinList.empty()); 01880 const stdair::Yield_T& lYield = lYieldDemandPair.first; 01881 const stdair::MeanStdDevPair_T& lMeanStdDevPair = 01882 lYieldDemandPair.second; 01883 const stdair::MeanValue_T& lMeanValue = lMeanStdDevPair.first; 01884 const stdair::StdDevValue_T& lStdDevValue = lMeanStdDevPair.second; 01885 for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin(); 01886 itLC != lLegCabinList.end(); ++itLC) { 01887 stdair::LegCabin* lLegCabin_ptr = *itLC; 01888 assert (lLegCabin_ptr != NULL); 01889 const stdair::BidPrice_T& lBidPrice = lLegCabin_ptr->getCurrentBidPrice(); 01890 const stdair::RealNumber_T lDynamicYieldProrationFactor = lBidPrice / lTotalBidPrice; 01891 const stdair::Yield_T lProratedYield = lDynamicYieldProrationFactor*lYield; 01892 lLegCabin_ptr->addDemandInformation (lProratedYield, lMeanValue, lStdDevValue); 01893 01894 // STDAIR_LOG_DEBUG ("Addding demand information to leg-cabin " << lLegCabin_ptr->getFullerKey() 01895 // << " Total yield " << lYield << " Proration factor " 01896 // << lDynamicYieldProrationFactor << " Prorated yield " << lProratedYield 01897 // << " Mean demand " << lMeanValue << " StdDev " << lStdDevValue); 01898 } 01899 } 01900 } 01901 } 01902 } 01903 } 01904 } 01905 01906 // /////////////////////////////////////////////////////////////////// 01907 void RMOL_Service::optimiseOnDUsingRMCooperation (const stdair::DateTime_T& iRMEventTime) { 01908 01909 if (_rmolServiceContext == NULL) { 01910 throw stdair::NonInitialisedServiceException ("The Rmol service " 01911 "has not been initialised"); 01912 } 01913 assert (_rmolServiceContext != NULL); 01914 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 01915 01916 // Retrieve the bom root 01917 stdair::STDAIR_Service& lSTDAIR_Service = 01918 lRMOL_ServiceContext.getSTDAIR_Service(); 01919 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot(); 01920 01921 // Retrieve the date from the RM event 01922 const stdair::Date_T lDate = iRMEventTime.date(); 01923 01924 // Browse the list of inventories and optimise within each one independently. 01925 const stdair::InventoryList_T& lInvList = 01926 stdair::BomManager::getList<stdair::Inventory> (lBomRoot); 01927 for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin(); 01928 itInv != lInvList.end(); ++itInv) { 01929 stdair::Inventory* lCurrentInv_ptr = *itInv; 01930 assert (lCurrentInv_ptr != NULL); 01931 01932 double lMaxBPVariation = 1.0; 01933 short lIterationCounter = 0; 01934 // Iterate until the variation is under the wanted level or the maximal number of iterations is reached. 01935 while (lMaxBPVariation > 0.01 && lIterationCounter < 10) { 01936 lMaxBPVariation = 0.0; 01937 lIterationCounter++; 01938 const stdair::FlightDateList_T& lFlightDateList = 01939 stdair::BomManager::getList<stdair::FlightDate> (*lCurrentInv_ptr); 01940 for (stdair::FlightDateList_T::const_iterator itFlightDate = 01941 lFlightDateList.begin(); 01942 itFlightDate != lFlightDateList.end(); ++itFlightDate) { 01943 stdair::FlightDate* lCurrentFlightDate_ptr = *itFlightDate; 01944 assert (lCurrentFlightDate_ptr != NULL); 01945 01946 const stdair::Date_T& lCurrentDepartureDate = lCurrentFlightDate_ptr->getDepartureDate(); 01947 stdair::DateOffset_T lDateOffset = lCurrentDepartureDate - lDate; 01948 stdair::DTD_T lDTD = short (lDateOffset.days()); 01949 01950 stdair::DCPList_T::const_iterator itDCP = 01951 std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD); 01952 // Check if the optimisation is needed. 01953 if (itDCP != stdair::DEFAULT_DCP_LIST.end()) { 01954 const double lBPVariation = Optimiser::optimiseUsingOnDForecast (*lCurrentFlightDate_ptr); 01955 lMaxBPVariation = std::max(lMaxBPVariation, lBPVariation); 01956 } 01957 } 01958 // Update the prorated yields for the current inventory. 01959 resetDemandInformation (iRMEventTime, *lCurrentInv_ptr); 01960 projectOnDDemandOnLegCabinsUsingDYP (iRMEventTime, *lCurrentInv_ptr); 01961 } 01962 } 01963 } 01964 01965 01966 // /////////////////////////////////////////////////////////////////// 01967 void RMOL_Service::optimiseOnDUsingAdvancedRMCooperation (const stdair::DateTime_T& iRMEventTime) { 01968 01969 if (_rmolServiceContext == NULL) { 01970 throw stdair::NonInitialisedServiceException ("The Rmol service " 01971 "has not been initialised"); 01972 } 01973 assert (_rmolServiceContext != NULL); 01974 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext; 01975 01976 // Retrieve the bom root 01977 stdair::STDAIR_Service& lSTDAIR_Service = 01978 lRMOL_ServiceContext.getSTDAIR_Service(); 01979 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot(); 01980 01981 // Retrieve the date from the RM event 01982 const stdair::Date_T lDate = iRMEventTime.date(); 01983 01984 double lMaxBPVariation = 1.0; 01985 short lIterationCounter = 0; 01986 // Iterate until the variation is under the wanted level or the maximal number of iterations is reached. 01987 // Every iteration corresponds to the optimisation of the whole network. Bid prices are communicated 01988 // between partners at the end of each iteration. 01989 while (lMaxBPVariation > 0.01 && lIterationCounter < 50) { 01990 lMaxBPVariation = 0.0; 01991 lIterationCounter++; 01992 01993 const stdair::InventoryList_T& lInvList = 01994 stdair::BomManager::getList<stdair::Inventory> (lBomRoot); 01995 for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin(); 01996 itInv != lInvList.end(); ++itInv) { 01997 stdair::Inventory* lCurrentInv_ptr = *itInv; 01998 assert (lCurrentInv_ptr != NULL); 01999 const stdair::FlightDateList_T& lFlightDateList = 02000 stdair::BomManager::getList<stdair::FlightDate> (*lCurrentInv_ptr); 02001 for (stdair::FlightDateList_T::const_iterator itFlightDate = 02002 lFlightDateList.begin(); 02003 itFlightDate != lFlightDateList.end(); ++itFlightDate) { 02004 stdair::FlightDate* lCurrentFlightDate_ptr = *itFlightDate; 02005 assert (lCurrentFlightDate_ptr != NULL); 02006 02007 const stdair::Date_T& lCurrentDepartureDate = lCurrentFlightDate_ptr->getDepartureDate(); 02008 stdair::DateOffset_T lDateOffset = lCurrentDepartureDate - lDate; 02009 stdair::DTD_T lDTD = short (lDateOffset.days()); 02010 02011 stdair::DCPList_T::const_iterator itDCP = 02012 std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD); 02013 if (itDCP != stdair::DEFAULT_DCP_LIST.end()) { 02014 const double lBPVariation = Optimiser::optimiseUsingOnDForecast (*lCurrentFlightDate_ptr); 02015 lMaxBPVariation = std::max(lMaxBPVariation, lBPVariation); 02016 } 02017 } 02018 } 02019 // At the end of each iteration, communicate bid prices and compute displacement adjusted yields. 02020 updateBidPrice (iRMEventTime); 02021 resetDemandInformation (iRMEventTime); 02022 projectOnDDemandOnLegCabinsUsingDYP (iRMEventTime); 02023 } 02024 } 02025 02026 }