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