RMOL Logo  1.00.13
C++ library of Revenue Management and Optimisation classes and functions
Loading...
Searching...
No Matches
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
47namespace RMOL {
48
49 // ////////////////////////////////////////////////////////////////////
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 // ////////////////////////////////////////////////////////////////////
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
241
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
300
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 // ////////////////////////////////////////////////////////////////////
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);
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);
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 // ///////////////////////////////////////////////////////////////////
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 // ///////////////////////////////////////////////////////////////////
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 // ///////////////////////////////////////////////////////////////////
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 // ///////////////////////////////////////////////////////////////////
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 // ///////////////////////////////////////////////////////////////////
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 // ///////////////////////////////////////////////////////////////////
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.,
1812 lYieldDemandPair.first - lComplementaryBidPrice);
1813
1814
1815 stdair::Yield_T lYield = lDAYield;
1816 // In order to be protected against important variations of partners' bid price,
1817 // the displacement adjusted yield is not allowed to get out of a certain range.
1818 // This range is chosen here to be from 80% to 100% of the (static rule) prorated yield.
1819 /*
1820 const int lNbOfLegs = lLegCabinList.size();
1821 const stdair::Yield_T& lStaticProrationYield =
1822 lDemandStruct.getYield()/(lNbOfLegs*lNbOfSegments);
1823 if (lDAYield < 0.8*lStaticProrationYield){
1824 lYield = 0.8*lStaticProrationYield;
1825 }
1826 if (lDAYield > lStaticProrationYield) {
1827 lYield = lStaticProrationYield;
1828 }
1829 */
1830 const stdair::MeanStdDevPair_T& lMeanStdDevPair =
1831 lYieldDemandPair.second;
1832 const stdair::MeanValue_T& lMeanValue = lMeanStdDevPair.first;
1833 const stdair::StdDevValue_T& lStdDevValue = lMeanStdDevPair.second;
1834 for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin();
1835 itLC != lLegCabinList.end(); ++itLC) {
1836 stdair::LegCabin* lLegCabin_ptr = *itLC;
1837 assert (lLegCabin_ptr != NULL);
1838 lLegCabin_ptr->addDemandInformation (lYield, lMeanValue, lStdDevValue);
1839 }
1840 }
1841 }
1842 }
1843 }
1844 }
1845 }
1846 }
1847
1848 // ///////////////////////////////////////////////////////////////////
1849 void RMOL_Service::projectOnDDemandOnLegCabinsUsingDYP(const stdair::DateTime_T& iRMEventTime) {
1850
1851 if (_rmolServiceContext == NULL) {
1852 throw stdair::NonInitialisedServiceException ("The Rmol service "
1853 "has not been initialised");
1854 }
1855 assert (_rmolServiceContext != NULL);
1856 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
1857
1858 // Retrieve the bom root
1859 stdair::STDAIR_Service& lSTDAIR_Service =
1860 lRMOL_ServiceContext.getSTDAIR_Service();
1861 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
1862
1863 const stdair::InventoryList_T lInventoryList =
1864 stdair::BomManager::getList<stdair::Inventory> (lBomRoot);
1865 assert (!lInventoryList.empty());
1866 for (stdair::InventoryList_T::const_iterator itInv = lInventoryList.begin();
1867 itInv != lInventoryList.end(); ++itInv) {
1868 const stdair::Inventory* lInventory_ptr = *itInv;
1869 assert (lInventory_ptr != NULL);
1870 projectOnDDemandOnLegCabinsUsingDYP (iRMEventTime, *lInventory_ptr);
1871 }
1872 }
1873
1874 // ///////////////////////////////////////////////////////////////////
1875 void RMOL_Service::projectOnDDemandOnLegCabinsUsingDYP(const stdair::DateTime_T& iRMEventTime,
1876 const stdair::Inventory& iInventory) {
1877
1878 const stdair::OnDDateList_T lOnDDateList =
1879 stdair::BomManager::getList<stdair::OnDDate> (iInventory);
1880 assert (!lOnDDateList.empty());
1881 for (stdair::OnDDateList_T::const_iterator itOD = lOnDDateList.begin();
1882 itOD != lOnDDateList.end(); ++itOD) {
1883 stdair::OnDDate* lOnDDate_ptr = *itOD;
1884 assert (lOnDDate_ptr != NULL);
1885
1886 // Retrieve the date from the RM event
1887 const stdair::Date_T lDate = iRMEventTime.date();
1888
1889 const stdair::Date_T& lDepartureDate = lOnDDate_ptr->getDate();
1890 stdair::DateOffset_T lDateOffset = lDepartureDate - lDate;
1891 stdair::DTD_T lDTD = short (lDateOffset.days());
1892
1893 stdair::DCPList_T::const_iterator itDCP =
1894 std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD);
1895 // Check if the forecast for this O&D date needs to be projected.
1896 if (itDCP != stdair::DEFAULT_DCP_LIST.end()) {
1897
1898 // Browse the demand info map.
1899 const stdair::StringDemandStructMap_T& lStringDemandStructMap =
1900 lOnDDate_ptr->getDemandInfoMap ();
1901 for (stdair::StringDemandStructMap_T::const_iterator itStrDS = lStringDemandStructMap.begin();
1902 itStrDS != lStringDemandStructMap.end(); ++itStrDS) {
1903 std::string lCabinClassPath = itStrDS->first;
1904 const stdair::YieldDemandPair_T& lYieldDemandPair = itStrDS->second;
1905 const stdair::CabinClassPairList_T& lCabinClassPairList =
1906 lOnDDate_ptr->getCabinClassPairList(lCabinClassPath);
1907 const stdair::NbOfSegments_T& lNbOfSegments = lOnDDate_ptr->getNbOfSegments();
1908 // Sanity check
1909 assert (lCabinClassPairList.size() == lNbOfSegments);
1910
1911 //
1912 const stdair::SegmentDateList_T lOnDSegmentDateList =
1913 stdair::BomManager::getList<stdair::SegmentDate> (*lOnDDate_ptr);
1914 // Sanity check
1915 assert (lOnDSegmentDateList.size() == lNbOfSegments);
1916 stdair::CabinClassPairList_T::const_iterator itCCP = lCabinClassPairList.begin();
1917 stdair::SegmentDateList_T::const_iterator itSD = lOnDSegmentDateList.begin();
1918 // The sum of bid prices of all cabins.
1919 stdair::BidPrice_T lTotalBidPrice = 0;
1920 for (; itSD != lOnDSegmentDateList.end(); ++itCCP, ++itSD) {
1921 // Get the operating segment cabin (it holds the bid price information).
1922 const stdair::SegmentDate* lSegmentDate_ptr = *itSD;
1923 assert (lSegmentDate_ptr != NULL);
1924 // Get the operating airline code and check if it is the airline we are looking for.
1925 const stdair::SegmentDate* lOperatingSegmentDate_ptr =
1926 lSegmentDate_ptr->getOperatingSegmentDate ();
1927 if (lOperatingSegmentDate_ptr != NULL) {
1928 lSegmentDate_ptr = lOperatingSegmentDate_ptr;
1929 }
1930 const stdair::CabinCode_T lCabinCode = itCCP->first;
1931 const stdair::SegmentCabin* lSegmentCabin_ptr =
1932 stdair::BomManager::getObjectPtr<stdair::SegmentCabin> (*lSegmentDate_ptr,
1933 lCabinCode);
1934 assert (lSegmentCabin_ptr != NULL);
1935 const stdair::LegCabinList_T lLegCabinList =
1936 stdair::BomManager::getList<stdair::LegCabin>(*lSegmentCabin_ptr);
1937 for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin();
1938 itLC != lLegCabinList.end(); ++itLC) {
1939 const stdair::LegCabin* lLegCabin_ptr = *itLC;
1940 assert (lLegCabin_ptr != NULL);
1941 lTotalBidPrice += lLegCabin_ptr->getCurrentBidPrice();
1942 }
1943 }
1944
1945
1946 itCCP = lCabinClassPairList.begin();
1947 itSD = lOnDSegmentDateList.begin();
1948 for (; itSD != lOnDSegmentDateList.end(); ++itCCP, ++itSD) {
1949 const stdair::SegmentDate* lSegmentDate_ptr = *itSD;
1950 assert (lSegmentDate_ptr != NULL);
1951 const stdair::SegmentDate* lOperatingSegmentDate_ptr =
1952 lSegmentDate_ptr->getOperatingSegmentDate ();
1953 // Only operated legs receive the demand information.
1954 if (lOperatingSegmentDate_ptr == NULL) {
1955 const stdair::CabinCode_T lCabinCode = itCCP->first;
1956 const stdair::ClassCode_T lClassCode = itCCP->second;
1957 const stdair::SegmentCabin* lSegmentCabin_ptr =
1958 stdair::BomManager::getObjectPtr<stdair::SegmentCabin> (*lSegmentDate_ptr,
1959 lCabinCode);
1960 assert (lSegmentCabin_ptr != NULL);
1961 const stdair::LegCabinList_T lLegCabinList =
1962 stdair::BomManager::getList<stdair::LegCabin> (*lSegmentCabin_ptr);
1963 assert (!lLegCabinList.empty());
1964 const stdair::Yield_T& lYield = lYieldDemandPair.first;
1965 const stdair::MeanStdDevPair_T& lMeanStdDevPair =
1966 lYieldDemandPair.second;
1967 const stdair::MeanValue_T& lMeanValue = lMeanStdDevPair.first;
1968 const stdair::StdDevValue_T& lStdDevValue = lMeanStdDevPair.second;
1969 for (stdair::LegCabinList_T::const_iterator itLC = lLegCabinList.begin();
1970 itLC != lLegCabinList.end(); ++itLC) {
1971 stdair::LegCabin* lLegCabin_ptr = *itLC;
1972 assert (lLegCabin_ptr != NULL);
1973 const stdair::BidPrice_T& lBidPrice = lLegCabin_ptr->getCurrentBidPrice();
1974 const stdair::RealNumber_T lDynamicYieldProrationFactor = lBidPrice / lTotalBidPrice;
1975 const stdair::Yield_T lProratedYield = lDynamicYieldProrationFactor*lYield;
1976 lLegCabin_ptr->addDemandInformation (lProratedYield, lMeanValue, lStdDevValue);
1977
1978 // STDAIR_LOG_DEBUG ("Addding demand information to leg-cabin " << lLegCabin_ptr->getFullerKey()
1979 // << " Total yield " << lYield << " Proration factor "
1980 // << lDynamicYieldProrationFactor << " Prorated yield " << lProratedYield
1981 // << " Mean demand " << lMeanValue << " StdDev " << lStdDevValue);
1982 }
1983 }
1984 }
1985 }
1986 }
1987 }
1988 }
1989
1990 // ///////////////////////////////////////////////////////////////////
1991 void RMOL_Service::optimiseOnDUsingRMCooperation (const stdair::DateTime_T& iRMEventTime) {
1992
1993 if (_rmolServiceContext == NULL) {
1994 throw stdair::NonInitialisedServiceException ("The Rmol service "
1995 "has not been initialised");
1996 }
1997 assert (_rmolServiceContext != NULL);
1998 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
1999
2000 // Retrieve the bom root
2001 stdair::STDAIR_Service& lSTDAIR_Service =
2002 lRMOL_ServiceContext.getSTDAIR_Service();
2003 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
2004
2005 // Retrieve the date from the RM event
2006 const stdair::Date_T lDate = iRMEventTime.date();
2007
2008 // Browse the list of inventories and optimise within each one independently.
2009 const stdair::InventoryList_T& lInvList =
2010 stdair::BomManager::getList<stdair::Inventory> (lBomRoot);
2011 for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
2012 itInv != lInvList.end(); ++itInv) {
2013 stdair::Inventory* lCurrentInv_ptr = *itInv;
2014 assert (lCurrentInv_ptr != NULL);
2015
2016 double lMaxBPVariation = 1.0;
2017 short lIterationCounter = 0;
2018 // Iterate until the variation is under the wanted level or the maximal number of iterations is reached.
2019 while (lMaxBPVariation > 0.01 && lIterationCounter < 10) {
2020 lMaxBPVariation = 0.0;
2021 lIterationCounter++;
2022 const stdair::FlightDateList_T& lFlightDateList =
2023 stdair::BomManager::getList<stdair::FlightDate> (*lCurrentInv_ptr);
2024 for (stdair::FlightDateList_T::const_iterator itFlightDate =
2025 lFlightDateList.begin();
2026 itFlightDate != lFlightDateList.end(); ++itFlightDate) {
2027 stdair::FlightDate* lCurrentFlightDate_ptr = *itFlightDate;
2028 assert (lCurrentFlightDate_ptr != NULL);
2029
2030 const stdair::Date_T& lCurrentDepartureDate = lCurrentFlightDate_ptr->getDepartureDate();
2031 stdair::DateOffset_T lDateOffset = lCurrentDepartureDate - lDate;
2032 stdair::DTD_T lDTD = short (lDateOffset.days());
2033
2034 stdair::DCPList_T::const_iterator itDCP =
2035 std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD);
2036 // Check if the optimisation is needed.
2037 if (itDCP != stdair::DEFAULT_DCP_LIST.end()) {
2038 const double lBPVariation = Optimiser::optimiseUsingOnDForecast (*lCurrentFlightDate_ptr);
2039 lMaxBPVariation = std::max(lMaxBPVariation, lBPVariation);
2040 }
2041 }
2042 // Update the prorated yields for the current inventory.
2043 resetDemandInformation (iRMEventTime, *lCurrentInv_ptr);
2044 projectOnDDemandOnLegCabinsUsingDYP (iRMEventTime, *lCurrentInv_ptr);
2045 }
2046 }
2047 }
2048
2049
2050 // ///////////////////////////////////////////////////////////////////
2051 void RMOL_Service::optimiseOnDUsingAdvancedRMCooperation (const stdair::DateTime_T& iRMEventTime) {
2052
2053 if (_rmolServiceContext == NULL) {
2054 throw stdair::NonInitialisedServiceException ("The Rmol service "
2055 "has not been initialised");
2056 }
2057 assert (_rmolServiceContext != NULL);
2058 RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
2059
2060 // Retrieve the bom root
2061 stdair::STDAIR_Service& lSTDAIR_Service =
2062 lRMOL_ServiceContext.getSTDAIR_Service();
2063 stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot();
2064
2065 // Retrieve the date from the RM event
2066 const stdair::Date_T lDate = iRMEventTime.date();
2067
2068 double lMaxBPVariation = 1.0;
2069 short lIterationCounter = 0;
2070 // Iterate until the variation is under the wanted level or the maximal number of iterations is reached.
2071 // Every iteration corresponds to the optimisation of the whole network. Bid prices are communicated
2072 // between partners at the end of each iteration.
2073 while (lMaxBPVariation > 0.01 && lIterationCounter < 50) {
2074 lMaxBPVariation = 0.0;
2075 lIterationCounter++;
2076
2077 const stdair::InventoryList_T& lInvList =
2078 stdair::BomManager::getList<stdair::Inventory> (lBomRoot);
2079 for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
2080 itInv != lInvList.end(); ++itInv) {
2081 stdair::Inventory* lCurrentInv_ptr = *itInv;
2082 assert (lCurrentInv_ptr != NULL);
2083 const stdair::FlightDateList_T& lFlightDateList =
2084 stdair::BomManager::getList<stdair::FlightDate> (*lCurrentInv_ptr);
2085 for (stdair::FlightDateList_T::const_iterator itFlightDate =
2086 lFlightDateList.begin();
2087 itFlightDate != lFlightDateList.end(); ++itFlightDate) {
2088 stdair::FlightDate* lCurrentFlightDate_ptr = *itFlightDate;
2089 assert (lCurrentFlightDate_ptr != NULL);
2090
2091 const stdair::Date_T& lCurrentDepartureDate = lCurrentFlightDate_ptr->getDepartureDate();
2092 stdair::DateOffset_T lDateOffset = lCurrentDepartureDate - lDate;
2093 stdair::DTD_T lDTD = short (lDateOffset.days());
2094
2095 stdair::DCPList_T::const_iterator itDCP =
2096 std::find (stdair::DEFAULT_DCP_LIST.begin(), stdair::DEFAULT_DCP_LIST.end(), lDTD);
2097 if (itDCP != stdair::DEFAULT_DCP_LIST.end()) {
2098 const double lBPVariation = Optimiser::optimiseUsingOnDForecast (*lCurrentFlightDate_ptr);
2099 lMaxBPVariation = std::max(lMaxBPVariation, lBPVariation);
2100 }
2101 }
2102 }
2103 // At the end of each iteration, communicate bid prices and compute displacement adjusted yields.
2104 updateBidPrice (iRMEventTime);
2105 resetDemandInformation (iRMEventTime);
2107 }
2108 }
2109
2110}
Forward declarations.
static bool forecast(stdair::FlightDate &, const stdair::DateTime_T &, const stdair::UnconstrainingMethod &, const stdair::ForecastingMethod &)
static bool parseInputFileAndBuildBom(const std::string &iInputFileName, stdair::BomRoot &)
static bool optimise(stdair::FlightDate &, const stdair::OptimisationMethod &)
Definition Optimiser.cpp:84
static double optimiseUsingOnDForecast(stdair::FlightDate &, const bool &iReduceFluctuations=false)
static void heuristicOptimisationByEmsr(stdair::LegCabin &)
Definition Optimiser.cpp:69
static void optimalOptimisationByMCIntegration(const stdair::NbOfSamples_T &, stdair::LegCabin &)
Definition Optimiser.cpp:30
static void heuristicOptimisationByEmsrB(stdair::LegCabin &)
Definition Optimiser.cpp:79
static void heuristicOptimisationByEmsrA(stdair::LegCabin &)
Definition Optimiser.cpp:74
static bool preOptimise(stdair::FlightDate &, const stdair::PreOptimisationMethod &)
static FacRmolServiceContext & instance()
void optimiseOnDUsingAdvancedRMCooperation(const stdair::DateTime_T &)
stdair::YieldFeatures * getYieldFeatures(const stdair::OnDDate &, const stdair::CabinCode_T &, stdair::BomRoot &)
bool optimise(stdair::FlightDate &, const stdair::DateTime_T &, const stdair::UnconstrainingMethod &, const stdair::ForecastingMethod &, const stdair::PreOptimisationMethod &, const stdair::OptimisationMethod &, const stdair::PartnershipTechnique &)
const stdair::SegmentCabin & retrieveDummySegmentCabin(const bool isForFareFamilies=false)
void updateBidPrice(const stdair::DateTime_T &)
void parseAndLoad(const stdair::CabinCapacity_T &iCabinCapacity, const stdair::Filename_T &iDemandAndClassDataFile)
void optimiseOnD(const stdair::DateTime_T &)
void projectOnDDemandOnLegCabinsUsingDA(const stdair::DateTime_T &)
void resetDemandInformation(const stdair::DateTime_T &)
void buildComplementaryLinks(stdair::BomRoot &)
void projectAggregatedDemandOnLegCabins(const stdair::DateTime_T &)
RMOL_Service(const stdair::BasLogParams &, const stdair::BasDBParams &)
void projectOnDDemandOnLegCabinsUsingYP(const stdair::DateTime_T &)
void optimiseOnDUsingRMCooperation(const stdair::DateTime_T &)
void projectOnDDemandOnLegCabinsUsingDYP(const stdair::DateTime_T &)
void setOnDForecast(const stdair::AirlineClassList &, const stdair::MeanValue_T &, const stdair::StdDevValue_T &, stdair::OnDDate &, const stdair::CabinCode_T &, stdair::BomRoot &)
void forecastOnD(const stdair::DateTime_T &iRMEventTime)
Inner class holding the context for the RMOL Service object.