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