13 #include <boost/tokenizer.hpp>
15 #include <boost/program_options.hpp>
17 #include <boost/accumulators/accumulators.hpp>
18 #include <boost/accumulators/statistics.hpp>
22 #include <stdair/stdair_basic_types.hpp>
23 #include <stdair/basic/BasConst_General.hpp>
24 #include <stdair/basic/ProgressStatusSet.hpp>
25 #include <stdair/basic/DemandGenerationMethod.hpp>
26 #include <stdair/bom/EventStruct.hpp>
27 #include <stdair/bom/BookingRequestStruct.hpp>
28 #include <stdair/bom/BomDisplay.hpp>
29 #include <stdair/service/Logger.hpp>
32 #include <trademgen/config/trademgen-paths.hpp>
35 namespace ba = boost::accumulators;
43 typedef ba::accumulator_set<double,
44 ba::stats<ba::tag::min, ba::tag::max,
45 ba::tag::mean (ba::immediate),
69 const stdair::DemandGenerationMethod
71 stdair::DemandGenerationMethod::POI_PRO;
83 stdair::DEFAULT_RANDOM_SEED;
108 std::ios::fmtflags oldFlags = oStream.flags();
111 oStream.setf (std::ios::fixed);
114 oStream <<
"Statistics for the demand generation runs: " << std::endl;
115 oStream <<
" minimum = " << ba::min (iStatAcc) << std::endl;
116 oStream <<
" mean = " << ba::mean (iStatAcc) << std::endl;
117 oStream <<
" maximum = " << ba::max (iStatAcc) << std::endl;
118 oStream <<
" count = " << ba::count (iStatAcc) << std::endl;
119 oStream <<
" variance = " << ba::variance (iStatAcc) << std::endl;
122 oStream.flags (oldFlags);
127 template<
class T> std::ostream&
operator<< (std::ostream& os,
128 const std::vector<T>& v) {
129 std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout,
" "));
137 stdair::RandomSeed_T& ioRandomSeed,
139 stdair::Filename_T& ioInputFilename,
140 stdair::Filename_T& ioOutputFilename,
141 stdair::Filename_T& ioLogFilename,
142 stdair::DemandGenerationMethod& ioDemandGenerationMethod) {
145 char lDemandGenerationMethodChar;
151 boost::program_options::options_description
generic (
"Generic options");
152 generic.add_options()
153 (
"prefix",
"print installation prefix")
154 (
"version,v",
"print version string")
155 (
"help,h",
"produce help message");
159 boost::program_options::options_description config (
"Configuration");
162 "The sample BOM tree can be either built-in or parsed from an input file. That latter must then be given with the -i/--input option")
164 boost::program_options::value<stdair::RandomSeed_T>(&ioRandomSeed)->default_value(K_TRADEMGEN_DEFAULT_RANDOM_SEED),
165 "Seed for the random generation")
167 boost::program_options::value<NbOfRuns_T>(&ioRandomRuns)->default_value(K_TRADEMGEN_DEFAULT_RANDOM_DRAWS),
168 "Number of runs for the demand generations")
169 (
"demandgeneration,G",
171 "Method used to generate the demand (i.e., the booking requests): Poisson Process (P) or Order Statistics (S)")
174 "(CSV) input file for the demand distributions")
177 "(CSV) output file for the generated requests")
180 "Filepath for the logs")
185 boost::program_options::options_description hidden (
"Hidden options");
188 boost::program_options::value< std::vector<std::string> >(),
189 "Show the copyright (license)");
191 boost::program_options::options_description cmdline_options;
192 cmdline_options.add(
generic).add(config).add(hidden);
194 boost::program_options::options_description config_file_options;
195 config_file_options.add(config).add(hidden);
197 boost::program_options::options_description visible (
"Allowed options");
198 visible.add(
generic).add(config);
200 boost::program_options::positional_options_description p;
201 p.add (
"copyright", -1);
203 boost::program_options::variables_map vm;
204 boost::program_options::
205 store (boost::program_options::command_line_parser (argc, argv).
206 options (cmdline_options).positional(p).run(), vm);
208 std::ifstream ifs (
"trademgen.cfg");
209 boost::program_options::store (parse_config_file (ifs, config_file_options),
211 boost::program_options::notify (vm);
213 if (vm.count (
"help")) {
214 std::cout << visible << std::endl;
218 if (vm.count (
"version")) {
219 std::cout << PACKAGE_NAME <<
", version " << PACKAGE_VERSION << std::endl;
223 if (vm.count (
"prefix")) {
224 std::cout <<
"Installation prefix: " << PREFIXDIR << std::endl;
228 if (vm.count (
"builtin")) {
231 const std::string isBuiltinStr = (ioIsBuiltin ==
true)?
"yes":
"no";
232 std::cout <<
"The BOM should be built-in? " << isBuiltinStr << std::endl;
234 if (ioIsBuiltin ==
false) {
237 if (vm.count (
"input")) {
238 ioInputFilename = vm[
"input"].as< std::string >();
239 std::cout <<
"Input filename is: " << ioInputFilename << std::endl;
244 std::cerr <<
"Either one among the -b/--builtin and -i/--input "
245 <<
"options must be specified" << std::endl;
249 if (vm.count (
"output")) {
250 ioOutputFilename = vm[
"output"].as< std::string >();
251 std::cout <<
"Output filename is: " << ioOutputFilename << std::endl;
254 if (vm.count (
"log")) {
255 ioLogFilename = vm[
"log"].as< std::string >();
256 std::cout <<
"Log filename is: " << ioLogFilename << std::endl;
259 if (vm.count (
"demandgeneration")) {
260 ioDemandGenerationMethod =
261 stdair::DemandGenerationMethod (lDemandGenerationMethodChar);
262 std::cout <<
"Date-time request generation method is: "
263 << ioDemandGenerationMethod.describe() << std::endl;
267 std::cout <<
"The random generation seed is: " << ioRandomSeed << std::endl;
270 std::cout <<
"The number of runs is: " << ioRandomRuns << std::endl;
277 const stdair::Filename_T& iOutputFilename,
279 const stdair::DemandGenerationMethod& iDemandGenerationMethod) {
282 std::ofstream output;
283 output.open (iOutputFilename.c_str());
291 const stdair::Count_T& lExpectedNbOfEventsToBeGenerated =
295 boost::progress_display lProgressDisplay (lExpectedNbOfEventsToBeGenerated
298 for (
NbOfRuns_T runIdx = 1; runIdx <= iNbOfRuns; ++runIdx) {
300 output <<
"Run number: " << runIdx << std::endl;
306 const stdair::Count_T& lActualNbOfEventsToBeGenerated =
310 STDAIR_LOG_DEBUG (
"[" << runIdx <<
"] Expected: "
311 << lExpectedNbOfEventsToBeGenerated <<
", actual: "
312 << lActualNbOfEventsToBeGenerated);
321 while (ioTrademgenService.
isQueueDone() ==
false) {
324 stdair::EventStruct lEventStruct;
325 stdair::ProgressStatusSet lProgressStatusSet =
326 ioTrademgenService.
popEvent (lEventStruct);
333 const stdair::BookingRequestStruct& lPoppedRequest =
334 lEventStruct.getBookingRequest();
337 STDAIR_LOG_DEBUG (
"[" << runIdx <<
"] Poped booking request: '"
338 << lPoppedRequest.describe() <<
"'.");
344 const stdair::DemandGeneratorKey_T& lDemandStreamKey =
345 lPoppedRequest.getDemandGeneratorKey();
348 const bool stillHavingRequestsToBeGenerated = ioTrademgenService.
349 stillHavingRequestsToBeGenerated (lDemandStreamKey,
351 iDemandGenerationMethod);
354 STDAIR_LOG_DEBUG (lProgressStatusSet.describe());
355 STDAIR_LOG_DEBUG (
"=> [" << lDemandStreamKey <<
"] is now processed. "
356 <<
"Still generate events for that demand stream? "
357 << stillHavingRequestsToBeGenerated);
361 if (stillHavingRequestsToBeGenerated ==
true) {
363 stdair::BookingRequestPtr_T lNextRequest_ptr =
365 iDemandGenerationMethod);
367 assert (lNextRequest_ptr != NULL);
370 const stdair::Duration_T lDuration =
371 lNextRequest_ptr->getRequestDateTime()
372 - lPoppedRequest.getRequestDateTime();
373 if (lDuration.total_milliseconds() < 0) {
374 STDAIR_LOG_ERROR (
"[" << lDemandStreamKey
375 <<
"] The date-time of the generated event ("
376 << lNextRequest_ptr->getRequestDateTime()
377 <<
") is lower than the date-time "
378 <<
"of the current event ("
379 << lPoppedRequest.getRequestDateTime() <<
")");
384 STDAIR_LOG_DEBUG (
"[" << lDemandStreamKey <<
"] Added request: '"
385 << lNextRequest_ptr->describe()
386 <<
"'. Is queue done? "
390 STDAIR_LOG_DEBUG (
"");
397 lStatAccumulator (lActualNbOfEventsToBeGenerated);
400 ioTrademgenService.
reset();
404 STDAIR_LOG_DEBUG (
"End of the demand generation. Following are some "
405 "statistics for the " << iNbOfRuns <<
" runs.");
406 std::ostringstream oStatStr;
408 STDAIR_LOG_DEBUG (oStatStr.str());
411 const std::string& lBOMStr = ioTrademgenService.
csvDisplay();
412 STDAIR_LOG_DEBUG (lBOMStr);
420 int main (
int argc,
char* argv[]) {
426 stdair::RandomSeed_T lRandomSeed;
432 stdair::Filename_T lInputFilename;
435 stdair::Filename_T lOutputFilename;
438 stdair::Filename_T lLogFilename;
441 stdair::DemandGenerationMethod
445 const int lOptionParserStatus =
447 lInputFilename, lOutputFilename, lLogFilename,
448 lDemandGenerationMethod);
450 if (lOptionParserStatus == K_TRADEMGEN_EARLY_RETURN_STATUS) {
455 std::ofstream logOutputFile;
457 logOutputFile.open (lLogFilename.c_str());
458 logOutputFile.clear();
461 const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
467 if (isBuiltin ==
true) {
479 lDemandGenerationMethod);
482 logOutputFile.close();