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/EventQueue.hpp>
28 #include <stdair/bom/BookingRequestStruct.hpp>
29 #include <stdair/bom/BomDisplay.hpp>
30 #include <stdair/service/Logger.hpp>
37 namespace ba = boost::accumulators;
45 typedef ba::accumulator_set<double,
46 ba::stats<ba::tag::min, ba::tag::max,
47 ba::tag::mean (ba::immediate),
71 const stdair::DemandGenerationMethod
73 stdair::DemandGenerationMethod::POI_PRO;
85 stdair::DEFAULT_RANDOM_SEED;
110 std::ios::fmtflags oldFlags = oStream.flags();
113 oStream.setf (std::ios::fixed);
116 oStream <<
"Statistics for the demand generation runs: " << std::endl;
117 oStream <<
" minimum = " << ba::min (iStatAcc) << std::endl;
118 oStream <<
" mean = " << ba::mean (iStatAcc) << std::endl;
119 oStream <<
" maximum = " << ba::max (iStatAcc) << std::endl;
120 oStream <<
" count = " << ba::count (iStatAcc) << std::endl;
121 oStream <<
" variance = " << ba::variance (iStatAcc) << std::endl;
124 oStream.flags (oldFlags);
129 template<
class T> std::ostream&
operator<< (std::ostream& os,
130 const std::vector<T>& v) {
131 std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout,
" "));
139 stdair::RandomSeed_T& ioRandomSeed,
141 stdair::Filename_T& ioInputFilename,
142 stdair::Filename_T& ioOutputFilename,
143 stdair::Filename_T& ioLogFilename,
144 stdair::DemandGenerationMethod& ioDemandGenerationMethod) {
147 char lDemandGenerationMethodChar;
153 boost::program_options::options_description
generic (
"Generic options");
154 generic.add_options()
155 (
"prefix",
"print installation prefix")
156 (
"version,v",
"print version string")
157 (
"help,h",
"produce help message");
161 boost::program_options::options_description config (
"Configuration");
164 "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")
166 boost::program_options::value<stdair::RandomSeed_T>(&ioRandomSeed)->default_value(K_TRADEMGEN_DEFAULT_RANDOM_SEED),
167 "Seed for the random generation")
169 boost::program_options::value<NbOfRuns_T>(&ioRandomRuns)->default_value(K_TRADEMGEN_DEFAULT_RANDOM_DRAWS),
170 "Number of runs for the demand generations")
171 (
"demandgeneration,G",
173 "Method used to generate the demand (i.e., the booking requests): Poisson Process (P) or Order Statistics (S)")
176 "(CSV) input file for the demand distributions")
179 "(CSV) output file for the generated requests")
182 "Filepath for the logs")
187 boost::program_options::options_description hidden (
"Hidden options");
190 boost::program_options::value< std::vector<std::string> >(),
191 "Show the copyright (license)");
193 boost::program_options::options_description cmdline_options;
194 cmdline_options.add(
generic).add(config).add(hidden);
196 boost::program_options::options_description config_file_options;
197 config_file_options.add(config).add(hidden);
199 boost::program_options::options_description visible (
"Allowed options");
200 visible.add(
generic).add(config);
202 boost::program_options::positional_options_description p;
203 p.add (
"copyright", -1);
205 boost::program_options::variables_map vm;
206 boost::program_options::
207 store (boost::program_options::command_line_parser (argc, argv).
208 options (cmdline_options).positional(p).run(), vm);
210 std::ifstream ifs (
"trademgen.cfg");
211 boost::program_options::store (parse_config_file (ifs, config_file_options),
213 boost::program_options::notify (vm);
215 if (vm.count (
"help")) {
216 std::cout << visible << std::endl;
220 if (vm.count (
"version")) {
225 if (vm.count (
"prefix")) {
226 std::cout <<
"Installation prefix: " <<
PREFIXDIR << std::endl;
230 if (vm.count (
"builtin")) {
233 const std::string isBuiltinStr = (ioIsBuiltin ==
true)?
"yes":
"no";
234 std::cout <<
"The BOM should be built-in? " << isBuiltinStr << std::endl;
236 if (ioIsBuiltin ==
false) {
239 if (vm.count (
"input")) {
240 ioInputFilename = vm[
"input"].as< std::string >();
241 std::cout <<
"Input filename is: " << ioInputFilename << std::endl;
246 std::cerr <<
"Either one among the -b/--builtin and -i/--input "
247 <<
"options must be specified" << std::endl;
251 if (vm.count (
"output")) {
252 ioOutputFilename = vm[
"output"].as< std::string >();
253 std::cout <<
"Output filename is: " << ioOutputFilename << std::endl;
256 if (vm.count (
"log")) {
257 ioLogFilename = vm[
"log"].as< std::string >();
258 std::cout <<
"Log filename is: " << ioLogFilename << std::endl;
261 if (vm.count (
"demandgeneration")) {
262 ioDemandGenerationMethod =
263 stdair::DemandGenerationMethod (lDemandGenerationMethodChar);
264 std::cout <<
"Date-time request generation method is: "
265 << ioDemandGenerationMethod.describe() << std::endl;
269 std::cout <<
"The random generation seed is: " << ioRandomSeed << std::endl;
272 std::cout <<
"The number of runs is: " << ioRandomRuns << std::endl;
279 const stdair::Filename_T& iOutputFilename,
281 const stdair::DemandGenerationMethod& iDemandGenerationMethod) {
284 std::ofstream output;
285 output.open (iOutputFilename.c_str());
293 const stdair::Count_T& lExpectedNbOfEventsToBeGenerated =
297 boost::progress_display lProgressDisplay (lExpectedNbOfEventsToBeGenerated
300 for (
NbOfRuns_T runIdx = 1; runIdx <= iNbOfRuns; ++runIdx) {
302 output <<
"Run number: " << runIdx << std::endl;
308 const stdair::Count_T& lActualNbOfEventsToBeGenerated =
312 STDAIR_LOG_DEBUG (
"[" << runIdx <<
"] Expected: "
313 << lExpectedNbOfEventsToBeGenerated <<
", actual: "
314 << lActualNbOfEventsToBeGenerated);
323 while (ioTrademgenService.
isQueueDone() ==
false) {
326 stdair::EventStruct lEventStruct;
327 stdair::ProgressStatusSet lProgressStatusSet =
328 ioTrademgenService.
popEvent (lEventStruct);
335 const stdair::BookingRequestStruct& lPoppedRequest =
336 lEventStruct.getBookingRequest();
339 STDAIR_LOG_DEBUG (
"[" << runIdx <<
"] Poped booking request: '"
340 << lPoppedRequest.describe() <<
"'.");
346 const stdair::DemandGeneratorKey_T& lDemandStreamKey =
347 lPoppedRequest.getDemandGeneratorKey();
350 const bool stillHavingRequestsToBeGenerated = ioTrademgenService.
351 stillHavingRequestsToBeGenerated (lDemandStreamKey,
353 iDemandGenerationMethod);
356 STDAIR_LOG_DEBUG (lProgressStatusSet.describe());
357 STDAIR_LOG_DEBUG (
"=> [" << lDemandStreamKey <<
"] is now processed. "
358 <<
"Still generate events for that demand stream? "
359 << stillHavingRequestsToBeGenerated);
363 if (stillHavingRequestsToBeGenerated ==
true) {
365 stdair::BookingRequestPtr_T lNextRequest_ptr =
367 iDemandGenerationMethod);
369 assert (lNextRequest_ptr != NULL);
372 const stdair::Duration_T lDuration =
373 lNextRequest_ptr->getRequestDateTime()
374 - lPoppedRequest.getRequestDateTime();
375 if (lDuration.total_milliseconds() < 0) {
376 STDAIR_LOG_ERROR (
"[" << lDemandStreamKey
377 <<
"] The date-time of the generated event ("
378 << lNextRequest_ptr->getRequestDateTime()
379 <<
") is lower than the date-time "
380 <<
"of the current event ("
381 << lPoppedRequest.getRequestDateTime() <<
")");
386 STDAIR_LOG_DEBUG (
"[" << lDemandStreamKey <<
"] Added request: '"
387 << lNextRequest_ptr->describe()
388 <<
"'. Is queue done? "
392 STDAIR_LOG_DEBUG (
"");
399 lStatAccumulator (lActualNbOfEventsToBeGenerated);
402 ioTrademgenService.
reset();
406 STDAIR_LOG_DEBUG (
"End of the demand generation. Following are some "
407 "statistics for the " << iNbOfRuns <<
" runs.");
408 std::ostringstream oStatStr;
410 STDAIR_LOG_DEBUG (oStatStr.str());
413 const std::string& lBOMStr = ioTrademgenService.
csvDisplay();
414 STDAIR_LOG_DEBUG (lBOMStr);
422 int main (
int argc,
char* argv[]) {
428 stdair::RandomSeed_T lRandomSeed;
434 stdair::Filename_T lInputFilename;
437 stdair::Filename_T lOutputFilename;
440 stdair::Filename_T lLogFilename;
443 stdair::DemandGenerationMethod
447 const int lOptionParserStatus =
449 lInputFilename, lOutputFilename, lLogFilename,
450 lDemandGenerationMethod);
452 if (lOptionParserStatus == K_TRADEMGEN_EARLY_RETURN_STATUS) {
457 std::ofstream logOutputFile;
459 logOutputFile.open (lLogFilename.c_str());
460 logOutputFile.clear();
463 const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
469 if (isBuiltin ==
true) {
480 lDemandGenerationMethod);
483 logOutputFile.close();