$treeview $search $mathjax
RMOL Logo  1.00.1
$projectbrief
$projectbrief
$searchbox

rmol/bom/Utilities.cpp

Go to the documentation of this file.
00001 
00002 // //////////////////////////////////////////////////////////////////////
00003 // Import section
00004 // //////////////////////////////////////////////////////////////////////
00005 // STL
00006 #include <cassert>
00007 #include <string>
00008 #include <numeric>
00009 #include <algorithm>
00010 #include <cmath>
00011 // StdAir
00012 #include <stdair/basic/BasConst_Inventory.hpp>
00013 #include <stdair/bom/BomManager.hpp>
00014 #include <stdair/bom/SegmentCabin.hpp>
00015 #include <stdair/bom/FareFamily.hpp>
00016 #include <stdair/bom/BookingClass.hpp>
00017 #include <stdair/bom/BookingClassTypes.hpp>
00018 #include <stdair/service/Logger.hpp>
00019 // RMOL
00020 #include <rmol/basic/BasConst_General.hpp>
00021 #include <rmol/bom/Utilities.hpp>
00022 #include <rmol/bom/SegmentSnapshotTableHelper.hpp>
00023 
00024 namespace RMOL {
00025   // ////////////////////////////////////////////////////////////////////
00026   void Utilities::
00027   computeDistributionParameters (const stdair::UncDemVector_T& iVector,
00028                                  stdair::MeanValue_T& ioMean,
00029                                  stdair::StdDevValue_T& ioStdDev) {
00030     ioMean = 0.0; ioStdDev = 0.0;
00031     const stdair::NbOfSamples_T lNbOfSamples = iVector.size();
00032     assert (lNbOfSamples > 1);
00033 
00034     // Compute the mean
00035     for (stdair::UncDemVector_T::const_iterator itSample = iVector.begin();
00036          itSample != iVector.end(); ++itSample) {
00037       //STDAIR_LOG_NOTIFICATION (*itSample);
00038       ioMean += *itSample;
00039     }
00040     ioMean /= lNbOfSamples;
00041 
00042     // Compute the standard deviation
00043     for (stdair::UncDemVector_T::const_iterator itSample = iVector.begin();
00044          itSample != iVector.end(); ++itSample) {
00045       const stdair::MeanValue_T& lSample = *itSample;
00046       ioStdDev += ((lSample - ioMean) * (lSample - ioMean));
00047     }
00048     ioStdDev /= (lNbOfSamples - 1);
00049     ioStdDev = std::sqrt (ioStdDev);
00050 
00051     // Sanity check
00052     if (ioStdDev == 0) {
00053       ioStdDev = 0.1;
00054     }
00055   }
00056 
00057   // ////////////////////////////////////////////////////////////////////
00058   stdair::DCPList_T Utilities::
00059   buildRemainingDCPList (const stdair::DTD_T& iDTD) {
00060     stdair::DCPList_T oDCPList;
00061 
00062     const stdair::DCPList_T lWholeDCPList = stdair::DEFAULT_DCP_LIST;
00063     stdair::DCPList_T::const_iterator itDCP = lWholeDCPList.begin();
00064     while (itDCP != lWholeDCPList.end()) {
00065       const stdair::DCP_T& lDCP = *itDCP;
00066       if (iDTD >= lDCP) {
00067         break;
00068       }
00069       ++itDCP;
00070     }
00071     assert (itDCP != lWholeDCPList.end());
00072 
00073     oDCPList.push_back (iDTD);
00074     ++itDCP;
00075     for (; itDCP != lWholeDCPList.end(); ++itDCP) {
00076       oDCPList.push_back (*itDCP);
00077     }
00078     
00079     return oDCPList;
00080   }
00081 
00082   // ////////////////////////////////////////////////////////////////////
00083   stdair::DCPList_T Utilities::
00084   buildPastDCPList (const stdair::DTD_T& iDTD) {
00085     stdair::DCPList_T oDCPList;
00086 
00087     const stdair::DCPList_T lWholeDCPList = stdair::DEFAULT_DCP_LIST;
00088     stdair::DCPList_T::const_iterator itDCP = lWholeDCPList.begin();
00089     while (itDCP != lWholeDCPList.end()) {
00090       const stdair::DCP_T& lDCP = *itDCP;
00091       if (iDTD <= lDCP) {
00092         oDCPList.push_back (lDCP);
00093         ++itDCP;
00094       } else {
00095         break;
00096       }
00097     }
00098     
00099     return oDCPList;
00100   }
00101   
00102   // ////////////////////////////////////////////////////////////////////
00103   stdair::NbOfSegments_T Utilities::
00104   getNbOfDepartedSimilarSegments (const stdair::SegmentCabin& iSegmentCabin,
00105                                   const stdair::Date_T& iEventDate) {
00106     stdair::DTD_T lDTD = 0;
00107     // Retrieve the guillotine block.
00108     const stdair::SegmentSnapshotTable& lSegmentSnapshotTable =
00109       iSegmentCabin.getSegmentSnapshotTable();
00110     return SegmentSnapshotTableHelper::
00111       getNbOfSegmentAlreadyPassedThisDTD (lSegmentSnapshotTable, lDTD, iEventDate);
00112   }
00113 
00114   // ////////////////////////////////////////////////////////////////////
00115   stdair::BookingClassSellUpCurveMap_T Utilities::
00116   computeSellUpFactorCurves (const stdair::FRAT5Curve_T& iFRAT5Curve,
00117                              const stdair::BookingClassList_T& iBCList) {
00118     stdair::BookingClassSellUpCurveMap_T oBCSellUpFactorMap;
00119 
00120     // Initialise a sell-up factor curve of 1.0 values
00121     stdair::SellUpCurve_T lBasedSellUpCurve;
00122     for (stdair::FRAT5Curve_T::const_iterator itFRAT5 = iFRAT5Curve.begin();
00123          itFRAT5 != iFRAT5Curve.end(); ++itFRAT5) {
00124       const stdair::DTD_T& lDTD = itFRAT5->first;
00125       lBasedSellUpCurve.insert(stdair::SellUpCurve_T::value_type(lDTD, 1.0));
00126     }
00127     
00128     // Retrieve the classes from low to high and compute the distributions of
00129     // product-oriented and price-oriented demand.
00130     // Retrieve the lowest class.
00131     stdair::BookingClassList_T::const_reverse_iterator itCurrentClass =
00132       iBCList.rbegin();
00133     assert (itCurrentClass != iBCList.rend());
00134     
00135     // If there is only one class in the cabin, all the sell-up factors
00136     // will be 1.
00137     stdair::BookingClass* lLowestBC_ptr = *itCurrentClass;
00138     assert (lLowestBC_ptr != NULL);
00139     const stdair::Yield_T& lLowestYield = lLowestBC_ptr->getYield();
00140     bool insert = oBCSellUpFactorMap.
00141       insert (stdair::BookingClassSellUpCurveMap_T::
00142               value_type(lLowestBC_ptr, lBasedSellUpCurve)).second;
00143     assert (insert == true);
00144     ++itCurrentClass;
00145     
00146     // Compute the demand for higher class using the formula
00147     // Pro_sell_up_from_Q_to_F = e ^ ((y_F/y_Q - 1) * ln (0.5) / (FRAT5 - 1))
00148     for (; itCurrentClass != iBCList.rend(); ++itCurrentClass) {
00149       stdair::BookingClass* lCurrentBC_ptr = *itCurrentClass;
00150       assert (lCurrentBC_ptr != NULL);
00151       const stdair::Yield_T& lCurrentYield = lCurrentBC_ptr->getYield();
00152 
00153       // Compute the sell-up factor curve for the current class.
00154       stdair::SellUpCurve_T lCurrentSellUpCurve;
00155       for (stdair::FRAT5Curve_T::const_iterator itFRAT5 = iFRAT5Curve.begin();
00156            itFRAT5 != iFRAT5Curve.end(); ++itFRAT5) {
00157         const stdair::DTD_T& lDTD = itFRAT5->first;
00158         const stdair::FRAT5_T& lFRAT5 = itFRAT5->second;
00159         const double lSellUpCoef = log(0.5)/(lFRAT5-1);
00160         const stdair::SellupProbability_T lSellUpFactor = 
00161           exp ((lCurrentYield/lLowestYield - 1.0) * lSellUpCoef);
00162         const bool isInsertionSuccessful =
00163           lCurrentSellUpCurve.insert (stdair::SellUpCurve_T::value_type(lDTD, lSellUpFactor)).second;
00164         assert (isInsertionSuccessful == true);
00165       }
00166       const bool isInsertionSuccessful = oBCSellUpFactorMap.
00167         insert (stdair::BookingClassSellUpCurveMap_T::
00168                 value_type(lCurrentBC_ptr, lCurrentSellUpCurve)).second;
00169       assert (isInsertionSuccessful == true);
00170     }
00171     return oBCSellUpFactorMap;
00172   }
00173 
00174   
00175   // ////////////////////////////////////////////////////////////////////
00176   stdair::BookingClassDispatchingCurveMap_T Utilities::
00177   computeDispatchingFactorCurves (const stdair::FRAT5Curve_T& iFRAT5Curve,
00178                                   const stdair::BookingClassList_T& iBCList) {
00179     stdair::BookingClassDispatchingCurveMap_T oBCDispatchingFactorMap;
00180 
00181     // Initialise a sell-up factor curve of 1.0 values
00182     stdair::DispatchingCurve_T lBasedDispatchingCurve;
00183     for (stdair::FRAT5Curve_T::const_iterator itFRAT5 = iFRAT5Curve.begin();
00184          itFRAT5 != iFRAT5Curve.end(); ++itFRAT5) {
00185       const stdair::DTD_T& lDTD = itFRAT5->first;
00186       lBasedDispatchingCurve.insert(stdair::DispatchingCurve_T::value_type(lDTD, 1.0));
00187     }
00188     
00189     // Retrieve the classes from low to high and compute the distributions of
00190     // product-oriented and price-oriented demand.
00191     // Retrieve the lowest class.
00192     stdair::BookingClassList_T::const_reverse_iterator itCurrentClass =
00193       iBCList.rbegin();
00194     assert (itCurrentClass != iBCList.rend());
00195     stdair::BookingClassList_T::const_reverse_iterator itNextClass =
00196       itCurrentClass; ++itNextClass;
00197     
00198     // If there is only one class in the cabin, all the sell-up factors
00199     // will be 1.
00200     stdair::BookingClass* lLowestBC_ptr = *itCurrentClass;
00201     assert (lLowestBC_ptr != NULL);
00202     const stdair::Yield_T& lLowestYield = lLowestBC_ptr->getYield();
00203     if (itNextClass == iBCList.rend()) {
00204       bool insert = oBCDispatchingFactorMap.
00205         insert (stdair::BookingClassDispatchingCurveMap_T::
00206                value_type(lLowestBC_ptr, lBasedDispatchingCurve)).second;
00207       assert (insert == true);
00208     } else {
00209       // Compute the demand for higher class using the formula
00210       // Pro_sell_up_from_Q_to_F = e ^ ((y_F/y_Q - 1) * ln (0.5) / (FRAT5 - 1))
00211       for (; itNextClass != iBCList.rend(); ++itCurrentClass, ++itNextClass) {
00212         stdair::BookingClass* lCurrentBC_ptr = *itCurrentClass;
00213         stdair::BookingClass* lNextBC_ptr = *itNextClass;
00214         assert (lNextBC_ptr != NULL);
00215         const stdair::Yield_T& lNextYield = lNextBC_ptr->getYield();
00216 
00217         // Compute the sell-up factor curve for the current class.
00218         stdair::DispatchingCurve_T lCurrentDispatchingCurve;
00219         for (stdair::FRAT5Curve_T::const_iterator itFRAT5 = iFRAT5Curve.begin();
00220          itFRAT5 != iFRAT5Curve.end(); ++itFRAT5) {
00221           const stdair::DTD_T& lDTD = itFRAT5->first;
00222           const stdair::FRAT5_T& lFRAT5 = itFRAT5->second;
00223           const double lDispatchingCoef = log(0.5)/(lFRAT5-1);
00224           double lDispatchingFactor = 
00225             exp ((lNextYield/lLowestYield - 1.0) * lDispatchingCoef);
00226           stdair::DispatchingCurve_T::iterator itBasedDispatching =
00227             lBasedDispatchingCurve.find (lDTD);
00228           assert (itBasedDispatching != lBasedDispatchingCurve.end());
00229           double& lBasedFactor = itBasedDispatching->second;
00230           bool insert = lCurrentDispatchingCurve.insert (stdair::DispatchingCurve_T::value_type(lDTD, lBasedFactor - lDispatchingFactor)).second;
00231           assert (insert == true);
00232           lBasedFactor = lDispatchingFactor;
00233         }
00234         bool insert = oBCDispatchingFactorMap.
00235           insert (stdair::BookingClassDispatchingCurveMap_T::
00236                  value_type(lCurrentBC_ptr, lCurrentDispatchingCurve)).second;
00237         assert (insert == true);
00238       }
00239 
00240       // Compute the sell-up factor curve for the highest class (which is the
00241       // "current class")
00242       stdair::BookingClass* lCurrentBC_ptr = *itCurrentClass;
00243       bool insert = oBCDispatchingFactorMap.
00244         insert (stdair::BookingClassDispatchingCurveMap_T::
00245                value_type(lCurrentBC_ptr, lBasedDispatchingCurve)).second;
00246       assert (insert == true);
00247     }
00248     return oBCDispatchingFactorMap;
00249   }
00250 
00251   // ////////////////////////////////////////////////////////////////////
00252   void Utilities::dispatchDemandForecast
00253   (const stdair::BookingClassDispatchingCurveMap_T& iBCDispatchingCurveMap,
00254    const stdair::MeanValue_T& iMean, 
00255    const stdair::StdDevValue_T& iStdDev,
00256    const stdair::DTD_T& iCurrentDCP) {
00257     for (stdair::BookingClassDispatchingCurveMap_T::const_iterator itBCDC =
00258            iBCDispatchingCurveMap.begin();
00259          itBCDC != iBCDispatchingCurveMap.end(); ++itBCDC) {
00260       stdair::BookingClass* lBC_ptr = itBCDC->first;
00261       assert (lBC_ptr != NULL);
00262       const stdair::DispatchingCurve_T& lDispatchingCurve = itBCDC->second;
00263       stdair::DispatchingCurve_T::const_iterator itDispatchingFactor =
00264         lDispatchingCurve.find (iCurrentDCP);
00265       assert (itDispatchingFactor != lDispatchingCurve.end());
00266       const double& lDF = itDispatchingFactor->second;
00267 
00268       const stdair::MeanValue_T& lCurrentMean = lBC_ptr->getPriceDemMean();
00269       const stdair::StdDevValue_T& lCurrentStdDev = lBC_ptr->getPriceDemStdDev();
00270 
00271       const stdair::MeanValue_T lAdditionalMean = iMean * lDF;
00272       const stdair::StdDevValue_T lAdditionalStdDev = iStdDev * std::sqrt (lDF);
00273 
00274       const stdair::MeanValue_T lNewMean = lCurrentMean + lAdditionalMean;
00275       const stdair::StdDevValue_T lNewStdDev = 
00276         std::sqrt (lCurrentStdDev * lCurrentStdDev
00277                    + lAdditionalStdDev * lAdditionalStdDev);
00278 
00279       lBC_ptr->setPriceDemMean (lNewMean);
00280       lBC_ptr->setPriceDemStdDev (lNewStdDev);
00281     }
00282   }
00283 
00284   // ////////////////////////////////////////////////////////////////////
00285   void Utilities::dispatchDemandForecastForFA
00286   (const stdair::BookingClassSellUpCurveMap_T& iBCSellUpCurveMap,
00287    const stdair::MeanValue_T& iMean,
00288    const stdair::StdDevValue_T& iStdDev,
00289    const stdair::DTD_T& iCurrentDCP) {
00290     for (stdair::BookingClassSellUpCurveMap_T::const_iterator itBCSU =
00291            iBCSellUpCurveMap.begin();
00292          itBCSU != iBCSellUpCurveMap.end(); ++itBCSU) {
00293       stdair::BookingClass* lBC_ptr = itBCSU->first;
00294       assert (lBC_ptr != NULL);
00295       const stdair::SellUpCurve_T& lSellUpCurve = itBCSU->second;
00296       stdair::SellUpCurve_T::const_iterator itSellUpFactor =
00297         lSellUpCurve.find (iCurrentDCP);
00298       assert (itSellUpFactor != lSellUpCurve.end());
00299       const stdair::SellupProbability_T& lSU = itSellUpFactor->second;
00300 
00301       const stdair::MeanValue_T& lCurrentMean = lBC_ptr->getCumuPriceDemMean();
00302       const stdair::StdDevValue_T& lCurrentStdDev = 
00303         lBC_ptr->getCumuPriceDemStdDev();
00304 
00305       const stdair::MeanValue_T lAdditionalMean = iMean * lSU;
00306       const stdair::StdDevValue_T lAdditionalStdDev = iStdDev * std::sqrt (lSU);
00307 
00308       const stdair::MeanValue_T lNewMean = lCurrentMean + lAdditionalMean;
00309       const stdair::StdDevValue_T lNewStdDev = 
00310         std::sqrt (lCurrentStdDev * lCurrentStdDev
00311                    + lAdditionalStdDev * lAdditionalStdDev);
00312 
00313       lBC_ptr->setCumuPriceDemMean (lNewMean);
00314       lBC_ptr->setCumuPriceDemStdDev (lNewStdDev);
00315     }
00316   }
00317 }