RMOL Logo  1.00.14
C++ library of Revenue Management and Optimisation classes and functions
Loading...
Searching...
No Matches
Optimiser.cpp
Go to the documentation of this file.
1// //////////////////////////////////////////////////////////////////////
2// Import section
3// //////////////////////////////////////////////////////////////////////
4// STL
5#include <cassert>
6#include <sstream>
7// StdAir
8#include <stdair/basic/BasConst_General.hpp>
9#include <stdair/basic/RandomGeneration.hpp>
10#include <stdair/bom/BomManager.hpp>
11#include <stdair/bom/FlightDate.hpp>
12#include <stdair/bom/LegDate.hpp>
13#include <stdair/bom/SegmentDate.hpp>
14#include <stdair/bom/LegCabin.hpp>
15#include <stdair/bom/SegmentCabin.hpp>
16#include <stdair/bom/FareFamily.hpp>
17#include <stdair/bom/BookingClass.hpp>
18#include <stdair/service/Logger.hpp>
19// RMOL
22#include <rmol/bom/Emsr.hpp>
25
26namespace RMOL {
27
28 // ////////////////////////////////////////////////////////////////////
30 optimalOptimisationByMCIntegration (const stdair::NbOfSamples_T& K,
31 stdair::LegCabin& ioLegCabin) {
32 // Retrieve the segment-cabin
33 const stdair::SegmentCabinList_T lSegmentCabinList =
34 stdair::BomManager::getList<stdair::SegmentCabin> (ioLegCabin);
35 stdair::SegmentCabinList_T::const_iterator itSC = lSegmentCabinList.begin();
36 assert (itSC != lSegmentCabinList.end());
37 const stdair::SegmentCabin* lSegmentCabin_ptr = *itSC;
38 assert (lSegmentCabin_ptr != NULL);
39
40 // Retrieve the class list.
41 const stdair::BookingClassList_T lBookingClassList =
42 stdair::BomManager::getList<stdair::BookingClass> (*lSegmentCabin_ptr);
43 stdair::RandomGeneration lSeedGenerator (stdair::DEFAULT_RANDOM_SEED);
44
45 // Generate the demand samples for the booking classes.
46 for (stdair::BookingClassList_T::const_iterator itBC =
47 lBookingClassList.begin(); itBC != lBookingClassList.end(); ++itBC) {
48 stdair::RandomSeed_T lRandomSeed =
49 lSeedGenerator.generateUniform01 () * 1e9;
50 stdair::BookingClass* lBookingClass_ptr = *itBC;
51 assert (lBookingClass_ptr != NULL);
52 lBookingClass_ptr->generateDemandSamples (K, lRandomSeed);
53
54 // DEBUG
55 //STDAIR_LOG_DEBUG ("Generating " << K << " demand samples for the class "
56 // << lBookingClass_ptr->describeKey());
57 }
58
59 // Call the class performing the actual algorithm
61 }
62
63 // ////////////////////////////////////////////////////////////////////
64 void Optimiser::optimalOptimisationByDP (stdair::LegCabin& ioLegCabin) {
66 }
67
68 // ////////////////////////////////////////////////////////////////////
69 void Optimiser::heuristicOptimisationByEmsr (stdair::LegCabin& ioLegCabin) {
71 }
72
73 // ////////////////////////////////////////////////////////////////////
74 void Optimiser::heuristicOptimisationByEmsrA (stdair::LegCabin& ioLegCabin) {
76 }
77
78 // ////////////////////////////////////////////////////////////////////
79 void Optimiser::heuristicOptimisationByEmsrB (stdair::LegCabin& ioLegCabin) {
81 }
82
83 // ////////////////////////////////////////////////////////////////////
84 bool Optimiser::optimise (stdair::FlightDate& ioFlightDate,
85 const stdair::OptimisationMethod& iOptimisationMethod) {
86 bool optimiseSucceeded = false;
87 // Browse the leg-cabin list and build the virtual class list for
88 // each cabin.
89 const stdair::LegDateList_T& lLDList =
90 stdair::BomManager::getList<stdair::LegDate> (ioFlightDate);
91 for (stdair::LegDateList_T::const_iterator itLD = lLDList.begin();
92 itLD != lLDList.end(); ++itLD) {
93 stdair::LegDate* lLD_ptr = *itLD;
94 assert (lLD_ptr != NULL);
95 const bool isSucceeded = optimise(*lLD_ptr, iOptimisationMethod);
96 // If at least one leg date is optimised, the optimisation is succeeded.
97 if (isSucceeded == true) {
98 optimiseSucceeded = true;
99 // Do not return now because all leg dates need to be optimised.
100 }
101 }
102 return optimiseSucceeded;
103 }
104
105 // ////////////////////////////////////////////////////////////////////
106 bool Optimiser::
107 optimise (stdair::LegDate& ioLegDate,
108 const stdair::OptimisationMethod& iOptimisationMethod) {
109 bool optimiseSucceeded = false;
110 // Browse the leg-cabin list
111 const stdair::LegCabinList_T& lLCList =
112 stdair::BomManager::getList<stdair::LegCabin> (ioLegDate);
113 for (stdair::LegCabinList_T::const_iterator itLC = lLCList.begin();
114 itLC != lLCList.end(); ++itLC) {
115 stdair::LegCabin* lLC_ptr = *itLC;
116 assert (lLC_ptr != NULL);
117 const bool isSucceeded = optimise(*lLC_ptr, iOptimisationMethod);
118 // If at least one leg cabin is optimised, the optimisation is succeeded.
119 if (isSucceeded == true) {
120 optimiseSucceeded = true;
121 // Do not return now because all leg cabins need to be optimised.
122 }
123 }
124 return optimiseSucceeded;
125 }
126
127 // ////////////////////////////////////////////////////////////////////
128 bool Optimiser::
129 optimise (stdair::LegCabin& ioLegCabin,
130 const stdair::OptimisationMethod& iOptimisationMethod) {
131 bool optimiseSucceeded = false;
132 //
133 // Build the virtual class list.
134 bool hasVirtualClass =
136 if (hasVirtualClass == true) {
137 switch (iOptimisationMethod.getMethod()) {
138 case stdair::OptimisationMethod::LEG_BASED_MC: {
139 // Number of samples generated for the Monte Carlo integration.
140 // It is important that number is greater than 100 (=10000 here).
141 const stdair::NbOfSamples_T lNbOfSamples =
143 optimalOptimisationByMCIntegration (lNbOfSamples, ioLegCabin);
144 optimiseSucceeded = true;
145 break;
146 }
147 case stdair::OptimisationMethod::LEG_BASED_EMSR_B: {
148 heuristicOptimisationByEmsrB (ioLegCabin);
149 optimiseSucceeded = true;
150 break;
151 }
152 default: {
153 assert (false);
154 break;
155 }
156 }
157 }
158
159 return optimiseSucceeded;
160 }
161
162 // ////////////////////////////////////////////////////////////////////
164 buildVirtualClassListForLegBasedOptimisation (stdair::LegCabin& ioLegCabin) {
165 // The map holding all virtual classes to be created.
166 stdair::VirtualClassMap_T lVirtualClassMap;
167 bool isNotEmpty = false;
168
169 // Retrieve the segment-cabin
170 const stdair::SegmentCabinList_T& lSegmentCabinList =
171 stdair::BomManager::getList<stdair::SegmentCabin> (ioLegCabin);
172 stdair::SegmentCabinList_T::const_iterator itSC = lSegmentCabinList.begin();
173 assert (itSC != lSegmentCabinList.end());
174 const stdair::SegmentCabin* lSegmentCabin_ptr = *itSC;
175 assert (lSegmentCabin_ptr != NULL);
176
177 // Retrieve the class list.
178 const stdair::BookingClassList_T lBookingClassList =
179 stdair::BomManager::getList<stdair::BookingClass> (*lSegmentCabin_ptr);
180
181 // Generate the demand samples for the booking classes.
182 for (stdair::BookingClassList_T::const_iterator itBC =
183 lBookingClassList.begin(); itBC != lBookingClassList.end(); ++itBC) {
184 stdair::BookingClass* lBookingClass_ptr = *itBC;
185 assert (lBookingClass_ptr != NULL);
186
187 // If the demand forecast of the class is zero, there no need to create
188 // a virtual class.
189 // TODO: use float utils
190 const stdair::NbOfRequests_T& lMean = lBookingClass_ptr->getMean();
191 const stdair::StdDevValue_T& lStdDev = lBookingClass_ptr->getStdDev();
192 if (lMean > 0.0) {
193 const stdair::Yield_T& lYield = lBookingClass_ptr->getAdjustedYield();
194 // TODO: use float utils
195 assert (lYield >= 0.0);
196 const stdair::Yield_T lRoundedYieldDouble = std::floor(lYield +0.5);
197 const stdair::YieldLevel_T lRoundedYieldLevel =
198 static_cast<stdair::YieldLevel_T>(lRoundedYieldDouble);
199 if (lRoundedYieldLevel > 0) {
200 // If there is already a virtual class with this yield, add the current
201 // booking class to its list and sum the two demand distributions.
202 // Otherwise, create a new virtual class.
203 stdair::VirtualClassMap_T::iterator itVCMap =
204 lVirtualClassMap.find(lRoundedYieldLevel);
205 if (itVCMap == lVirtualClassMap.end()) {
206 stdair::BookingClassList_T lBookingClassList;
207 lBookingClassList.push_back(lBookingClass_ptr);
208 stdair::VirtualClassStruct lVirtualClass (lBookingClassList);
209 lVirtualClass.setYield (lRoundedYieldLevel);
210 lVirtualClass.setMean (lMean);
211 lVirtualClass.setStdDev (lStdDev);
212
213 lVirtualClassMap.insert (stdair::VirtualClassMap_T::
214 value_type (lRoundedYieldLevel, lVirtualClass));
215 } else {
216 stdair::VirtualClassStruct& lVirtualClass = itVCMap->second;
217 const stdair::MeanValue_T& lVCMean = lVirtualClass.getMean();
218 const stdair::StdDevValue_T& lVCStdDev = lVirtualClass.getStdDev();
219 const stdair::MeanValue_T lNewMean = lVCMean + lMean;
220 const stdair::StdDevValue_T lNewStdDev =
221 std::sqrt(lVCStdDev * lVCStdDev + lStdDev * lStdDev);
222 lVirtualClass.setMean (lNewMean);
223 lVirtualClass.setStdDev (lNewStdDev);
224
225 lVirtualClass.addBookingClass(*lBookingClass_ptr);
226 }
227 }
228 }
229 }
230
231 // Browse the virtual class map from high to low yield.
232 ioLegCabin.emptyVirtualClassList();
233 for (stdair::VirtualClassMap_T::reverse_iterator itVC =
234 lVirtualClassMap.rbegin(); itVC != lVirtualClassMap.rend(); ++itVC) {
235 stdair::VirtualClassStruct& lVC = itVC->second;
236
237 ioLegCabin.addVirtualClass (lVC);
238 if (isNotEmpty == false) {
239 isNotEmpty = true;
240 }
241 }
242 return isNotEmpty;
243 }
244
245 // ////////////////////////////////////////////////////////////////////
247 optimiseUsingOnDForecast (stdair::FlightDate& ioFlightDate,
248 const bool& iReduceFluctuations) {
249 double lMaxBPVariation = 0.0;
250 // Check if the flight date holds a list of leg dates.
251 // If so, retieve it and optimise the cabins.
252 const bool hasLegDateList =
253 stdair::BomManager::hasList<stdair::LegDate> (ioFlightDate);
254 if (hasLegDateList == true) {
255 STDAIR_LOG_DEBUG ("Optimisation for the flight date: "
256 << ioFlightDate.toString());
257 const stdair::LegDateList_T& lLDList =
258 stdair::BomManager::getList<stdair::LegDate> (ioFlightDate);
259 for (stdair::LegDateList_T::const_iterator itLD = lLDList.begin();
260 itLD != lLDList.end(); ++itLD) {
261 stdair::LegDate* lLD_ptr = *itLD;
262 assert (lLD_ptr != NULL);
263
264 //
265 const stdair::LegCabinList_T& lLCList =
266 stdair::BomManager::getList<stdair::LegCabin> (*lLD_ptr);
267 for (stdair::LegCabinList_T::const_iterator itLC = lLCList.begin();
268 itLC != lLCList.end(); ++itLC) {
269 stdair::LegCabin* lLC_ptr = *itLC;
270 assert (lLC_ptr != NULL);
272 const stdair::BidPrice_T& lCurrentBidPrice =
273 lLC_ptr->getCurrentBidPrice();
274 const stdair::BidPrice_T& lPreviousBidPrice =
275 lLC_ptr->getPreviousBidPrice();
276 assert (lPreviousBidPrice != 0);
277 const double lBPVariation =
278 std::abs((lCurrentBidPrice - lPreviousBidPrice)/lPreviousBidPrice);
279 lMaxBPVariation = std::max(lMaxBPVariation, lBPVariation);
280 }
281 }
282 }
283 return lMaxBPVariation;
284 }
285
286}
const int DEFAULT_NUMBER_OF_DRAWS_FOR_MC_SIMULATION
Definition BasConst.cpp:17
static void optimalOptimisationByDP(stdair::LegCabin &)
static void heuristicOptimisationByEmsrB(stdair::LegCabin &)
Definition Emsr.cpp:64
static void heuristicOptimisationByEmsrA(stdair::LegCabin &)
Definition Emsr.cpp:21
static void heuristicOptimisationByEmsr(stdair::LegCabin &)
Definition Emsr.cpp:108
static void optimisationByMCIntegration(stdair::LegCabin &)
static void optimalOptimisationByMCIntegration(stdair::LegCabin &)
static bool optimise(stdair::FlightDate &, const stdair::OptimisationMethod &)
Definition Optimiser.cpp:84
static void optimalOptimisationByDP(stdair::LegCabin &)
Definition Optimiser.cpp:64
static double optimiseUsingOnDForecast(stdair::FlightDate &, const bool &iReduceFluctuations=false)
static void heuristicOptimisationByEmsr(stdair::LegCabin &)
Definition Optimiser.cpp:69
static bool buildVirtualClassListForLegBasedOptimisation(stdair::LegCabin &)
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