RMOL Logo  1.00.0
C++ library of Revenue Management and Optimisation classes and functions
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
rmol.cpp
Go to the documentation of this file.
1 // STL
2 #include <cassert>
3 #include <iostream>
4 #include <sstream>
5 #include <fstream>
6 #include <string>
7 // Boost (Extended STL)
8 #include <boost/date_time/posix_time/posix_time.hpp>
9 #include <boost/date_time/gregorian/gregorian.hpp>
10 #include <boost/program_options.hpp>
11 // StdAir
12 #include <stdair/service/Logger.hpp>
13 // RMOL
15 #include <rmol/RMOL_Service.hpp>
16 #include <rmol/config/rmol-paths.hpp>
17 
18 // //////// Constants //////
20 const std::string K_RMOL_DEFAULT_LOG_FILENAME ("rmol.log");
21 
24 const bool K_RMOL_DEFAULT_BUILT_IN_INPUT = false;
25 
27 const std::string K_RMOL_DEFAULT_INPUT_FILENAME (STDAIR_SAMPLE_DIR "/rm01.csv");
28 
31 
33 const double K_RMOL_DEFAULT_CAPACITY = 500.0;
34 
44 const short K_RMOL_DEFAULT_METHOD = 0;
45 
46 // ///////// Parsing of Options & Configuration /////////
47 // A helper function to simplify the main part.
48 template<class T> std::ostream& operator<< (std::ostream& os,
49  const std::vector<T>& v) {
50  std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout, " "));
51  return os;
52 }
53 
56 
58 int readConfiguration(int argc, char* argv[],
59  int& ioRandomDraws, double& ioCapacity,
60  short& ioMethod, bool& ioIsBuiltin,
61  std::string& ioInputFilename, std::string& ioLogFilename){
62 
63  // Default for the built-in input
64  ioIsBuiltin = K_RMOL_DEFAULT_BUILT_IN_INPUT;
65 
66  // Declare a group of options that will be allowed only on command line
67  boost::program_options::options_description generic ("Generic options");
68  generic.add_options()
69  ("prefix", "print installation prefix")
70  ("version,v", "print version string")
71  ("help,h", "produce help message");
72 
73  // Declare a group of options that will be allowed both on command
74  // line and in config file
75  boost::program_options::options_description config ("Configuration");
76  config.add_options()
77  ("draws,d",
78  boost::program_options::value<int>(&ioRandomDraws)->default_value(K_RMOL_DEFAULT_RANDOM_DRAWS),
79  "Number of to-be-generated random draws")
80  ("capacity,c",
81  boost::program_options::value<double>(&ioCapacity)->default_value(K_RMOL_DEFAULT_CAPACITY),
82  "Resource capacity (e.g., for a flight leg)")
83  ("method,m",
84  boost::program_options::value<short>(&ioMethod)->default_value(K_RMOL_DEFAULT_METHOD),
85  "Revenue Management method to be used (0 = Monte-Carlo, 1 = Dynamic Programming, 2 = EMSR, 3 = EMSR-a, 4 = EMSR-b)")
86  ("builtin,b",
87  "The cabin set up can be either built-in or parsed from an input file. That latter must then be given with the -i/--input option")
88  ("input,i",
89  boost::program_options::value< std::string >(&ioInputFilename)->default_value(K_RMOL_DEFAULT_INPUT_FILENAME),
90  "(CSV) input file for the demand distribution parameters and resource (leg-cabin) capacities")
91  ("log,l",
92  boost::program_options::value< std::string >(&ioLogFilename)->default_value(K_RMOL_DEFAULT_LOG_FILENAME),
93  "Filename for the logs")
94  ;
95 
96  // Hidden options, will be allowed both on command line and
97  // in config file, but will not be shown to the user.
98  boost::program_options::options_description hidden ("Hidden options");
99  hidden.add_options()
100  ("copyright",
101  boost::program_options::value< std::vector<std::string> >(),
102  "Show the copyright (license)");
103 
104  boost::program_options::options_description cmdline_options;
105  cmdline_options.add(generic).add(config).add(hidden);
106 
107  boost::program_options::options_description config_file_options;
108  config_file_options.add(config).add(hidden);
109 
110  boost::program_options::options_description visible ("Allowed options");
111  visible.add(generic).add(config);
112 
113  boost::program_options::positional_options_description p;
114  p.add ("copyright", -1);
115 
116  boost::program_options::variables_map vm;
117  boost::program_options::
118  store (boost::program_options::command_line_parser (argc, argv).
119  options (cmdline_options).positional(p).run(), vm);
120 
121  std::ifstream ifs ("rmol.cfg");
122  boost::program_options::store (parse_config_file (ifs, config_file_options),
123  vm);
124  boost::program_options::notify (vm);
125 
126  if (vm.count ("help")) {
127  std::cout << visible << std::endl;
129  }
130 
131  if (vm.count ("version")) {
132  std::cout << PACKAGE_NAME << ", version " << PACKAGE_VERSION << std::endl;
134  }
135 
136  if (vm.count ("prefix")) {
137  std::cout << "Installation prefix: " << PREFIXDIR << std::endl;
139  }
140 
141  if (vm.count ("builtin")) {
142  ioIsBuiltin = true;
143  }
144  const std::string isBuiltinStr = (ioIsBuiltin == true)?"yes":"no";
145  std::cout << "The BOM should be built-in? " << isBuiltinStr << std::endl;
146 
147  if (ioIsBuiltin == false) {
148  if (vm.count ("input")) {
149  ioInputFilename = vm["input"].as< std::string >();
150  std::cout << "Input filename is: " << ioInputFilename << std::endl;
151  }
152  }
153 
154  if (vm.count ("log")) {
155  ioLogFilename = vm["log"].as< std::string >();
156  std::cout << "Log filename is: " << ioLogFilename << std::endl;
157  }
158 
159  std::cout << "The number of random draws is: " << ioRandomDraws << std::endl;
160  std::cout << "The resource capacity is: " << ioCapacity << std::endl;
161  std::cout << "The optimisation method is: " << ioMethod << std::endl;
162  std::cout << std::endl;
163 
164  return 0;
165 }
166 
167 // /////////////////////////////////////////////////////
168 void optimise (RMOL::RMOL_Service& rmolService,
169  const short& iMethod, const int& iRandomDraws) {
170 
171  switch (iMethod) {
172  case 0: {
173  // Calculate the optimal protections by the Monte Carlo
174  // Integration approach
175  rmolService.optimalOptimisationByMCIntegration (iRandomDraws);
176  break;
177  }
178  case 1: {
179  // Calculate the optimal protections by DP.
180  rmolService.optimalOptimisationByDP ();
181  break;
182  }
183  case 2: {
184  // Calculate the Bid-Price Vector by EMSR
185  rmolService.heuristicOptimisationByEmsr ();
186  break;
187  }
188  case 3: {
189  // Calculate the protections by EMSR-a
190  rmolService.heuristicOptimisationByEmsrA ();
191  break;
192  }
193  case 4: {
194  // Calculate the protections by EMSR-b
195  rmolService.heuristicOptimisationByEmsrB ();
196  break;
197  }
198  default: {
199  rmolService.optimalOptimisationByMCIntegration (iRandomDraws);
200  }
201  }
202 }
203 
204 // ///////// M A I N ////////////
205 int main (int argc, char* argv[]) {
206 
207  // Number of random draws to be generated (best if greater than 100)
208  int lRandomDraws = 0;
209 
210  // Cabin Capacity (it must be greater then 100 here)
211  double lCapacity = 0.0;
212 
213  // Methods of optimisation (0 = Monte-Carlo, 1 = Dynamic Programming,
214  // 2 = EMSR, 3 = EMSR-a, 4 = EMSR-b)
215  short lMethod = 0;
216 
217  // Built-in
218  bool isBuiltin;
219 
220  // Input file name
221  std::string lInputFilename;
222 
223  // Output log File
224  std::string lLogFilename;
225 
226  // Call the command-line option parser
227  const int lOptionParserStatus =
228  readConfiguration (argc, argv, lRandomDraws, lCapacity, lMethod,
229  isBuiltin, lInputFilename, lLogFilename);
230 
231  if (lOptionParserStatus == K_RMOL_EARLY_RETURN_STATUS) {
232  return 0;
233  }
234 
235  // Set the log parameters
236  std::ofstream logOutputFile;
237  // Open and clean the log outputfile
238  logOutputFile.open (lLogFilename.c_str());
239  logOutputFile.clear();
240 
241  // Initialise the log stream
242  const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
243 
244  // Initialise the RMOL service
245  RMOL::RMOL_Service rmolService (lLogParams);
246 
247  if (isBuiltin == true) {
248  // DEBUG
249  STDAIR_LOG_DEBUG ("No input file has been given."
250  "A sample BOM tree will therefore be built.");
251 
252  // Build a sample BOM tree
253  rmolService.buildSampleBom();
254 
255  } else {
256  // DEBUG
257  STDAIR_LOG_DEBUG ("RMOL will parse " << lInputFilename
258  << " and build the corresponding BOM tree.");
259 
260  //
261  rmolService.parseAndLoad (lCapacity, lInputFilename);
262  }
263 
264  // Launch the optimisation
265  optimise (rmolService, lMethod, lRandomDraws);
266 
267  //
268  logOutputFile.close();
269 
270  return 0;
271 }