RMOL Logo  1.00.0
C++ library of Revenue Management and Optimisation classes and functions
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
RMOL_Service.cpp
Go to the documentation of this file.
1 // //////////////////////////////////////////////////////////////////////
2 // Import section
3 // //////////////////////////////////////////////////////////////////////
4 // STL
5 #include <cassert>
6 // Boost
7 #include <boost/make_shared.hpp>
8 // StdAir
9 #include <stdair/stdair_inventory_types.hpp>
10 #include <stdair/basic/BasChronometer.hpp>
11 #include <stdair/basic/ContinuousAttributeLite.hpp>
12 #include <stdair/bom/BomManager.hpp>
13 #include <stdair/bom/BomRetriever.hpp>
14 #include <stdair/bom/BomRoot.hpp>
15 #include <stdair/bom/Inventory.hpp>
16 #include <stdair/bom/FlightDate.hpp>
17 #include <stdair/bom/LegCabin.hpp>
18 #include <stdair/bom/LegDate.hpp>
19 #include <stdair/bom/YieldFeatures.hpp>
20 #include <stdair/bom/AirportPair.hpp>
21 #include <stdair/bom/PosChannel.hpp>
22 #include <stdair/bom/DatePeriod.hpp>
23 #include <stdair/bom/TimePeriod.hpp>
24 #include <stdair/bom/AirlineClassList.hpp>
25 #include <stdair/basic/BasConst_Request.hpp>
26 #include <stdair/basic/BasConst_Inventory.hpp>
27 #include <stdair/bom/Inventory.hpp>
28 #include <stdair/bom/FlightDate.hpp>
29 #include <stdair/bom/SegmentDate.hpp>
30 #include <stdair/bom/SegmentCabin.hpp>
31 #include <stdair/bom/BookingClass.hpp>
32 #include <stdair/bom/OnDDate.hpp>
33 #include <stdair/bom/OnDDateTypes.hpp>
34 #include <stdair/command/CmdBomManager.hpp>
35 #include <stdair/service/Logger.hpp>
36 #include <stdair/STDAIR_Service.hpp>
37 // RMOL
45 #include <rmol/RMOL_Service.hpp>
46 
47 namespace RMOL {
48 
49  // ////////////////////////////////////////////////////////////////////
50  RMOL_Service::RMOL_Service()
51  : _rmolServiceContext (NULL),
52  _previousForecastDate (stdair::Date_T (2000, 1, 1)) {
53  assert (false);
54  }
55 
56  // ////////////////////////////////////////////////////////////////////
57  RMOL_Service::RMOL_Service (const RMOL_Service& iService) :
58  _rmolServiceContext (NULL),
59  _previousForecastDate (stdair::Date_T (2000, 1, 1)) {
60  assert (false);
61  }
62 
63  // ////////////////////////////////////////////////////////////////////
64  RMOL_Service::RMOL_Service (const stdair::BasLogParams& iLogParams) :
65  _rmolServiceContext (NULL),
66  _previousForecastDate (stdair::Date_T (2000, 1, 1)) {
67 
68  // Initialise the STDAIR service handler
69  stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr =
70  initStdAirService (iLogParams);
71 
72  // Initialise the service context
73  initServiceContext();
74 
75  // Add the StdAir service context to the RMOL service context
76  // \note RMOL owns the STDAIR service resources here.
77  const bool ownStdairService = true;
78  addStdAirService (lSTDAIR_Service_ptr, ownStdairService);
79 
80  // Initialise the (remaining of the) context
81  initRmolService();
82  }
83 
84  // ////////////////////////////////////////////////////////////////////
85  RMOL_Service::RMOL_Service (const stdair::BasLogParams& iLogParams,
86  const stdair::BasDBParams& iDBParams) :
87  _rmolServiceContext (NULL),
88  _previousForecastDate (stdair::Date_T (2000, 1, 1)) {
89 
90  // Initialise the STDAIR service handler
91  stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr =
92  initStdAirService (iLogParams, iDBParams);
93 
94  // Initialise the service context
95  initServiceContext();
96 
97  // Add the StdAir service context to the RMOL service context
98  // \note RMOL owns the STDAIR service resources here.
99  const bool ownStdairService = true;
100  addStdAirService (lSTDAIR_Service_ptr, ownStdairService);
101 
102  // Initialise the (remaining of the) context
103  initRmolService();
104  }
105 
106  // ////////////////////////////////////////////////////////////////////
107  RMOL_Service::RMOL_Service (stdair::STDAIR_ServicePtr_T ioSTDAIRServicePtr)
108  : _rmolServiceContext (NULL),
109  _previousForecastDate (stdair::Date_T (2000, 1, 1)) {
110 
111  // Initialise the context
112  initServiceContext();
113 
114  // Add the StdAir service context to the RMOL service context.
115  // \note RMOL does not own the STDAIR service resources here.
116  const bool doesNotOwnStdairService = false;
117  addStdAirService (ioSTDAIRServicePtr, doesNotOwnStdairService);
118 
119  // Initialise the (remaining of the) context
120  initRmolService();
121  }
122 
123  // ////////////////////////////////////////////////////////////////////
125  // Delete/Clean all the objects from memory
126  finalise();
127  }
128 
129  // ////////////////////////////////////////////////////////////////////
130  void RMOL_Service::finalise() {
131  assert (_rmolServiceContext != NULL);
132  // Reset the (Boost.)Smart pointer pointing on the STDAIR_Service object.
133  _rmolServiceContext->reset();
134  }
135 
136  // ////////////////////////////////////////////////////////////////////
137  void RMOL_Service::initServiceContext() {
138  // Initialise the service context
139  RMOL_ServiceContext& lRMOL_ServiceContext =
141  _rmolServiceContext = &lRMOL_ServiceContext;
142  }
143 
144  // ////////////////////////////////////////////////////////////////////
145  void RMOL_Service::
146  addStdAirService (stdair::STDAIR_ServicePtr_T ioSTDAIR_Service_ptr,
147  const bool iOwnStdairService) {
148 
149  // Retrieve the RMOL service context
150  assert (_rmolServiceContext != NULL);
151  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
152 
153  // Store the STDAIR service object within the (AIRINV) service context
154  lRMOL_ServiceContext.setSTDAIR_Service (ioSTDAIR_Service_ptr,
155  iOwnStdairService);
156  }
157 
158  // ////////////////////////////////////////////////////////////////////
159  stdair::STDAIR_ServicePtr_T RMOL_Service::
160  initStdAirService (const stdair::BasLogParams& iLogParams) {
161 
169  stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr =
170  boost::make_shared<stdair::STDAIR_Service> (iLogParams);
171 
172  return lSTDAIR_Service_ptr;
173  }
174 
175  // //////////////////////////////////////////////////////////////////////
176  stdair::STDAIR_ServicePtr_T RMOL_Service::
177  initStdAirService (const stdair::BasLogParams& iLogParams,
178  const stdair::BasDBParams& iDBParams) {
179 
187  stdair::STDAIR_ServicePtr_T lSTDAIR_Service_ptr =
188  boost::make_shared<stdair::STDAIR_Service> (iLogParams, iDBParams);
189 
190  return lSTDAIR_Service_ptr;
191  }
192 
193  // ////////////////////////////////////////////////////////////////////
194  void RMOL_Service::initRmolService() {
195  // Do nothing at this stage. A sample BOM tree may be built by
196  // calling the buildSampleBom() method
197  }
198 
199  // ////////////////////////////////////////////////////////////////////
200  void RMOL_Service::
201  parseAndLoad (const stdair::CabinCapacity_T& iCabinCapacity,
202  const stdair::Filename_T& iInputFileName) {
203 
204  // Retrieve the RMOL service context
205  if (_rmolServiceContext == NULL) {
206  throw stdair::NonInitialisedServiceException ("The RMOL service has not"
207  " been initialised");
208  }
209  assert (_rmolServiceContext != NULL);
210  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
211  const bool doesOwnStdairService =
212  lRMOL_ServiceContext.getOwnStdairServiceFlag();
213 
214  // Retrieve the StdAir service object from the (RMOL) service context
215  stdair::STDAIR_Service& lSTDAIR_Service =
216  lRMOL_ServiceContext.getSTDAIR_Service();
217  stdair::BomRoot& lPersistentBomRoot =
218  lSTDAIR_Service.getPersistentBomRoot();
219 
223  lSTDAIR_Service.buildDummyInventory (iCabinCapacity);
224 
229  lPersistentBomRoot);
230 
246  buildComplementaryLinks (lPersistentBomRoot);
247 
252  if (doesOwnStdairService == true) {
253 
254  //
256  }
257  }
258 
259  // ////////////////////////////////////////////////////////////////////
261 
262  // Retrieve the RMOL service context
263  if (_rmolServiceContext == NULL) {
264  throw stdair::NonInitialisedServiceException ("The RMOL service has not"
265  " been initialised");
266  }
267  assert (_rmolServiceContext != NULL);
268 
269  // Retrieve the RMOL service context and whether it owns the Stdair
270  // service
271  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
272  const bool doesOwnStdairService =
273  lRMOL_ServiceContext.getOwnStdairServiceFlag();
274 
275  // Retrieve the StdAir service object from the (RMOL) service context
276  stdair::STDAIR_Service& lSTDAIR_Service =
277  lRMOL_ServiceContext.getSTDAIR_Service();
278  stdair::BomRoot& lPersistentBomRoot =
279  lSTDAIR_Service.getPersistentBomRoot();
280 
285  if (doesOwnStdairService == true) {
286  //
287  lSTDAIR_Service.buildSampleBom();
288  }
289 
305  buildComplementaryLinks (lPersistentBomRoot);
306 
311  if (doesOwnStdairService == true) {
312 
313  //
315  }
316  }
317 
318  // ////////////////////////////////////////////////////////////////////
320 
321  // Retrieve the RMOL service context
322  if (_rmolServiceContext == NULL) {
323  throw stdair::NonInitialisedServiceException("The RMOL service has not "
324  "been initialised");
325  }
326  assert (_rmolServiceContext != NULL);
327 
328  // Retrieve the RMOL service context and whether it owns the Stdair
329  // service
330  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
331  const bool doesOwnStdairService =
332  lRMOL_ServiceContext.getOwnStdairServiceFlag();
333 
334  // Retrieve the StdAir service object from the (RMOL) service context
335  stdair::STDAIR_Service& lSTDAIR_Service =
336  lRMOL_ServiceContext.getSTDAIR_Service();
337 
342  if (doesOwnStdairService == true) {
343 
344  //
345  lSTDAIR_Service.clonePersistentBom ();
346  }
347 
351  stdair::BomRoot& lBomRoot =
352  lSTDAIR_Service.getBomRoot();
353  buildComplementaryLinks (lBomRoot);
354  }
355 
356  // ////////////////////////////////////////////////////////////////////
357  void RMOL_Service::buildComplementaryLinks (stdair::BomRoot& ioBomRoot) {
358 
359  // Retrieve the RMOL service context
360  if (_rmolServiceContext == NULL) {
361  throw stdair::NonInitialisedServiceException("The RMOL service has not "
362  "been initialised");
363  }
364  assert (_rmolServiceContext != NULL);
365 
366  // Retrieve the RMOL service context and whether it owns the Stdair
367  // service
368  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
369 
370  // Retrieve the StdAir service object from the (RMOL) service context
371  stdair::STDAIR_Service& lSTDAIR_Service =
372  lRMOL_ServiceContext.getSTDAIR_Service();
373 
378  lSTDAIR_Service.buildDummyLegSegmentAccesses (ioBomRoot);
379  }
380 
381  // ////////////////////////////////////////////////////////////////////
383  assert (_rmolServiceContext != NULL);
384  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
385 
386  // Retrieve the StdAir service
387  stdair::STDAIR_Service& lSTDAIR_Service =
388  lRMOL_ServiceContext.getSTDAIR_Service();
389  // TODO: gsabatier
390  // Replace the getPersistentBomRoot method by the getBomRoot method,
391  // in order to work on the clone Bom root instead of the persistent one.
392  // Does not work for now because virtual classes are not cloned.
393  stdair::BomRoot& lBomRoot = lSTDAIR_Service.getPersistentBomRoot();
394 
395  //
396  stdair::LegCabin& lLegCabin =
397  stdair::BomRetriever::retrieveDummyLegCabin (lBomRoot);
398 
399  stdair::BasChronometer lOptimisationChronometer;
400  lOptimisationChronometer.start();
401 
403 
404  const double lOptimisationMeasure = lOptimisationChronometer.elapsed();
405 
406  // DEBUG
407  STDAIR_LOG_DEBUG ("Optimisation by Monte-Carlo performed in "
408  << lOptimisationMeasure);
409  STDAIR_LOG_DEBUG ("Result: " << lLegCabin.displayVirtualClassList());
410 
411  std::ostringstream logStream;
412  stdair::BidPriceVector_T lBidPriceVector = lLegCabin.getBidPriceVector();
413  logStream << "Bid-Price Vector (BPV): ";
414  const unsigned int size = lBidPriceVector.size();
415 
416  for (unsigned int i = 0; i < size - 1; ++i) {
417  const double bidPrice = lBidPriceVector.at(i);
418  logStream << std::fixed << std::setprecision (2) << bidPrice << ", ";
419  }
420  const double bidPrice = lBidPriceVector.at(size -1);
421  logStream << std::fixed << std::setprecision (2) << bidPrice;
422  STDAIR_LOG_DEBUG (logStream.str());
423  }
424 
425  // ////////////////////////////////////////////////////////////////////
427  }
428 
429  // ////////////////////////////////////////////////////////////////////
431  assert (_rmolServiceContext != NULL);
432  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
433 
434  // Retrieve the StdAir service
435  stdair::STDAIR_Service& lSTDAIR_Service =
436  lRMOL_ServiceContext.getSTDAIR_Service();
437  // TODO: gsabatier
438  // Replace the getPersistentBomRoot method by the getBomRoot method,
439  // in order to work on the clone Bom root instead of the persistent one.
440  // Does not work for now because virtual classes are not cloned.
441  stdair::BomRoot& lBomRoot = lSTDAIR_Service.getPersistentBomRoot();
442 
443  //
444  stdair::LegCabin& lLegCabin =
445  stdair::BomRetriever::retrieveDummyLegCabin (lBomRoot);
446 
447  stdair::BasChronometer lOptimisationChronometer;
448  lOptimisationChronometer.start();
449 
451 
452  const double lOptimisationMeasure = lOptimisationChronometer.elapsed();
453  // DEBUG
454  STDAIR_LOG_DEBUG ("Optimisation EMSR performed in "
455  << lOptimisationMeasure);
456  STDAIR_LOG_DEBUG ("Result: " << lLegCabin.displayVirtualClassList());
457 
458  stdair::BidPriceVector_T lBidPriceVector = lLegCabin.getBidPriceVector();
459  std::ostringstream logStream;
460  logStream << "Bid-Price Vector (BPV): ";
461  stdair::UnsignedIndex_T idx = 0;
462  for (stdair::BidPriceVector_T::const_iterator itBP = lBidPriceVector.begin();
463  itBP != lBidPriceVector.end(); ++itBP) {
464  if (idx != 0) {
465  logStream << ", ";
466  }
467  const stdair::BidPrice_T& lBidPrice = *itBP;
468  logStream << std::fixed << std::setprecision (2) << lBidPrice;
469  }
470  // DEBUG
471  STDAIR_LOG_DEBUG (logStream.str());
472  }
473 
474  // ////////////////////////////////////////////////////////////////////
476  assert (_rmolServiceContext != NULL);
477  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
478 
479  // Retrieve the StdAir service
480  stdair::STDAIR_Service& lSTDAIR_Service =
481  lRMOL_ServiceContext.getSTDAIR_Service();
482  // TODO: gsabatier
483  // Replace the getPersistentBomRoot method by the getBomRoot method,
484  // in order to work on the clone Bom root instead of the persistent one.
485  // Does not work for now because virtual classes are not cloned.
486  stdair::BomRoot& lBomRoot = lSTDAIR_Service.getPersistentBomRoot();
487 
488  //
489  stdair::LegCabin& lLegCabin =
490  stdair::BomRetriever::retrieveDummyLegCabin (lBomRoot);
491 
493 
494  // DEBUG
495  STDAIR_LOG_DEBUG ("Result: " << lLegCabin.displayVirtualClassList());
496 
497  }
498 
499  // ////////////////////////////////////////////////////////////////////
501  assert (_rmolServiceContext != NULL);
502  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
503 
504  // Retrieve the StdAir service
505  stdair::STDAIR_Service& lSTDAIR_Service =
506  lRMOL_ServiceContext.getSTDAIR_Service();
507  // TODO: gsabatier
508  // Replace the getPersistentBomRoot method by the getBomRoot method,
509  // in order to work on the clone Bom root instead of the persistent one.
510  // Does not work for now because virtual classes are not cloned.
511  stdair::BomRoot& lBomRoot = lSTDAIR_Service.getPersistentBomRoot();
512 
513  //
514  stdair::LegCabin& lLegCabin =
515  stdair::BomRetriever::retrieveDummyLegCabin (lBomRoot);
516 
518 
519  // DEBUG
520  STDAIR_LOG_DEBUG ("Result: " << lLegCabin.displayVirtualClassList());
521  }
522 
523  // ////////////////////////////////////////////////////////////////////
524  const stdair::SegmentCabin& RMOL_Service::
525  retrieveDummySegmentCabin(const bool isForFareFamilies) {
526  assert (_rmolServiceContext != NULL);
527  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
528 
529  // Retrieve the StdAir service
530  stdair::STDAIR_Service& lSTDAIR_Service =
531  lRMOL_ServiceContext.getSTDAIR_Service();
532  // TODO: gsabatier
533  // Replace the getPersistentBomRoot method by the getBomRoot method,
534  // in order to work on the clone Bom root instead of the persistent one.
535  // Does not work for now because virtual classes are not cloned.
536  stdair::BomRoot& lBomRoot = lSTDAIR_Service.getPersistentBomRoot();
537 
538  const stdair::SegmentCabin& lSegmentCabin =
540  isForFareFamilies);
541  return lSegmentCabin;
542 
543  }
544 
545  // ////////////////////////////////////////////////////////////////////
546  bool RMOL_Service::
547  optimise (stdair::FlightDate& ioFlightDate,
548  const stdair::DateTime_T& iRMEventTime,
549  const stdair::UnconstrainingMethod& iUnconstrainingMethod,
550  const stdair::ForecastingMethod& iForecastingMethod,
551  const stdair::PreOptimisationMethod& iPreOptimisationMethod,
552  const stdair::OptimisationMethod& iOptimisationMethod,
553  const stdair::PartnershipTechnique& iPartnershipTechnique) {
554 
555 
556  STDAIR_LOG_DEBUG ("Forecast & Optimisation");
557 
558  const stdair::PartnershipTechnique::EN_PartnershipTechnique& lPartnershipTechnique =
559  iPartnershipTechnique.getTechnique();
560 
561  switch (lPartnershipTechnique) {
562  case stdair::PartnershipTechnique::NONE:{
563  // DEBUG
564  STDAIR_LOG_DEBUG ("Forecast");
565 
566  // 1. Forecasting
567  const bool isForecasted = Forecaster::forecast (ioFlightDate,
568  iRMEventTime,
569  iUnconstrainingMethod,
570  iForecastingMethod);
571  // DEBUG
572  STDAIR_LOG_DEBUG ("Forecast successful: " << isForecasted);
573 
574  if (isForecasted == true) {
575  // 2a. MRT or FA
576  // DEBUG
577  STDAIR_LOG_DEBUG ("Pre-optimise");
578 
579  const bool isPreOptimised =
580  PreOptimiser::preOptimise (ioFlightDate, iPreOptimisationMethod);
581 
582  // DEBUG
583  STDAIR_LOG_DEBUG ("Pre-Optimise successful: " << isPreOptimised);
584 
585  if (isPreOptimised == true) {
586  // 2b. Optimisation
587  // DEBUG
588  STDAIR_LOG_DEBUG ("Optimise");
589  const bool optimiseSucceeded =
590  Optimiser::optimise (ioFlightDate, iOptimisationMethod);
591  // DEBUG
592  STDAIR_LOG_DEBUG ("Optimise successful: " << optimiseSucceeded);
593  return optimiseSucceeded ;
594  }
595  }
596  break;
597  }
598  case stdair::PartnershipTechnique::RAE_DA:
599  case stdair::PartnershipTechnique::IBP_DA:{
600  if (_previousForecastDate < iRMEventTime.date()) {
601  forecastOnD (iRMEventTime);
602  resetDemandInformation (iRMEventTime);
603  projectAggregatedDemandOnLegCabins (iRMEventTime);
604  optimiseOnD (iRMEventTime);
605  }
606  break;
607  }
608  case stdair::PartnershipTechnique::RAE_YP:
609  case stdair::PartnershipTechnique::IBP_YP:
610  case stdair::PartnershipTechnique::IBP_YP_U:{
611  if (_previousForecastDate < iRMEventTime.date()) {
612  forecastOnD (iRMEventTime);
613  resetDemandInformation (iRMEventTime);
614  projectOnDDemandOnLegCabinsUsingYP (iRMEventTime);
615  optimiseOnD (iRMEventTime);
616  }
617  break;
618  }
619  case stdair::PartnershipTechnique::RMC:{
620  if (_previousForecastDate < iRMEventTime.date()) {
621  forecastOnD (iRMEventTime);
622  resetDemandInformation (iRMEventTime);
623  updateBidPrice (iRMEventTime);
625  optimiseOnDUsingRMCooperation (iRMEventTime);
626  }
627  break;
628  }
629  case stdair::PartnershipTechnique::A_RMC:{
630  if (_previousForecastDate < iRMEventTime.date()) {
631  forecastOnD (iRMEventTime);
632  resetDemandInformation (iRMEventTime);
633  updateBidPrice (iRMEventTime);
636  }
637  break;
638  }
639  default:{
640  assert (false);
641  break;
642  }
643  }
644  return false;
645  }
646 
647  // ////////////////////////////////////////////////////////////////////
648  void RMOL_Service::forecastOnD (const stdair::DateTime_T& iRMEventTime) {
649 
650  if (_rmolServiceContext == NULL) {
651  throw stdair::NonInitialisedServiceException ("The Rmol service "
652  "has not been initialised");
653  }
654  assert (_rmolServiceContext != NULL);
655  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
656 
657  // Retrieve the bom root
658  stdair::STDAIR_Service& lSTDAIR_Service =
659  lRMOL_ServiceContext.getSTDAIR_Service();
660  stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
661 
662  // Retrieve the date from the RM event
663  const stdair::Date_T lDate = iRMEventTime.date();
664 
665  _previousForecastDate = lDate;
666 
667  const stdair::InventoryList_T& lInventoryList =
668  stdair::BomManager::getList<stdair::Inventory> (lBomRoot);
669  assert (!lInventoryList.empty());
670  for (stdair::InventoryList_T::const_iterator itInv = lInventoryList.begin();
671  itInv != lInventoryList.end(); ++itInv) {
672  const stdair::Inventory* lInventory_ptr = *itInv;
673  assert (lInventory_ptr != NULL);
674  const bool hasOnDDateList =
675  stdair::BomManager::hasList<stdair::OnDDate> (*lInventory_ptr);
676  if (hasOnDDateList == true) {
677  const stdair::OnDDateList_T lOnDDateList =
678  stdair::BomManager::getList<stdair::OnDDate> (*lInventory_ptr);
679 
680  for (stdair::OnDDateList_T::const_iterator itOD = lOnDDateList.begin();
681  itOD != lOnDDateList.end(); ++itOD) {
682  stdair::OnDDate* lOnDDate_ptr = *itOD;
683  assert (lOnDDate_ptr != NULL);
684 
685  const stdair::Date_T& lDepartureDate = lOnDDate_ptr->getDate();
686  stdair::DateOffset_T lDateOffset = lDepartureDate - lDate;
687  stdair::DTD_T lDTD = short (lDateOffset.days());
688 
689  stdair::DCPList_T::const_iterator itDCP =
690  std::find (stdair::DEFAULT_DCP_LIST.begin(),
691  stdair::DEFAULT_DCP_LIST.end(), lDTD);
692  // Check if the forecast for this O&D date needs to be forecasted.
693  if (itDCP != stdair::DEFAULT_DCP_LIST.end()) {
694  // Retrieve the total forecast map.
695  const stdair::CabinForecastMap_T& lTotalForecastMap =
696  lOnDDate_ptr->getTotalForecastMap();
697 
698  // Browse the map and make a forecast for every cabin.
699  for (stdair::CabinForecastMap_T::const_iterator itCF =
700  lTotalForecastMap.begin();
701  itCF != lTotalForecastMap.end(); ++itCF) {
702  const stdair::CabinCode_T lCabinCode = itCF->first;
703  stdair::YieldFeatures* lYieldFeatures_ptr =
704  getYieldFeatures(*lOnDDate_ptr, lCabinCode, lBomRoot);
705  if (lYieldFeatures_ptr == NULL) {
706  STDAIR_LOG_ERROR ("Cannot find yield corresponding to "
707  << "the O&D date"
708  << lOnDDate_ptr->toString()
709  << " Cabin " << lCabinCode);
710  assert (false);
711  }
712  forecastOnD (*lYieldFeatures_ptr, *lOnDDate_ptr, lCabinCode, lDTD,
713  lBomRoot);
714  }
715  }
716  }
717  }
718  }
719  }
720 
721  // ///////////////////////////////////////////////////////////////////
722  stdair::YieldFeatures* RMOL_Service::
723  getYieldFeatures(const stdair::OnDDate& iOnDDate,
724  const stdair::CabinCode_T& iCabinCode,
725  stdair::BomRoot& iBomRoot) {
726 
727  const stdair::AirportCode_T& lOrigin = iOnDDate.getOrigin();
728  const stdair::AirportCode_T& lDestination = iOnDDate.getDestination();
729 
730  const stdair::Date_T& lDepartureDate = iOnDDate.getDate();
731 
732  // Build the airport pair key out of O&D and get the airport pair object
733  const stdair::AirportPairKey lAirportPairKey(lOrigin, lDestination);
734  stdair::AirportPair* lAirportPair_ptr = stdair::BomManager::
735  getObjectPtr<stdair::AirportPair> (iBomRoot,
736  lAirportPairKey.toString());
737  if (lAirportPair_ptr == NULL) {
738  STDAIR_LOG_ERROR ("Cannot find yield corresponding to the airport "
739  << "pair: " << lAirportPairKey.toString());
740  assert (false);
741  }
742 
743  // Retrieve the corresponding date period to lDepartureDate.
744  const stdair::DatePeriodList_T lDatePeriodList =
745  stdair::BomManager::getList<stdair::DatePeriod> (*lAirportPair_ptr);
746  for (stdair::DatePeriodList_T::const_iterator itDatePeriod =
747  lDatePeriodList.begin();
748  itDatePeriod != lDatePeriodList.end(); ++itDatePeriod) {
749  const stdair::DatePeriod* lDatePeriod_ptr = *itDatePeriod;
750  assert (lDatePeriod_ptr != NULL);
751 
752  const bool isDepartureDateValid =
753  lDatePeriod_ptr->isDepartureDateValid (lDepartureDate);
754 
755  if (isDepartureDateValid == true) {
756  // Retrieve the PoS-Channel.
757  // TODO: Use POS and Channel from demand instead of default
758  const stdair::PosChannelKey lPosChannelKey (stdair::DEFAULT_POS,
759  stdair::DEFAULT_CHANNEL);
760  stdair::PosChannel* lPosChannel_ptr = stdair::BomManager::
761  getObjectPtr<stdair::PosChannel> (*lDatePeriod_ptr,
762  lPosChannelKey.toString());
763  if (lPosChannel_ptr == NULL) {
764  STDAIR_LOG_ERROR ("Cannot find yield corresponding to the PoS-"
765  << "Channel: " << lPosChannelKey.toString());
766  assert (false);
767  }
768  // Retrieve the yield features.
769  const stdair::TimePeriodList_T lTimePeriodList = stdair::
770  BomManager::getList<stdair::TimePeriod> (*lPosChannel_ptr);
771  for (stdair::TimePeriodList_T::const_iterator itTimePeriod =
772  lTimePeriodList.begin();
773  itTimePeriod != lTimePeriodList.end(); ++itTimePeriod) {
774  const stdair::TimePeriod* lTimePeriod_ptr = *itTimePeriod;
775  assert (lTimePeriod_ptr != NULL);
776 
777  // TODO: Use trip type from demand instead of default value.
778  const stdair::YieldFeaturesKey lYieldFeaturesKey (stdair::TRIP_TYPE_ONE_WAY,
779  iCabinCode);
780  stdair::YieldFeatures* oYieldFeatures_ptr = stdair::BomManager::
781  getObjectPtr<stdair::YieldFeatures>(*lTimePeriod_ptr,
782  lYieldFeaturesKey.toString());
783  if (oYieldFeatures_ptr != NULL) {
784  return oYieldFeatures_ptr;
785  }
786  }
787  }
788  }
789  return NULL;
790 
791  }
792 
793 
794  // ///////////////////////////////////////////////////////////////////
795  void RMOL_Service::
796  forecastOnD (const stdair::YieldFeatures& iYieldFeatures,
797  stdair::OnDDate& iOnDDate,
798  const stdair::CabinCode_T& iCabinCode,
799  const stdair::DTD_T& iDTD,
800  stdair::BomRoot& iBomRoot) {
801 
802  const stdair::AirlineClassListList_T lAirlineClassListList =
803  stdair::BomManager::getList<stdair::AirlineClassList> (iYieldFeatures);
804  assert (lAirlineClassListList.begin() != lAirlineClassListList.end());
805 
806  // Yield order check
807  stdair::AirlineClassListList_T::const_iterator itACL =
808  lAirlineClassListList.begin();
809  stdair::Yield_T lPreviousYield((*itACL)->getYield());
810  ++itACL;
811  for (; itACL != lAirlineClassListList.end(); ++itACL) {
812  const stdair::AirlineClassList* lAirlineClassList = *itACL;
813  const stdair::Yield_T& lYield = lAirlineClassList->getYield();
814  if (lYield <= lPreviousYield) {
815  lPreviousYield = lYield;
816  }
817  else{
818  STDAIR_LOG_ERROR ("Yields should be given in a descendant order"
819  << " in the yield input file") ;
820  assert (false);
821  }
822  }
823  // Proportion factor list initialisation
824  // Each element corresponds to a yield rule
825  stdair::ProportionFactorList_T lProportionFactorList;
826  stdair::ProportionFactor_T lPreviousProportionFactor = 0;
827 
828  // Retrieve the minimal willingness to pay associated to the demand
829  const stdair::WTPDemandPair_T& lTotalForecast =
830  iOnDDate.getTotalForecast (iCabinCode);
831  const stdair::WTP_T& lMinWTP = lTotalForecast.first;
832 
833  // Retrieve the remaining percentage of booking requests
834  const stdair::ContinuousAttributeLite<stdair::FloatDuration_T>
835  lArrivalPattern (stdair::DEFAULT_DTD_PROB_MAP);
836 
837  STDAIR_LOG_DEBUG (lArrivalPattern.displayCumulativeDistribution());
838  const stdair::Probability_T lRemainingProportion =
839  lArrivalPattern.getRemainingProportion(-float(iDTD));
840 
841  // Compute the characteristics (mean and std dev) of the total
842  // forecast demand to come
843  const stdair::MeanStdDevPair_T lForecatsMeanStdDevPair =
844  lTotalForecast.second;
845  const stdair::MeanValue_T& lMeanValue =
846  lForecatsMeanStdDevPair.first;
847  const stdair::MeanValue_T& lRemainingMeanValue =
848  lRemainingProportion*lMeanValue;
849  const stdair::StdDevValue_T& lStdDevValue =
850  lForecatsMeanStdDevPair.second;
851  const stdair::StdDevValue_T& lRemainingStdDevValue =
852  lRemainingProportion*lStdDevValue;
853 
854  // Retrieve the frat5 coef corresponding to the input dtd
855  stdair::DTDFratMap_T::const_iterator itDFC =
856  stdair::DEFAULT_DTD_FRAT5COEF_MAP.find(iDTD);
857  if (itDFC == stdair::DEFAULT_DTD_FRAT5COEF_MAP.end()) {
858  STDAIR_LOG_ERROR ("Cannot find frat5 coef for DTD = " << iDTD );
859  assert (false);
860  }
861  stdair::RealNumber_T lFrat5Coef =
862  stdair::DEFAULT_DTD_FRAT5COEF_MAP.at(iDTD);
863 
864  STDAIR_LOG_DEBUG ("Remaining proportion " << lRemainingProportion
865  << " Total " << lMeanValue
866  << " StdDev " << lStdDevValue
867  << "Frat5 Coef " << lFrat5Coef);
868 
869  std::ostringstream oStr;
870  // Compute the "forecast demand to come" proportion by class
871  itACL = lAirlineClassListList.begin();
872  for (; itACL != lAirlineClassListList.end(); ++itACL) {
873  const stdair::AirlineClassList* lAirlineClassList_ptr = *itACL;
874  const stdair::Yield_T& lYield = lAirlineClassList_ptr->getYield();
875  stdair::ProportionFactor_T lProportionFactor =
876  exp ((lYield - lMinWTP)*log(0.5)/(lMinWTP*(lFrat5Coef-1.0)));
877  // If the yield is smaller than minimal WTP, the factor is greater than 1.
878  // In that case it should be modified and put to 1.
879  lProportionFactor = std::min (lProportionFactor, 1.0);
880  lProportionFactorList.push_back(lProportionFactor - lPreviousProportionFactor);
881  lPreviousProportionFactor = lProportionFactor;
882  oStr << lAirlineClassList_ptr->toString() << lProportionFactor << " ";
883  }
884 
885  STDAIR_LOG_DEBUG (oStr.str());
886 
887  // Sanity check
888  assert (lAirlineClassListList.size() == lProportionFactorList.size());
889 
890  STDAIR_LOG_DEBUG ("Forecast for " << iOnDDate.describeKey()
891  << " " << iDTD << " days to departure");
892 
893  // store the forecast demand to come characteristics in the booking classes
894  stdair::ProportionFactorList_T::const_iterator itPF =
895  lProportionFactorList.begin();
896  itACL = lAirlineClassListList.begin();
897  for (; itACL != lAirlineClassListList.end(); ++itACL, ++itPF) {
898  const stdair::AirlineClassList* lAirlineClassList_ptr = *itACL;
899  const stdair::ProportionFactor_T& lProportionFactor = *itPF;
900  stdair::MeanValue_T lMeanValue = lProportionFactor*lRemainingMeanValue;
901  stdair::StdDevValue_T lStdDevValue =
902  lProportionFactor*lRemainingStdDevValue;
903  setOnDForecast(*lAirlineClassList_ptr, lMeanValue, lStdDevValue,
904  iOnDDate, iCabinCode, iBomRoot);
905  }
906 
907  }
908 
909  // ///////////////////////////////////////////////////////////////////
910  void RMOL_Service::
911  setOnDForecast (const stdair::AirlineClassList& iAirlineClassList,
912  const stdair::MeanValue_T& iMeanValue,
913  const stdair::StdDevValue_T& iStdDevValue,
914  stdair::OnDDate& iOnDDate,
915  const stdair::CabinCode_T& iCabinCode,
916  stdair::BomRoot& iBomRoot) {
917 
918  const stdair::AirportCode_T& lOrigin = iOnDDate.getOrigin();
919  const stdair::AirportCode_T& lDestination = iOnDDate.getDestination();
920 
921  const stdair::Date_T& lDepartureDate = iOnDDate.getDate();
922 
923  const stdair::AirlineCodeList_T& lAirlineCodeList =
924  iAirlineClassList.getAirlineCodeList();
925 
926  // Retrieve the class list (one class per airline)
927  const stdair::ClassList_StringList_T& lClassList_StringList =
928  iAirlineClassList.getClassCodeList();
929  assert (!lClassList_StringList.empty());
930  stdair::ClassCodeList_T lClassCodeList;
931  for (stdair::ClassList_StringList_T::const_iterator itCL =
932  lClassList_StringList.begin();
933  itCL != lClassList_StringList.end(); ++itCL){
934  const stdair::ClassList_String_T& lClassList_String = *itCL;
935  assert (lClassList_String.size() > 0);
936  stdair::ClassCode_T lFirstClass;
937  lFirstClass.append (lClassList_String, 0, 1);
938  lClassCodeList.push_back(lFirstClass);
939  }
940 
941  // Sanity check
942  assert (lAirlineCodeList.size() == lClassCodeList.size());
943  assert (!lAirlineCodeList.empty());
944 
945  if (lAirlineCodeList.size() == 1) {
946  // Store the forecast information in the case of a single segment
947  stdair::AirlineCode_T lAirlineCode = lAirlineCodeList.front();
948  stdair::ClassCode_T lClassCode = lClassCodeList.front();
949  stdair::Yield_T lYield = iAirlineClassList.getYield();
950  setOnDForecast(lAirlineCode, lDepartureDate, lOrigin,
951  lDestination, iCabinCode, lClassCode,
952  iMeanValue, iStdDevValue, lYield, iBomRoot);
953  } else {
954  // Store the forecast information in the case of a multiple segment
955 
956  stdair::Yield_T lYield = iAirlineClassList.getYield();
957  for (stdair::AirlineCodeList_T::const_iterator itAC =
958  lAirlineCodeList.begin();
959  itAC != lAirlineCodeList.end(); ++itAC) {
960  const stdair::AirlineCode_T& lAirlineCode = *itAC;
961  setOnDForecast(lAirlineCodeList, lAirlineCode, lDepartureDate, lOrigin,
962  lDestination, iCabinCode, lClassCodeList,
963  iMeanValue, iStdDevValue, lYield, iBomRoot);
964  }
965  }
966  }
967 
968  // ///////////////////////////////////////////////////////////////////
969  void RMOL_Service::
970  setOnDForecast (const stdair::AirlineCode_T& iAirlineCode,
971  const stdair::Date_T& iDepartureDate,
972  const stdair::AirportCode_T& iOrigin,
973  const stdair::AirportCode_T& iDestination,
974  const stdair::CabinCode_T& iCabinCode,
975  const stdair::ClassCode_T& iClassCode,
976  const stdair::MeanValue_T& iMeanValue,
977  const stdair::StdDevValue_T& iStdDevValue,
978  const stdair::Yield_T& iYield,
979  stdair::BomRoot& iBomRoot) {
980  stdair::Inventory* lInventory_ptr = iBomRoot.getInventory(iAirlineCode);
981  if (lInventory_ptr == NULL) {
982  STDAIR_LOG_ERROR ("Cannot find the inventory corresponding"
983  << " to the airline" << iAirlineCode) ;
984  assert(false);
985  }
986  const stdair::OnDDateList_T lOnDDateList =
987  stdair::BomManager::getList<stdair::OnDDate> (*lInventory_ptr);
988  assert (!lOnDDateList.empty());
989  bool lFoundOnDDate = false;
990  for (stdair::OnDDateList_T::const_iterator itOD = lOnDDateList.begin();
991  itOD != lOnDDateList.end(); ++itOD) {
992  stdair::OnDDate* lOnDDate_ptr = *itOD;
993  assert (lOnDDate_ptr != NULL);
994  const stdair::Date_T& lDepartureDate = lOnDDate_ptr->getDate();
995  const stdair::AirportCode_T& lOrigin = lOnDDate_ptr->getOrigin();
996  const stdair::AirportCode_T& lDestination = lOnDDate_ptr->getDestination();
997  const bool hasSegmentDateList =
998  stdair::BomManager::hasList<stdair::SegmentDate> (*lOnDDate_ptr);
999  if (hasSegmentDateList == false) {
1000  STDAIR_LOG_ERROR ("The O&D date " << lOnDDate_ptr->describeKey()
1001  << "has not been correctly initialized : SegmentDate list is missing");
1002  assert (false);
1003  }
1004  const stdair::SegmentDateList_T& lSegmentDateList =
1005  stdair::BomManager::getList<stdair::SegmentDate> (*lOnDDate_ptr);
1006  // Check if the the O&D date is the one we are looking for
1007  if (lDepartureDate == iDepartureDate && lOrigin == iOrigin &&
1008  lDestination == iDestination && lSegmentDateList.size() == 1) {
1009  stdair::CabinClassPair_T lCabinClassPair (iCabinCode, iClassCode);
1010  stdair::CabinClassPairList_T lCabinClassPairList;
1011  lCabinClassPairList.push_back(lCabinClassPair);
1012  const stdair::MeanStdDevPair_T lMeanStdDevPair (iMeanValue, iStdDevValue);
1013  const stdair::WTPDemandPair_T lWTPDemandPair (iYield, lMeanStdDevPair);
1014  lOnDDate_ptr->setDemandInformation(lCabinClassPairList, lWTPDemandPair);
1015  lFoundOnDDate = true;
1016  STDAIR_LOG_DEBUG (iAirlineCode << " Class " << iClassCode
1017  << " Mean " << iMeanValue
1018  << " Std Dev " << iStdDevValue);
1019  break;
1020  }
1021  }
1022 
1023  if (!lFoundOnDDate) {
1024  STDAIR_LOG_ERROR ("Cannot find class " << iClassCode << " in cabin "
1025  << iCabinCode << " for the segment "
1026  << iOrigin << "-" << iDestination << " with"
1027  << " the airline " << iAirlineCode);
1028  assert(false);
1029  }
1030  }
1031 
1032  // ///////////////////////////////////////////////////////////////////
1033  void RMOL_Service::
1034  setOnDForecast (const stdair::AirlineCodeList_T& iAirlineCodeList,
1035  const stdair::AirlineCode_T& iAirlineCode,
1036  const stdair::Date_T& iDepartureDate,
1037  const stdair::AirportCode_T& iOrigin,
1038  const stdair::AirportCode_T& iDestination,
1039  const stdair::CabinCode_T& iCabinCode,
1040  const stdair::ClassCodeList_T& iClassCodeList,
1041  const stdair::MeanValue_T& iMeanValue,
1042  const stdair::StdDevValue_T& iStdDevValue,
1043  const stdair::Yield_T& iYield,
1044  stdair::BomRoot& iBomRoot) {
1045  stdair::Inventory* lInventory_ptr = iBomRoot.getInventory(iAirlineCode);
1046  if (lInventory_ptr == NULL) {
1047  STDAIR_LOG_ERROR ("Cannot find the inventory corresponding"
1048  << " to the airline" << iAirlineCode) ;
1049  assert(false);
1050  }
1051  const stdair::OnDDateList_T lOnDDateList =
1052  stdair::BomManager::getList<stdair::OnDDate> (*lInventory_ptr);
1053  assert (!lOnDDateList.empty());
1054  bool lFoundOnDDate = false;
1055  for (stdair::OnDDateList_T::const_iterator itOD = lOnDDateList.begin();
1056  itOD != lOnDDateList.end(); ++itOD) {
1057  stdair::OnDDate* lOnDDate_ptr = *itOD;
1058  assert (lOnDDate_ptr != NULL);
1059  const stdair::Date_T& lDepartureDate = lOnDDate_ptr->getDate();
1060  const stdair::AirportCode_T& lOrigin = lOnDDate_ptr->getOrigin();
1061  const stdair::AirportCode_T& lDestination = lOnDDate_ptr->getDestination();
1062  const bool hasSegmentDateList =
1063  stdair::BomManager::hasList<stdair::SegmentDate> (*lOnDDate_ptr);
1064  if (hasSegmentDateList == false) {
1065  STDAIR_LOG_ERROR ("The O&D date " << lOnDDate_ptr->describeKey()
1066  << "has not been correctly initialized : SegmentDate list is missing");
1067  assert (false);
1068  }
1069  const stdair::SegmentDateList_T& lSegmentDateList =
1070  stdair::BomManager::getList<stdair::SegmentDate> (*lOnDDate_ptr);
1071  // Check if the O&D date might be the one we are looking for.
1072  // There still is a test to go through to see if the combination of airlines is right.
1073  if (lDepartureDate == iDepartureDate && lOrigin == iOrigin &&
1074  lDestination == iDestination && lSegmentDateList.size() == iAirlineCodeList.size()) {
1075  const stdair::SegmentDateList_T& lSegmentDateList =
1076  stdair::BomManager::getList<stdair::SegmentDate> (*lOnDDate_ptr);
1077  stdair::AirlineCodeList_T::const_iterator itAC = iAirlineCodeList.begin();
1078  stdair::SegmentDateList_T::const_iterator itSD = lSegmentDateList.begin();
1079  for (;itAC != iAirlineCodeList.end(); ++itAC, ++itSD) {
1080  const stdair::AirlineCode_T lForecastAirlineCode = *itAC;
1081  const stdair::SegmentDate* lSegmentDate_ptr = *itSD;
1082  // Check if the operating airline is a different one and check if it
1083  // is the airline that we are looking for.
1084  const stdair::SegmentDate* lOperatingSegmentDate_ptr =
1085  lSegmentDate_ptr->getOperatingSegmentDate ();
1086  if (lOperatingSegmentDate_ptr != NULL) {
1087  const stdair::FlightDate* lOperatingFD_ptr =
1088  stdair::BomManager::getParentPtr<stdair::FlightDate>(*lOperatingSegmentDate_ptr);
1089  const stdair::AirlineCode_T lOperatingAirlineCode =
1090  lOperatingFD_ptr->getAirlineCode();
1091  if (lOperatingAirlineCode != lForecastAirlineCode) {
1092  break;
1093  }
1094  } else {
1095  const stdair::AirlineCode_T lOperatingAirlineCode =
1096  lOnDDate_ptr->getAirlineCode();
1097  if (lOperatingAirlineCode != lForecastAirlineCode) {
1098  break;
1099  }
1100  }
1101  }
1102  if (itAC == iAirlineCodeList.end()) {lFoundOnDDate = true;}
1103  }
1104  if (lFoundOnDDate) {
1105  stdair::CabinClassPairList_T lCabinClassPairList;
1106  for (stdair::ClassCodeList_T::const_iterator itCC = iClassCodeList.begin();
1107  itCC != iClassCodeList.end(); ++itCC) {
1108  const stdair::ClassCode_T lClassCode = *itCC;
1109  stdair::CabinClassPair_T lCabinClassPair (iCabinCode, lClassCode);
1110  lCabinClassPairList.push_back(lCabinClassPair);
1111  }
1112  const stdair::MeanStdDevPair_T lMeanStdDevPair (iMeanValue, iStdDevValue);
1113  const stdair::YieldDemandPair_T lYieldDemandPair (iYield, lMeanStdDevPair);
1114  lOnDDate_ptr->setDemandInformation(lCabinClassPairList, lYieldDemandPair);
1115  lFoundOnDDate = true;
1116  std::ostringstream oACStr;
1117  for (stdair::AirlineCodeList_T::const_iterator itAC = iAirlineCodeList.begin();
1118  itAC != iAirlineCodeList.end(); ++itAC) {
1119  if (itAC == iAirlineCodeList.begin()) {
1120  oACStr << *itAC;
1121  }
1122  else {
1123  oACStr << "-" << *itAC;
1124  }
1125  }
1126  std::ostringstream oCCStr;
1127  for (stdair::ClassCodeList_T::const_iterator itCC = iClassCodeList.begin();
1128  itCC != iClassCodeList.end(); ++itCC) {
1129  if (itCC == iClassCodeList.begin()) {
1130  oCCStr << *itCC;
1131  }
1132  else {
1133  oCCStr << "-" << *itCC;
1134  }
1135  }
1136 
1137  STDAIR_LOG_DEBUG (oACStr.str() << " Classes " << oCCStr.str()
1138  << " Mean " << iMeanValue << " Std Dev " << iStdDevValue);
1139  break;
1140  }
1141  }
1142  if (!lFoundOnDDate) {
1143  STDAIR_LOG_ERROR ("Cannot find the required multi-segment O&D date: "
1144  << iOrigin << "-" << iDestination << " " << iDepartureDate);
1145  assert(false);
1146  }
1147  }
1148 
1149  // ///////////////////////////////////////////////////////////////////
1150  void RMOL_Service::
1151  resetDemandInformation (const stdair::DateTime_T& iRMEventTime) {
1152  if (_rmolServiceContext == NULL) {
1153  throw stdair::NonInitialisedServiceException ("The Rmol service "
1154  "has not been initialised");
1155  }
1156  assert (_rmolServiceContext != NULL);
1157  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
1158 
1159  // Retrieve the bom root
1160  stdair::STDAIR_Service& lSTDAIR_Service =
1161  lRMOL_ServiceContext.getSTDAIR_Service();
1162  stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
1163 
1164  const stdair::InventoryList_T lInventoryList =
1165  stdair::BomManager::getList<stdair::Inventory> (lBomRoot);
1166  assert (!lInventoryList.empty());
1167  for (stdair::InventoryList_T::const_iterator itInv = lInventoryList.begin();
1168  itInv != lInventoryList.end(); ++itInv) {
1169  const stdair::Inventory* lInventory_ptr = *itInv;
1170  assert (lInventory_ptr != NULL);
1171  resetDemandInformation (iRMEventTime, *lInventory_ptr);
1172  }
1173  }
1174 
1175  // ///////////////////////////////////////////////////////////////////
1176  void RMOL_Service::
1177  resetDemandInformation (const stdair::DateTime_T& iRMEventTime,
1178  const stdair::Inventory& iInventory) {
1179 
1180  const stdair::FlightDateList_T lFlightDateList =
1181  stdair::BomManager::getList<stdair::FlightDate> (iInventory);
1182  assert (!lFlightDateList.empty());
1183  for (stdair::FlightDateList_T::const_iterator itFD = lFlightDateList.begin();
1184  itFD != lFlightDateList.end(); ++itFD) {
1185  const stdair::FlightDate* lFlightDate_ptr = *itFD;
1186  assert (lFlightDate_ptr != NULL);
1187 
1188  // Retrieve the date from the RM event
1189  const stdair::Date_T lDate = iRMEventTime.date();
1190 
1191  const stdair::Date_T& lDepartureDate = lFlightDate_ptr->getDepartureDate();
1192  stdair::DateOffset_T lDateOffset = lDepartureDate - lDate;
1193  stdair::DTD_T lDTD = short (lDateOffset.days());
1194 
1195  stdair::DCPList_T::const_iterator itDCP =
1196  std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD);
1197  // Check if the demand forecast info corresponding to this flight date needs to be reset.
1198  if (itDCP != stdair::DEFAULT_DCP_LIST.end()) {
1199  // Check if the flight date holds a list of leg dates.
1200  // If so, find all leg cabin and reset the forecast they are holding.
1201  const bool hasLegDateList =
1202  stdair::BomManager::hasList<stdair::LegDate> (*lFlightDate_ptr);
1203  if (hasLegDateList == true) {
1204  const stdair::LegDateList_T lLegDateList =
1205  stdair::BomManager::getList<stdair::LegDate> (*lFlightDate_ptr);
1206  assert (!lLegDateList.empty());
1207  for (stdair::LegDateList_T::const_iterator itLD = lLegDateList.begin();
1208  itLD != lLegDateList.end(); ++itLD) {
1209  const stdair::LegDate* lLegDate_ptr = *itLD;
1210  assert (lLegDate_ptr != NULL);
1211  const stdair::LegCabinList_T lLegCabinList =
1212  stdair::BomManager::getList<stdair::LegCabin> (*lLegDate_ptr);
1213  assert (!lLegCabinList.empty());
1214  for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin();
1215  itLC != lLegCabinList.end(); ++itLC) {
1216  stdair::LegCabin* lLegCabin_ptr = *itLC;
1217  assert (lLegCabin_ptr != NULL);
1218  lLegCabin_ptr->emptyYieldLevelDemandMap();
1219  }
1220  }
1221  }
1222  }
1223  }
1224  }
1225 
1226  // ///////////////////////////////////////////////////////////////////
1227  void RMOL_Service::projectAggregatedDemandOnLegCabins(const stdair::DateTime_T& iRMEventTime) {
1228 
1229  if (_rmolServiceContext == NULL) {
1230  throw stdair::NonInitialisedServiceException ("The Rmol service "
1231  "has not been initialised");
1232  }
1233  assert (_rmolServiceContext != NULL);
1234  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
1235 
1236  // Retrieve the bom root
1237  stdair::STDAIR_Service& lSTDAIR_Service =
1238  lRMOL_ServiceContext.getSTDAIR_Service();
1239  stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
1240 
1241  // Retrieve the date from the RM event
1242  const stdair::Date_T lDate = iRMEventTime.date();
1243 
1244  const stdair::InventoryList_T lInventoryList =
1245  stdair::BomManager::getList<stdair::Inventory> (lBomRoot);
1246  assert (!lInventoryList.empty());
1247  for (stdair::InventoryList_T::const_iterator itInv = lInventoryList.begin();
1248  itInv != lInventoryList.end(); ++itInv) {
1249  const stdair::Inventory* lInventory_ptr = *itInv;
1250  assert (lInventory_ptr != NULL);
1251  const stdair::OnDDateList_T lOnDDateList =
1252  stdair::BomManager::getList<stdair::OnDDate> (*lInventory_ptr);
1253  assert (!lOnDDateList.empty());
1254  for (stdair::OnDDateList_T::const_iterator itOD = lOnDDateList.begin();
1255  itOD != lOnDDateList.end(); ++itOD) {
1256  stdair::OnDDate* lOnDDate_ptr = *itOD;
1257  assert (lOnDDate_ptr != NULL);
1258 
1259  const stdair::Date_T& lDepartureDate = lOnDDate_ptr->getDate();
1260  stdair::DateOffset_T lDateOffset = lDepartureDate - lDate;
1261  stdair::DTD_T lDTD = short (lDateOffset.days());
1262 
1263  stdair::DCPList_T::const_iterator itDCP =
1264  std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD);
1265  // Check if the forecast for this O&D date needs to be projected.
1266  if (itDCP != stdair::DEFAULT_DCP_LIST.end()) {
1267 
1268  // Browse the demand info map.
1269  const stdair::StringDemandStructMap_T& lStringDemandStructMap =
1270  lOnDDate_ptr->getDemandInfoMap ();
1271  for (stdair::StringDemandStructMap_T::const_iterator itStrDS = lStringDemandStructMap.begin();
1272  itStrDS != lStringDemandStructMap.end(); ++itStrDS) {
1273  std::string lCabinClassPath = itStrDS->first;
1274  const stdair::YieldDemandPair_T& lYieldDemandPair =
1275  itStrDS->second;
1276  const stdair::CabinClassPairList_T& lCabinClassPairList =
1277  lOnDDate_ptr->getCabinClassPairList(lCabinClassPath);
1278  const stdair::NbOfSegments_T& lNbOfSegments = lOnDDate_ptr->getNbOfSegments();
1279  // Sanity check
1280  assert (lCabinClassPairList.size() == lNbOfSegments);
1281 
1282  const stdair::SegmentDateList_T lOnDSegmentDateList =
1283  stdair::BomManager::getList<stdair::SegmentDate> (*lOnDDate_ptr);
1284  // Sanity check
1285  assert (lOnDSegmentDateList.size() == lNbOfSegments);
1286  stdair::CabinClassPairList_T::const_iterator itCCP = lCabinClassPairList.begin();
1287  stdair::SegmentDateList_T::const_iterator itSD = lOnDSegmentDateList.begin();
1288  for (; itSD != lOnDSegmentDateList.end(); ++itCCP, ++itSD) {
1289  const stdair::SegmentDate* lSegmentDate_ptr = *itSD;
1290  const stdair::SegmentDate* lOperatingSegmentDate_ptr =
1291  lSegmentDate_ptr->getOperatingSegmentDate ();
1292  assert (lSegmentDate_ptr != NULL);
1293  // Only operated legs receive the demand information.
1294  if (lOperatingSegmentDate_ptr == NULL) {
1295  const stdair::CabinCode_T lCabinCode = itCCP->first;
1296  const stdair::ClassCode_T lClassCode = itCCP->second;
1297  const stdair::SegmentCabin* lSegmentCabin_ptr =
1298  stdair::BomManager::getObjectPtr<stdair::SegmentCabin> (*lSegmentDate_ptr,
1299  lCabinCode);
1300  assert (lSegmentCabin_ptr != NULL);
1301  // Retrieve the booking class (level of aggregation of demand).
1302  // The yield of the class is assigned to all types of demand for it.
1303  const stdair::BookingClass* lBookingClass_ptr =
1304  stdair::BomManager::getObjectPtr<stdair::BookingClass> (*lSegmentCabin_ptr,
1305  lClassCode);
1306  assert (lBookingClass_ptr != NULL);
1307  const stdair::LegCabinList_T lLegCabinList =
1308  stdair::BomManager::getList<stdair::LegCabin> (*lSegmentCabin_ptr);
1309  assert (!lLegCabinList.empty());
1310  const int lNbOfLegs = lLegCabinList.size();
1311  // Determine the yield (equally distributed over legs).
1312  const stdair::Yield_T& lYield = lBookingClass_ptr->getYield()/lNbOfLegs;
1313  const stdair::MeanStdDevPair_T& lMeanStdDevPair =
1314  lYieldDemandPair.second;
1315  const stdair::MeanValue_T& lMeanValue = lMeanStdDevPair.first;
1316  const stdair::StdDevValue_T& lStdDevValue = lMeanStdDevPair.second;
1317  for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin();
1318  itLC != lLegCabinList.end(); ++itLC) {
1319  stdair::LegCabin* lLegCabin_ptr = *itLC;
1320  assert (lLegCabin_ptr != NULL);
1321  lLegCabin_ptr->addDemandInformation (lYield, lMeanValue, lStdDevValue);
1322  }
1323  }
1324  }
1325  }
1326  }
1327  }
1328  }
1329  }
1330 
1331  // ///////////////////////////////////////////////////////////////////
1332  void RMOL_Service::projectOnDDemandOnLegCabinsUsingYP(const stdair::DateTime_T& iRMEventTime) {
1333 
1334  if (_rmolServiceContext == NULL) {
1335  throw stdair::NonInitialisedServiceException ("The Rmol service "
1336  "has not been initialised");
1337  }
1338  assert (_rmolServiceContext != NULL);
1339  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
1340 
1341  // Retrieve the bom root
1342  stdair::STDAIR_Service& lSTDAIR_Service =
1343  lRMOL_ServiceContext.getSTDAIR_Service();
1344  stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
1345 
1346  // Retrieve the date from the RM event
1347  const stdair::Date_T lDate = iRMEventTime.date();
1348 
1349  const stdair::InventoryList_T lInventoryList =
1350  stdair::BomManager::getList<stdair::Inventory> (lBomRoot);
1351  assert (!lInventoryList.empty());
1352  for (stdair::InventoryList_T::const_iterator itInv = lInventoryList.begin();
1353  itInv != lInventoryList.end(); ++itInv) {
1354  const stdair::Inventory* lInventory_ptr = *itInv;
1355  assert (lInventory_ptr != NULL);
1356  const stdair::OnDDateList_T lOnDDateList =
1357  stdair::BomManager::getList<stdair::OnDDate> (*lInventory_ptr);
1358  assert (!lOnDDateList.empty());
1359  for (stdair::OnDDateList_T::const_iterator itOD = lOnDDateList.begin();
1360  itOD != lOnDDateList.end(); ++itOD) {
1361  stdair::OnDDate* lOnDDate_ptr = *itOD;
1362  assert (lOnDDate_ptr != NULL);
1363 
1364  const stdair::Date_T& lDepartureDate = lOnDDate_ptr->getDate();
1365  stdair::DateOffset_T lDateOffset = lDepartureDate - lDate;
1366  stdair::DTD_T lDTD = short (lDateOffset.days());
1367 
1368  stdair::DCPList_T::const_iterator itDCP =
1369  std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD);
1370  // Check if the forecast for this O&D date needs to be projected.
1371  if (itDCP != stdair::DEFAULT_DCP_LIST.end()) {
1372 
1373  // Browse the demand info map.
1374  const stdair::StringDemandStructMap_T& lStringDemandStructMap =
1375  lOnDDate_ptr->getDemandInfoMap ();
1376  for (stdair::StringDemandStructMap_T::const_iterator itStrDS = lStringDemandStructMap.begin();
1377  itStrDS != lStringDemandStructMap.end(); ++itStrDS) {
1378  std::string lCabinClassPath = itStrDS->first;
1379  const stdair::YieldDemandPair_T& lYieldDemandPair =
1380  itStrDS->second;
1381  const stdair::CabinClassPairList_T& lCabinClassPairList =
1382  lOnDDate_ptr->getCabinClassPairList(lCabinClassPath);
1383  const stdair::NbOfSegments_T& lNbOfSegments = lOnDDate_ptr->getNbOfSegments();
1384  // Sanity check
1385  assert (lCabinClassPairList.size() == lNbOfSegments);
1386 
1387  const stdair::SegmentDateList_T lOnDSegmentDateList =
1388  stdair::BomManager::getList<stdair::SegmentDate> (*lOnDDate_ptr);
1389  // Sanity check
1390  assert (lOnDSegmentDateList.size() == lNbOfSegments);
1391  stdair::CabinClassPairList_T::const_iterator itCCP = lCabinClassPairList.begin();
1392  stdair::SegmentDateList_T::const_iterator itSD = lOnDSegmentDateList.begin();
1393  for (; itSD != lOnDSegmentDateList.end(); ++itCCP, ++itSD) {
1394  const stdair::SegmentDate* lSegmentDate_ptr = *itSD;
1395  assert (lSegmentDate_ptr != NULL);
1396  const stdair::SegmentDate* lOperatingSegmentDate_ptr =
1397  lSegmentDate_ptr->getOperatingSegmentDate ();
1398  // Only operated legs receive the demand information.
1399  if (lOperatingSegmentDate_ptr == NULL) {
1400  const stdair::CabinCode_T lCabinCode = itCCP->first;
1401  const stdair::ClassCode_T lClassCode = itCCP->second;
1402  const stdair::SegmentCabin* lSegmentCabin_ptr =
1403  stdair::BomManager::getObjectPtr<stdair::SegmentCabin> (*lSegmentDate_ptr,
1404  lCabinCode);
1405  assert (lSegmentCabin_ptr != NULL);
1406  const stdair::LegCabinList_T lLegCabinList =
1407  stdair::BomManager::getList<stdair::LegCabin> (*lSegmentCabin_ptr);
1408  assert (!lLegCabinList.empty());
1409  const int lNbOfLegs = lLegCabinList.size();
1410  // Determine the yield (equally distributed over segments and then legs).
1411  const stdair::MeanStdDevPair_T& lMeanStdDevPair =
1412  lYieldDemandPair.second;
1413  const stdair::Yield_T& lYield = lYieldDemandPair.first/(lNbOfLegs*lNbOfSegments);
1414  const stdair::MeanValue_T& lMeanValue = lMeanStdDevPair.first;
1415  const stdair::StdDevValue_T& lStdDevValue = lMeanStdDevPair.second;
1416  for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin();
1417  itLC != lLegCabinList.end(); ++itLC) {
1418  stdair::LegCabin* lLegCabin_ptr = *itLC;
1419  assert (lLegCabin_ptr != NULL);
1420  lLegCabin_ptr->addDemandInformation (lYield, lMeanValue, lStdDevValue);
1421  }
1422  }
1423  }
1424  }
1425  }
1426  }
1427  }
1428  }
1429 
1430  // ///////////////////////////////////////////////////////////////////
1431  void RMOL_Service::optimiseOnD (const stdair::DateTime_T& iRMEventTime) {
1432 
1433  if (_rmolServiceContext == NULL) {
1434  throw stdair::NonInitialisedServiceException ("The Rmol service "
1435  "has not been initialised");
1436  }
1437  assert (_rmolServiceContext != NULL);
1438  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
1439 
1440  // Retrieve the bom root
1441  stdair::STDAIR_Service& lSTDAIR_Service =
1442  lRMOL_ServiceContext.getSTDAIR_Service();
1443  stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
1444 
1445  // Retrieve the date from the RM event
1446  const stdair::Date_T lDate = iRMEventTime.date();
1447 
1448  const stdair::InventoryList_T& lInvList =
1449  stdair::BomManager::getList<stdair::Inventory> (lBomRoot);
1450  for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
1451  itInv != lInvList.end(); ++itInv) {
1452  stdair::Inventory* lCurrentInv_ptr = *itInv;
1453  assert (lCurrentInv_ptr != NULL);
1454 
1455  const stdair::FlightDateList_T& lFlightDateList =
1456  stdair::BomManager::getList<stdair::FlightDate> (*lCurrentInv_ptr);
1457  for (stdair::FlightDateList_T::const_iterator itFlightDate =
1458  lFlightDateList.begin();
1459  itFlightDate != lFlightDateList.end(); ++itFlightDate) {
1460  stdair::FlightDate* lCurrentFlightDate_ptr = *itFlightDate;
1461  assert (lCurrentFlightDate_ptr != NULL);
1462 
1463  const stdair::Date_T& lCurrentDepartureDate = lCurrentFlightDate_ptr->getDepartureDate();
1464  stdair::DateOffset_T lDateOffset = lCurrentDepartureDate - lDate;
1465  stdair::DTD_T lDTD = short (lDateOffset.days());
1466 
1467  stdair::DCPList_T::const_iterator itDCP =
1468  std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD);
1469  // Check if the optimisation is needed.
1470  if (itDCP != stdair::DEFAULT_DCP_LIST.end()) {
1471  STDAIR_LOG_DEBUG ("Optimisation using O&D forecast: " << lCurrentInv_ptr->getAirlineCode()
1472  << " Departure " << lCurrentDepartureDate << " DTD " << lDTD);
1473  Optimiser::optimiseUsingOnDForecast (*lCurrentFlightDate_ptr);
1474  }
1475  }
1476  }
1477  }
1478 
1479  // ///////////////////////////////////////////////////////////////////
1480  void RMOL_Service::updateBidPrice (const stdair::DateTime_T& iRMEventTime) {
1481 
1482  if (_rmolServiceContext == NULL) {
1483  throw stdair::NonInitialisedServiceException ("The Rmol service "
1484  "has not been initialised");
1485  }
1486  assert (_rmolServiceContext != NULL);
1487  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
1488 
1489  // Retrieve the bom root
1490  stdair::STDAIR_Service& lSTDAIR_Service =
1491  lRMOL_ServiceContext.getSTDAIR_Service();
1492  stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
1493 
1494  // Retrieve the date from the RM event
1495  const stdair::Date_T lDate = iRMEventTime.date();
1496 
1497  const stdair::InventoryList_T& lInvList =
1498  stdair::BomManager::getList<stdair::Inventory> (lBomRoot);
1499 
1500  for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
1501  itInv != lInvList.end(); ++itInv) {
1502  stdair::Inventory* lCurrentInv_ptr = *itInv;
1503  assert (lCurrentInv_ptr != NULL);
1504 
1505  const stdair::FlightDateList_T& lFlightDateList =
1506  stdair::BomManager::getList<stdair::FlightDate> (*lCurrentInv_ptr);
1507  for (stdair::FlightDateList_T::const_iterator itFlightDate =
1508  lFlightDateList.begin();
1509  itFlightDate != lFlightDateList.end(); ++itFlightDate) {
1510  stdair::FlightDate* lCurrentFlightDate_ptr = *itFlightDate;
1511  assert (lCurrentFlightDate_ptr != NULL);
1512 
1513  const stdair::Date_T& lCurrentDepartureDate = lCurrentFlightDate_ptr->getDepartureDate();
1514  stdair::DateOffset_T lDateOffset = lCurrentDepartureDate - lDate;
1515  stdair::DTD_T lDTD = short (lDateOffset.days());
1516 
1517  stdair::DCPList_T::const_iterator itDCP =
1518  std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD);
1519  // Check if the operation is needed.
1520  if (itDCP != stdair::DEFAULT_DCP_LIST.end()) {
1521  updateBidPrice (*lCurrentFlightDate_ptr, lBomRoot);
1522  }
1523  }
1524  }
1525  }
1526 
1527  // ///////////////////////////////////////////////////////////////////
1528  void RMOL_Service::updateBidPrice (const stdair::FlightDate& iFlightDate,
1529  stdair::BomRoot& iBomRoot) {
1530  const stdair::SegmentDateList_T& lSegmentDateList =
1531  stdair::BomManager::getList<stdair::SegmentDate> (iFlightDate);
1532  const stdair::AirlineCode_T& lOptAC = iFlightDate.getAirlineCode();
1533  const std::string lFDKeyStr = iFlightDate.describeKey();
1534 
1535  for (stdair::SegmentDateList_T::const_iterator itSegmentDate = lSegmentDateList.begin();
1536  itSegmentDate != lSegmentDateList.end(); ++itSegmentDate) {
1537  stdair::SegmentDate* lSegmentDate_ptr = *itSegmentDate;
1538  assert (lSegmentDate_ptr != NULL);
1539  const bool hasSegmentDateList =
1540  stdair::BomManager::hasList<stdair::SegmentDate>(*lSegmentDate_ptr);
1541  if (hasSegmentDateList == true) {
1542  const stdair::LegDateList_T& lLegDateList =
1543  stdair::BomManager::getList<stdair::LegDate>(*lSegmentDate_ptr);
1544  // Get the list of marketing carriers segments.
1545  // These are part of maketing partners inventories images held by the operating airline.
1546  const stdair::SegmentDateList_T& lMktSegmentDateList =
1547  stdair::BomManager::getList<stdair::SegmentDate>(*lSegmentDate_ptr);
1548  for (stdair::SegmentDateList_T::const_iterator itMktSD = lMktSegmentDateList.begin();
1549  itMktSD != lMktSegmentDateList.end(); ++itMktSD) {
1550  // Get the marketing airline code.
1551  stdair::SegmentDate* lMktSD_ptr = *itMktSD;
1552  assert (lMktSD_ptr != NULL);
1553  stdair::FlightDate* lMktFD_ptr =
1554  stdair::BomManager::getParentPtr<stdair::FlightDate>(*lMktSD_ptr);
1555  assert (lMktFD_ptr != NULL);
1556  const stdair::AirlineCode_T& lMktAC = lMktFD_ptr->getAirlineCode();
1557  // Get the (real) marketer inventory.
1558  const stdair::Inventory* lMktInv_ptr =
1559  stdair::BomManager::getObjectPtr<stdair::Inventory>(iBomRoot,lMktAC);
1560  assert (lMktInv_ptr != NULL);
1561  // Get the image of the operating airline inventory held by the marketer.
1562  const stdair::Inventory* lOptInv_ptr =
1563  stdair::BomManager::getObjectPtr<stdair::Inventory>(*lMktInv_ptr,lOptAC);
1564  assert (lOptInv_ptr != NULL);
1565  // Find the image of the concerned flight date.
1566  const stdair::FlightDate* lOptFD_ptr =
1567  stdair::BomManager::getObjectPtr<stdair::FlightDate>(*lOptInv_ptr,lFDKeyStr);
1568  assert (lOptFD_ptr != NULL);
1569  // Browse the list of leg dates in the real operating inventory.
1570  // Retrieve the image of each leg date.
1571  for (stdair::LegDateList_T::const_iterator itLD = lLegDateList.begin();
1572  itLD != lLegDateList.end(); ++itLD) {
1573  const stdair::LegDate* lLD_ptr = *itLD;
1574  assert (lLD_ptr != NULL);
1575  const std::string lLDKeyStr = lLD_ptr->describeKey();
1576  stdair::LegDate* lOptLD_ptr =
1577  stdair::BomManager::getObjectPtr<stdair::LegDate>(*lOptFD_ptr,lLDKeyStr);
1578  assert (lOptLD_ptr != NULL);
1579  const stdair::LegCabinList_T& lLegCabinList_T =
1580  stdair::BomManager::getList<stdair::LegCabin>(*lLD_ptr);
1581  // Browse the list of leg cabins in the real operating inventory.
1582  // Retrieve the image of each leg cabin and update the bid price of the real and send it to the image.
1583  for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList_T.begin();
1584  itLC != lLegCabinList_T.end(); ++itLC) {
1585  stdair::LegCabin* lLC_ptr = *itLC;
1586  assert (lLC_ptr != NULL);
1587  const std::string lLCKeyStr = lLC_ptr->describeKey();
1588  stdair::LegCabin* lOptLC_ptr =
1589  stdair::BomManager::getObjectPtr<stdair::LegCabin>(*lOptLD_ptr, lLCKeyStr);
1590  assert (lOptLC_ptr != NULL);
1591  // Update the current bid price of the real leg.
1592  lLC_ptr->updateCurrentBidPrice();
1593  // Update the previous bid price (store the current).
1594  lOptLC_ptr->updatePreviousBidPrice();
1595  // Update the current bid price.
1596  lOptLC_ptr->setCurrentBidPrice (lLC_ptr->getCurrentBidPrice());
1597 
1598  STDAIR_LOG_DEBUG ("Update bid price of " << lLC_ptr->getFullerKey()
1599  << " : " << lOptLC_ptr->getCurrentBidPrice()
1600  << " Availability pool " << lLC_ptr->getAvailabilityPool());
1601  }
1602  }
1603  }
1604  }
1605  }
1606  }
1607 
1608  // ///////////////////////////////////////////////////////////////////
1609  void RMOL_Service::projectOnDDemandOnLegCabinsUsingDA(const stdair::DateTime_T& iRMEventTime) {
1610 
1611  if (_rmolServiceContext == NULL) {
1612  throw stdair::NonInitialisedServiceException ("The Rmol service "
1613  "has not been initialised");
1614  }
1615  assert (_rmolServiceContext != NULL);
1616  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
1617 
1618  // Retrieve the bom root
1619  stdair::STDAIR_Service& lSTDAIR_Service =
1620  lRMOL_ServiceContext.getSTDAIR_Service();
1621  stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
1622 
1623  // Retrieve the date from the RM event
1624  const stdair::Date_T lDate = iRMEventTime.date();
1625 
1626  const stdair::InventoryList_T lInventoryList =
1627  stdair::BomManager::getList<stdair::Inventory> (lBomRoot);
1628  assert (!lInventoryList.empty());
1629  for (stdair::InventoryList_T::const_iterator itInv = lInventoryList.begin();
1630  itInv != lInventoryList.end(); ++itInv) {
1631  const stdair::Inventory* lInventory_ptr = *itInv;
1632  assert (lInventory_ptr != NULL);
1633  const stdair::OnDDateList_T lOnDDateList =
1634  stdair::BomManager::getList<stdair::OnDDate> (*lInventory_ptr);
1635  assert (!lOnDDateList.empty());
1636  for (stdair::OnDDateList_T::const_iterator itOD = lOnDDateList.begin();
1637  itOD != lOnDDateList.end(); ++itOD) {
1638  stdair::OnDDate* lOnDDate_ptr = *itOD;
1639  assert (lOnDDate_ptr != NULL);
1640 
1641  const stdair::Date_T& lDepartureDate = lOnDDate_ptr->getDate();
1642  stdair::DateOffset_T lDateOffset = lDepartureDate - lDate;
1643  stdair::DTD_T lDTD = short (lDateOffset.days());
1644 
1645  stdair::DCPList_T::const_iterator itDCP =
1646  std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD);
1647  // Check if the forecast for this O&D date needs to be projected.
1648  if (itDCP != stdair::DEFAULT_DCP_LIST.end()) {
1649 
1650  // Browse the demand info map.
1651  const stdair::StringDemandStructMap_T& lStringDemandStructMap =
1652  lOnDDate_ptr->getDemandInfoMap ();
1653  for (stdair::StringDemandStructMap_T::const_iterator itStrDS = lStringDemandStructMap.begin();
1654  itStrDS != lStringDemandStructMap.end(); ++itStrDS) {
1655  std::string lCabinClassPath = itStrDS->first;
1656  const stdair::YieldDemandPair_T& lYieldDemandPair = itStrDS->second;
1657  const stdair::CabinClassPairList_T& lCabinClassPairList =
1658  lOnDDate_ptr->getCabinClassPairList(lCabinClassPath);
1659  const stdair::NbOfSegments_T& lNbOfSegments = lOnDDate_ptr->getNbOfSegments();
1660  // Sanity check
1661  assert (lCabinClassPairList.size() == lNbOfSegments);
1662 
1663  //
1664  const stdair::SegmentDateList_T lOnDSegmentDateList =
1665  stdair::BomManager::getList<stdair::SegmentDate> (*lOnDDate_ptr);
1666  // Sanity check
1667  assert (lOnDSegmentDateList.size() == lNbOfSegments);
1668  stdair::CabinClassPairList_T::const_iterator itCCP = lCabinClassPairList.begin();
1669  stdair::SegmentDateList_T::const_iterator itSD = lOnDSegmentDateList.begin();
1670  // List of bid prices that will be used to easily compute displacement-ajusted yields.
1671  std::list<stdair::BidPrice_T> lBidPriceList;
1672  // The sum of bid prices that will be stored in the list above.
1673  stdair::BidPrice_T lTotalBidPrice = 0;
1674  // Retrieve the bid prices
1675  for (; itSD != lOnDSegmentDateList.end(); ++itCCP, ++itSD) {
1676  // Get the operating segment cabin (it holds the bid price information).
1677  const stdair::SegmentDate* lSegmentDate_ptr = *itSD;
1678  assert (lSegmentDate_ptr != NULL);
1679  // Get the operating airline code and check if it is the airline we are looking for.
1680  const stdair::SegmentDate* lOperatingSegmentDate_ptr =
1681  lSegmentDate_ptr->getOperatingSegmentDate ();
1682  if (lOperatingSegmentDate_ptr != NULL) {
1683  lSegmentDate_ptr = lOperatingSegmentDate_ptr;
1684  }
1685  const stdair::CabinCode_T lCabinCode = itCCP->first;
1686  const stdair::SegmentCabin* lSegmentCabin_ptr =
1687  stdair::BomManager::getObjectPtr<stdair::SegmentCabin> (*lSegmentDate_ptr,
1688  lCabinCode);
1689  assert (lSegmentCabin_ptr != NULL);
1690  stdair::BidPrice_T lBidPrice = 0;
1691  const stdair::LegCabinList_T lLegCabinList =
1692  stdair::BomManager::getList<stdair::LegCabin>(*lSegmentCabin_ptr);
1693  for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin();
1694  itLC != lLegCabinList.end(); ++itLC) {
1695  const stdair::LegCabin* lLegCabin_ptr = *itLC;
1696  assert (lLegCabin_ptr != NULL);
1697  lBidPrice += lLegCabin_ptr->getCurrentBidPrice();
1698  }
1699  lBidPriceList.push_back (lBidPrice);
1700  lTotalBidPrice += lBidPrice;
1701  }
1702 
1703 
1704  itCCP = lCabinClassPairList.begin();
1705  itSD = lOnDSegmentDateList.begin();
1706  std::list<stdair::BidPrice_T>::const_iterator itBP = lBidPriceList.begin();
1707  for (; itSD != lOnDSegmentDateList.end(); ++itCCP, ++itSD, ++itBP) {
1708  stdair::BidPrice_T lBidPrice = *itBP;
1709  stdair::BidPrice_T lComplementaryBidPrice = lTotalBidPrice - lBidPrice;
1710  const stdair::SegmentDate* lSegmentDate_ptr = *itSD;
1711  assert (lSegmentDate_ptr != NULL);
1712  const stdair::SegmentDate* lOperatingSegmentDate_ptr =
1713  lSegmentDate_ptr->getOperatingSegmentDate ();
1714  // Only operated legs receive the demand information.
1715  if (lOperatingSegmentDate_ptr == NULL) {
1716  const stdair::CabinCode_T lCabinCode = itCCP->first;
1717  const stdair::ClassCode_T lClassCode = itCCP->second;
1718  const stdair::SegmentCabin* lSegmentCabin_ptr =
1719  stdair::BomManager::getObjectPtr<stdair::SegmentCabin> (*lSegmentDate_ptr,
1720  lCabinCode);
1721  assert (lSegmentCabin_ptr != NULL);
1722  const stdair::LegCabinList_T lLegCabinList =
1723  stdair::BomManager::getList<stdair::LegCabin> (*lSegmentCabin_ptr);
1724  assert (!lLegCabinList.empty());
1725  // Determine the displacement-adjusted yield.
1726  // It is set to 100 (positive small value), if the computed value is negative.
1727  const stdair::Yield_T& lDAYield =
1728  std::max(100., lYieldDemandPair.first - lComplementaryBidPrice);
1729 
1730 
1731  stdair::Yield_T lYield = lDAYield;
1732  // In order to be protected against important variations of partners' bid price,
1733  // the displacement adjusted yield is noy allowed to get out of a certain range.
1734  // This range is here chosen to be from 80% to 100% of the (static rule) prorated yield.
1735  /*
1736  const int lNbOfLegs = lLegCabinList.size();
1737  const stdair::Yield_T& lStaticProrationYield =
1738  lDemandStruct.getYield()/(lNbOfLegs*lNbOfSegments);
1739  if (lDAYield < 0.8*lStaticProrationYield){
1740  lYield = 0.8*lStaticProrationYield;
1741  }
1742  if (lDAYield > lStaticProrationYield) {
1743  lYield = lStaticProrationYield;
1744  }
1745  */
1746  const stdair::MeanStdDevPair_T& lMeanStdDevPair =
1747  lYieldDemandPair.second;
1748  const stdair::MeanValue_T& lMeanValue = lMeanStdDevPair.first;
1749  const stdair::StdDevValue_T& lStdDevValue = lMeanStdDevPair.second;
1750  for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin();
1751  itLC != lLegCabinList.end(); ++itLC) {
1752  stdair::LegCabin* lLegCabin_ptr = *itLC;
1753  assert (lLegCabin_ptr != NULL);
1754  lLegCabin_ptr->addDemandInformation (lYield, lMeanValue, lStdDevValue);
1755  }
1756  }
1757  }
1758  }
1759  }
1760  }
1761  }
1762  }
1763 
1764  // ///////////////////////////////////////////////////////////////////
1765  void RMOL_Service::projectOnDDemandOnLegCabinsUsingDYP(const stdair::DateTime_T& iRMEventTime) {
1766 
1767  if (_rmolServiceContext == NULL) {
1768  throw stdair::NonInitialisedServiceException ("The Rmol service "
1769  "has not been initialised");
1770  }
1771  assert (_rmolServiceContext != NULL);
1772  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
1773 
1774  // Retrieve the bom root
1775  stdair::STDAIR_Service& lSTDAIR_Service =
1776  lRMOL_ServiceContext.getSTDAIR_Service();
1777  stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
1778 
1779  const stdair::InventoryList_T lInventoryList =
1780  stdair::BomManager::getList<stdair::Inventory> (lBomRoot);
1781  assert (!lInventoryList.empty());
1782  for (stdair::InventoryList_T::const_iterator itInv = lInventoryList.begin();
1783  itInv != lInventoryList.end(); ++itInv) {
1784  const stdair::Inventory* lInventory_ptr = *itInv;
1785  assert (lInventory_ptr != NULL);
1786  projectOnDDemandOnLegCabinsUsingDYP (iRMEventTime, *lInventory_ptr);
1787  }
1788  }
1789 
1790  // ///////////////////////////////////////////////////////////////////
1791  void RMOL_Service::projectOnDDemandOnLegCabinsUsingDYP(const stdair::DateTime_T& iRMEventTime,
1792  const stdair::Inventory& iInventory) {
1793 
1794  const stdair::OnDDateList_T lOnDDateList =
1795  stdair::BomManager::getList<stdair::OnDDate> (iInventory);
1796  assert (!lOnDDateList.empty());
1797  for (stdair::OnDDateList_T::const_iterator itOD = lOnDDateList.begin();
1798  itOD != lOnDDateList.end(); ++itOD) {
1799  stdair::OnDDate* lOnDDate_ptr = *itOD;
1800  assert (lOnDDate_ptr != NULL);
1801 
1802  // Retrieve the date from the RM event
1803  const stdair::Date_T lDate = iRMEventTime.date();
1804 
1805  const stdair::Date_T& lDepartureDate = lOnDDate_ptr->getDate();
1806  stdair::DateOffset_T lDateOffset = lDepartureDate - lDate;
1807  stdair::DTD_T lDTD = short (lDateOffset.days());
1808 
1809  stdair::DCPList_T::const_iterator itDCP =
1810  std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD);
1811  // Check if the forecast for this O&D date needs to be projected.
1812  if (itDCP != stdair::DEFAULT_DCP_LIST.end()) {
1813 
1814  // Browse the demand info map.
1815  const stdair::StringDemandStructMap_T& lStringDemandStructMap =
1816  lOnDDate_ptr->getDemandInfoMap ();
1817  for (stdair::StringDemandStructMap_T::const_iterator itStrDS = lStringDemandStructMap.begin();
1818  itStrDS != lStringDemandStructMap.end(); ++itStrDS) {
1819  std::string lCabinClassPath = itStrDS->first;
1820  const stdair::YieldDemandPair_T& lYieldDemandPair = itStrDS->second;
1821  const stdair::CabinClassPairList_T& lCabinClassPairList =
1822  lOnDDate_ptr->getCabinClassPairList(lCabinClassPath);
1823  const stdair::NbOfSegments_T& lNbOfSegments = lOnDDate_ptr->getNbOfSegments();
1824  // Sanity check
1825  assert (lCabinClassPairList.size() == lNbOfSegments);
1826 
1827  //
1828  const stdair::SegmentDateList_T lOnDSegmentDateList =
1829  stdair::BomManager::getList<stdair::SegmentDate> (*lOnDDate_ptr);
1830  // Sanity check
1831  assert (lOnDSegmentDateList.size() == lNbOfSegments);
1832  stdair::CabinClassPairList_T::const_iterator itCCP = lCabinClassPairList.begin();
1833  stdair::SegmentDateList_T::const_iterator itSD = lOnDSegmentDateList.begin();
1834  // The sum of bid prices of all cabins.
1835  stdair::BidPrice_T lTotalBidPrice = 0;
1836  for (; itSD != lOnDSegmentDateList.end(); ++itCCP, ++itSD) {
1837  // Get the operating segment cabin (it holds the bid price information).
1838  const stdair::SegmentDate* lSegmentDate_ptr = *itSD;
1839  assert (lSegmentDate_ptr != NULL);
1840  // Get the operating airline code and check if it is the airline we are looking for.
1841  const stdair::SegmentDate* lOperatingSegmentDate_ptr =
1842  lSegmentDate_ptr->getOperatingSegmentDate ();
1843  if (lOperatingSegmentDate_ptr != NULL) {
1844  lSegmentDate_ptr = lOperatingSegmentDate_ptr;
1845  }
1846  const stdair::CabinCode_T lCabinCode = itCCP->first;
1847  const stdair::SegmentCabin* lSegmentCabin_ptr =
1848  stdair::BomManager::getObjectPtr<stdair::SegmentCabin> (*lSegmentDate_ptr,
1849  lCabinCode);
1850  assert (lSegmentCabin_ptr != NULL);
1851  const stdair::LegCabinList_T lLegCabinList =
1852  stdair::BomManager::getList<stdair::LegCabin>(*lSegmentCabin_ptr);
1853  for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin();
1854  itLC != lLegCabinList.end(); ++itLC) {
1855  const stdair::LegCabin* lLegCabin_ptr = *itLC;
1856  assert (lLegCabin_ptr != NULL);
1857  lTotalBidPrice += lLegCabin_ptr->getCurrentBidPrice();
1858  }
1859  }
1860 
1861 
1862  itCCP = lCabinClassPairList.begin();
1863  itSD = lOnDSegmentDateList.begin();
1864  for (; itSD != lOnDSegmentDateList.end(); ++itCCP, ++itSD) {
1865  const stdair::SegmentDate* lSegmentDate_ptr = *itSD;
1866  assert (lSegmentDate_ptr != NULL);
1867  const stdair::SegmentDate* lOperatingSegmentDate_ptr =
1868  lSegmentDate_ptr->getOperatingSegmentDate ();
1869  // Only operated legs receive the demand information.
1870  if (lOperatingSegmentDate_ptr == NULL) {
1871  const stdair::CabinCode_T lCabinCode = itCCP->first;
1872  const stdair::ClassCode_T lClassCode = itCCP->second;
1873  const stdair::SegmentCabin* lSegmentCabin_ptr =
1874  stdair::BomManager::getObjectPtr<stdair::SegmentCabin> (*lSegmentDate_ptr,
1875  lCabinCode);
1876  assert (lSegmentCabin_ptr != NULL);
1877  const stdair::LegCabinList_T lLegCabinList =
1878  stdair::BomManager::getList<stdair::LegCabin> (*lSegmentCabin_ptr);
1879  assert (!lLegCabinList.empty());
1880  const stdair::Yield_T& lYield = lYieldDemandPair.first;
1881  const stdair::MeanStdDevPair_T& lMeanStdDevPair =
1882  lYieldDemandPair.second;
1883  const stdair::MeanValue_T& lMeanValue = lMeanStdDevPair.first;
1884  const stdair::StdDevValue_T& lStdDevValue = lMeanStdDevPair.second;
1885  for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin();
1886  itLC != lLegCabinList.end(); ++itLC) {
1887  stdair::LegCabin* lLegCabin_ptr = *itLC;
1888  assert (lLegCabin_ptr != NULL);
1889  const stdair::BidPrice_T& lBidPrice = lLegCabin_ptr->getCurrentBidPrice();
1890  const stdair::RealNumber_T lDynamicYieldProrationFactor = lBidPrice / lTotalBidPrice;
1891  const stdair::Yield_T lProratedYield = lDynamicYieldProrationFactor*lYield;
1892  lLegCabin_ptr->addDemandInformation (lProratedYield, lMeanValue, lStdDevValue);
1893 
1894  // STDAIR_LOG_DEBUG ("Addding demand information to leg-cabin " << lLegCabin_ptr->getFullerKey()
1895  // << " Total yield " << lYield << " Proration factor "
1896  // << lDynamicYieldProrationFactor << " Prorated yield " << lProratedYield
1897  // << " Mean demand " << lMeanValue << " StdDev " << lStdDevValue);
1898  }
1899  }
1900  }
1901  }
1902  }
1903  }
1904  }
1905 
1906  // ///////////////////////////////////////////////////////////////////
1907  void RMOL_Service::optimiseOnDUsingRMCooperation (const stdair::DateTime_T& iRMEventTime) {
1908 
1909  if (_rmolServiceContext == NULL) {
1910  throw stdair::NonInitialisedServiceException ("The Rmol service "
1911  "has not been initialised");
1912  }
1913  assert (_rmolServiceContext != NULL);
1914  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
1915 
1916  // Retrieve the bom root
1917  stdair::STDAIR_Service& lSTDAIR_Service =
1918  lRMOL_ServiceContext.getSTDAIR_Service();
1919  stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
1920 
1921  // Retrieve the date from the RM event
1922  const stdair::Date_T lDate = iRMEventTime.date();
1923 
1924  // Browse the list of inventories and optimise within each one independently.
1925  const stdair::InventoryList_T& lInvList =
1926  stdair::BomManager::getList<stdair::Inventory> (lBomRoot);
1927  for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
1928  itInv != lInvList.end(); ++itInv) {
1929  stdair::Inventory* lCurrentInv_ptr = *itInv;
1930  assert (lCurrentInv_ptr != NULL);
1931 
1932  double lMaxBPVariation = 1.0;
1933  short lIterationCounter = 0;
1934  // Iterate until the variation is under the wanted level or the maximal number of iterations is reached.
1935  while (lMaxBPVariation > 0.01 && lIterationCounter < 10) {
1936  lMaxBPVariation = 0.0;
1937  lIterationCounter++;
1938  const stdair::FlightDateList_T& lFlightDateList =
1939  stdair::BomManager::getList<stdair::FlightDate> (*lCurrentInv_ptr);
1940  for (stdair::FlightDateList_T::const_iterator itFlightDate =
1941  lFlightDateList.begin();
1942  itFlightDate != lFlightDateList.end(); ++itFlightDate) {
1943  stdair::FlightDate* lCurrentFlightDate_ptr = *itFlightDate;
1944  assert (lCurrentFlightDate_ptr != NULL);
1945 
1946  const stdair::Date_T& lCurrentDepartureDate = lCurrentFlightDate_ptr->getDepartureDate();
1947  stdair::DateOffset_T lDateOffset = lCurrentDepartureDate - lDate;
1948  stdair::DTD_T lDTD = short (lDateOffset.days());
1949 
1950  stdair::DCPList_T::const_iterator itDCP =
1951  std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD);
1952  // Check if the optimisation is needed.
1953  if (itDCP != stdair::DEFAULT_DCP_LIST.end()) {
1954  const double lBPVariation = Optimiser::optimiseUsingOnDForecast (*lCurrentFlightDate_ptr);
1955  lMaxBPVariation = std::max(lMaxBPVariation, lBPVariation);
1956  }
1957  }
1958  // Update the prorated yields for the current inventory.
1959  resetDemandInformation (iRMEventTime, *lCurrentInv_ptr);
1960  projectOnDDemandOnLegCabinsUsingDYP (iRMEventTime, *lCurrentInv_ptr);
1961  }
1962  }
1963  }
1964 
1965 
1966  // ///////////////////////////////////////////////////////////////////
1967  void RMOL_Service::optimiseOnDUsingAdvancedRMCooperation (const stdair::DateTime_T& iRMEventTime) {
1968 
1969  if (_rmolServiceContext == NULL) {
1970  throw stdair::NonInitialisedServiceException ("The Rmol service "
1971  "has not been initialised");
1972  }
1973  assert (_rmolServiceContext != NULL);
1974  RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
1975 
1976  // Retrieve the bom root
1977  stdair::STDAIR_Service& lSTDAIR_Service =
1978  lRMOL_ServiceContext.getSTDAIR_Service();
1979  stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
1980 
1981  // Retrieve the date from the RM event
1982  const stdair::Date_T lDate = iRMEventTime.date();
1983 
1984  double lMaxBPVariation = 1.0;
1985  short lIterationCounter = 0;
1986  // Iterate until the variation is under the wanted level or the maximal number of iterations is reached.
1987  // Every iteration corresponds to the optimisation of the whole network. Bid prices are communicated
1988  // between partners at the end of each iteration.
1989  while (lMaxBPVariation > 0.01 && lIterationCounter < 50) {
1990  lMaxBPVariation = 0.0;
1991  lIterationCounter++;
1992 
1993  const stdair::InventoryList_T& lInvList =
1994  stdair::BomManager::getList<stdair::Inventory> (lBomRoot);
1995  for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
1996  itInv != lInvList.end(); ++itInv) {
1997  stdair::Inventory* lCurrentInv_ptr = *itInv;
1998  assert (lCurrentInv_ptr != NULL);
1999  const stdair::FlightDateList_T& lFlightDateList =
2000  stdair::BomManager::getList<stdair::FlightDate> (*lCurrentInv_ptr);
2001  for (stdair::FlightDateList_T::const_iterator itFlightDate =
2002  lFlightDateList.begin();
2003  itFlightDate != lFlightDateList.end(); ++itFlightDate) {
2004  stdair::FlightDate* lCurrentFlightDate_ptr = *itFlightDate;
2005  assert (lCurrentFlightDate_ptr != NULL);
2006 
2007  const stdair::Date_T& lCurrentDepartureDate = lCurrentFlightDate_ptr->getDepartureDate();
2008  stdair::DateOffset_T lDateOffset = lCurrentDepartureDate - lDate;
2009  stdair::DTD_T lDTD = short (lDateOffset.days());
2010 
2011  stdair::DCPList_T::const_iterator itDCP =
2012  std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD);
2013  if (itDCP != stdair::DEFAULT_DCP_LIST.end()) {
2014  const double lBPVariation = Optimiser::optimiseUsingOnDForecast (*lCurrentFlightDate_ptr);
2015  lMaxBPVariation = std::max(lMaxBPVariation, lBPVariation);
2016  }
2017  }
2018  }
2019  // At the end of each iteration, communicate bid prices and compute displacement adjusted yields.
2020  updateBidPrice (iRMEventTime);
2021  resetDemandInformation (iRMEventTime);
2022  projectOnDDemandOnLegCabinsUsingDYP (iRMEventTime);
2023  }
2024  }
2025 
2026 }