RMOL Logo Get Revenue Management Optimisation Library at SourceForge.net. Fast, secure and Free Open Source software downloads

rmol.cpp

Go to the documentation of this file.
00001 // C
00002 #include <assert.h>
00003 // STL
00004 #include <iostream>
00005 #include <sstream>
00006 #include <fstream>
00007 #include <string>
00008 // Boost (Extended STL)
00009 #include <boost/date_time/posix_time/posix_time.hpp>
00010 #include <boost/date_time/gregorian/gregorian.hpp>
00011 #include <boost/program_options.hpp>
00012 // RMOL
00013 #include <rmol/RMOL_Service.hpp>
00014 #include <rmol/config/rmol-paths.hpp>
00015 
00016 
00017 // //////// Constants //////
00019 const std::string K_RMOL_DEFAULT_LOG_FILENAME ("rmol.log");
00020 
00022 const std::string K_RMOL_DEFAULT_INPUT_FILENAME ("class.csv");
00023 
00025 const int K_RMOL_DEFAULT_RANDOM_DRAWS = 100000;
00026 
00028 const double K_RMOL_DEFAULT_CAPACITY = 500.0;
00029 
00032 // const std::vector<double> K_RMOL_DEFAULT_SELLUP_PROBABILITY;
00033 
00044 const short K_RMOL_DEFAULT_METHOD = 0;
00045 
00047 void initDefaultValuesForSellupProbabilityVector (RMOL::SellupProbabilityVector_T& ioSellUpProbabilityVector) {
00048   // Add default values only when the given vector is empty
00049   if (ioSellUpProbabilityVector.empty() == true) {
00050     ioSellUpProbabilityVector.push_back (0.2);
00051   }
00052 }
00053 
00054 
00055 // ///////// Parsing of Options & Configuration /////////
00056 // A helper function to simplify the main part.
00057 template<class T> std::ostream& operator<< (std::ostream& os,
00058                                             const std::vector<T>& v) {
00059   std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout, " ")); 
00060   return os;
00061 }
00062 
00064 const int K_RMOL_EARLY_RETURN_STATUS = 99;
00065 
00067 int readConfiguration(int argc, char* argv[], 
00068                       int& ioRandomDraws, double& ioCapacity, 
00069                       RMOL::SellupProbabilityVector_T& ioSellupProbabilityVector,
00070                       short& ioMethod, std::string& ioInputFilename, 
00071                       std::string& ioLogFilename) {
00072 
00073   // Initialise the sell-up probability vector with default values
00074   initDefaultValuesForSellupProbabilityVector (ioSellupProbabilityVector);
00075     
00076   // Declare a group of options that will be allowed only on command line
00077   boost::program_options::options_description generic ("Generic options");
00078   generic.add_options()
00079     ("prefix", "print installation prefix")
00080     ("version,v", "print version string")
00081     ("help,h", "produce help message");
00082     
00083   // Declare a group of options that will be allowed both on command
00084   // line and in config file
00085   boost::program_options::options_description config ("Configuration");
00086   config.add_options()
00087     ("draws,d",
00088      boost::program_options::value<int>(&ioRandomDraws)->default_value(K_RMOL_DEFAULT_RANDOM_DRAWS), 
00089      "Number of to-be-generated random draws")
00090     ("capacity,c",
00091      boost::program_options::value<double>(&ioCapacity)->default_value(K_RMOL_DEFAULT_CAPACITY), 
00092      "Resource capacity (e.g., for a flight leg)")
00093     ("sellup,s",
00094      boost::program_options::value< std::vector<double> >(&ioSellupProbabilityVector)->multitoken(),
00095      "Sell-up proability vector (e.g. j-th element implies the sell up probability of class j+1 to class j where class 1 yields the highest value")
00096     ("method,m",
00097      boost::program_options::value<short>(&ioMethod)->default_value(K_RMOL_DEFAULT_METHOD), 
00098      "Revenue Management method to be used (0 = Monte-Carlo, 1 = Dynamic Programming, 2 = EMSR, 3 = EMSR-a, 4 = EMSR-b, 5 = EMSR-a with sell up probability)")
00099     ("input,i",
00100      boost::program_options::value< std::string >(&ioInputFilename)->default_value(K_RMOL_DEFAULT_INPUT_FILENAME),
00101      "(CVS) input file for the demand distributions")
00102     ("log,l",
00103      boost::program_options::value< std::string >(&ioLogFilename)->default_value(K_RMOL_DEFAULT_LOG_FILENAME),
00104      "Filename for the logs")
00105     ;
00106 
00107   // Hidden options, will be allowed both on command line and
00108   // in config file, but will not be shown to the user.
00109   boost::program_options::options_description hidden ("Hidden options");
00110   hidden.add_options()
00111     ("copyright",
00112      boost::program_options::value< std::vector<std::string> >(),
00113      "Show the copyright (license)");
00114         
00115   boost::program_options::options_description cmdline_options;
00116   cmdline_options.add(generic).add(config).add(hidden);
00117 
00118   boost::program_options::options_description config_file_options;
00119   config_file_options.add(config).add(hidden);
00120 
00121   boost::program_options::options_description visible ("Allowed options");
00122   visible.add(generic).add(config);
00123         
00124   boost::program_options::positional_options_description p;
00125   p.add ("copyright", -1);
00126         
00127   boost::program_options::variables_map vm;
00128   boost::program_options::
00129     store (boost::program_options::command_line_parser (argc, argv).
00130            options (cmdline_options).positional(p).run(), vm);
00131 
00132   std::ifstream ifs ("rmol.cfg");
00133   boost::program_options::store (parse_config_file (ifs, config_file_options),
00134                                  vm);
00135   boost::program_options::notify (vm);
00136     
00137   if (vm.count ("help")) {
00138     std::cout << visible << std::endl;
00139     return K_RMOL_EARLY_RETURN_STATUS;
00140   }
00141 
00142   if (vm.count ("version")) {
00143     std::cout << PACKAGE_NAME << ", version " << PACKAGE_VERSION << std::endl;
00144     return K_RMOL_EARLY_RETURN_STATUS;
00145   }
00146 
00147   if (vm.count ("prefix")) {
00148     std::cout << "Installation prefix: " << PREFIXDIR << std::endl;
00149     return K_RMOL_EARLY_RETURN_STATUS;
00150   }
00151 
00152   if (vm.count ("input")) {
00153     ioInputFilename = vm["input"].as< std::string >();
00154     std::cout << "Input filename is: " << ioInputFilename << std::endl;
00155   }
00156 
00157   if (vm.count ("log")) {
00158     ioLogFilename = vm["log"].as< std::string >();
00159     std::cout << "Log filename is: " << ioLogFilename << std::endl;
00160   }
00161 
00162   std::cout << "The number of random draws is: " << ioRandomDraws << std::endl;
00163   std::cout << "The resource capacity is: " << ioCapacity << std::endl;
00164   std::cout << "The Revenue Management method is: " << ioMethod << std::endl;
00165   std::cout << "The sell-up probability vector is: " << std::endl;
00166   unsigned short idx = 0;
00167   for (RMOL::SellupProbabilityVector_T::const_iterator itValue =
00168          ioSellupProbabilityVector.begin();
00169        itValue != ioSellupProbabilityVector.end(); ++itValue, ++idx) {
00170     std::cout << "[" << idx << "] " << *itValue << "; ";
00171   }
00172   std::cout << std::endl;
00173   
00174   return 0;
00175 }
00176 
00177 
00178 // ///////// M A I N ////////////
00179 int main (int argc, char* argv[]) {
00180   try {
00181     
00182     // Number of random draws to be generated (best if greater than 100)
00183     int lRandomDraws = 0;
00184     
00185     // Cabin Capacity (it must be greater then 100 here)
00186     double lCapacity = 0.0;
00187 
00191     RMOL::SellupProbabilityVector_T lSellupProbabilityVector;
00192     // lSellupProbabilityVector.push_back (0.2);
00193 
00194     // Methods of optimisation (0 = Monte-Carlo, 1 = Dynamic Programming, 
00195     // 2 = EMSR, 3 = EMSR-a, 4 = EMSR-b, 5 = EMSR-a with sell up probability)
00196     short lMethod = 0;   
00197     
00198     // Input file name
00199     std::string lInputFilename;
00200 
00201     // Output log File
00202     std::string lLogFilename;
00203 
00204     // Call the command-line option parser
00205     const int lOptionParserStatus = 
00206       readConfiguration (argc, argv, lRandomDraws, lCapacity,
00207                          lSellupProbabilityVector, lMethod, lInputFilename,
00208                          lLogFilename);
00209 
00210     if (lOptionParserStatus == K_RMOL_EARLY_RETURN_STATUS) {
00211       return 0;
00212     }
00213 
00214     // Check wether or not a (CSV) input file should be read
00215     bool hasInputFile = false;
00216     if (lInputFilename.empty() == false) {
00217       hasInputFile = true;
00218     }
00219 
00220     // Set the log parameters
00221     std::ofstream logOutputFile;
00222     // Open and clean the log outputfile
00223     logOutputFile.open (lLogFilename.c_str());
00224     logOutputFile.clear();
00225     
00226     // Initialise the list of classes/buckets
00227     RMOL::RMOL_Service rmolService (logOutputFile, lCapacity);
00228     rmolService.setUpStudyStatManager();
00229     
00230     if (hasInputFile) {
00231       // Read the input file
00232       rmolService.readFromInputFile (lInputFilename);
00233       
00234     } else {
00235       // No input file has been provided. So, process a sample.
00236       
00237       // STEP 0.
00238       // List of demand distribution parameters (mean and standard deviation)
00239       
00240       // Class/bucket 1: N (20, 9), p1 = 100
00241       rmolService.addBucket (100.0, 20, 9);
00242       
00243       // Class/bucket 2: N (45, 12), p2 = 70
00244       rmolService.addBucket (70.0, 45, 12);
00245       
00246       // Class/bucket 3: no need to define a demand distribution, p3 = 42
00247       rmolService.addBucket (42.0, 0, 0);
00248     }
00249     
00250     switch (lMethod) {
00251     case 0: {
00252       // Calculate the optimal protections by the Monte Carlo
00253       // Integration approach
00254       rmolService.optimalOptimisationByMCIntegration (lRandomDraws);
00255       break;
00256     }
00257     case 1: {
00258       // Calculate the optimal protections by DP.
00259       rmolService.optimalOptimisationByDP ();
00260       break;
00261     }
00262     case 2: {
00263       // Calculate the Bid-Price Vector by EMSR
00264       rmolService.heuristicOptimisationByEmsr ();
00265       break;
00266     }
00267     case 3: {
00268       // Calculate the protections by EMSR-a
00269       rmolService.heuristicOptimisationByEmsrA ();
00270       break;
00271     }
00272     case 4: {
00273       // Calculate the protections by EMSR-b
00274       rmolService.heuristicOptimisationByEmsrB ();
00275       break;
00276     }
00277     case 5: {
00278       // Calculate the protections by EMSR-a with sell up probability
00279       rmolService.heuristicOptimisationByEmsrAwithSellup 
00280         (lSellupProbabilityVector);
00281       break;
00282     }
00283     case 6: {
00284       // Calculate the optimal protections by the Monte Carlo
00285       // Integration approach
00286       rmolService.buildContextForMC (lRandomDraws);
00287       rmolService.legOptimisationByMC ();
00288       break;
00289     }
00290     default: {
00291       rmolService.optimalOptimisationByMCIntegration (lRandomDraws);
00292     }
00293     }
00294     
00295   } catch (const std::exception& stde) {
00296     std::cerr << "Standard exception: " << stde.what() << std::endl;
00297     return -1;
00298     
00299   } catch (...) {
00300     return -1;
00301   }
00302   
00303   return 0;     
00304 }
SourceForge Logo

Generated on Sat Jun 6 13:48:25 2009 for RMOL by Doxygen 1.5.7.1