# HG changeset patch # User Alpar Juttner # Date 1213956570 -3600 # Node ID 0c6556a8e1053e483f829338b701d57536183886 # Parent 9c6dfb5141d37ae0d3df1aafc182d23fa8bff535# Parent d2bac07f174234a37a21860c8c8a9ed4d14b3415 Merge diff -r 9c6dfb5141d3 -r 0c6556a8e105 configure.ac --- a/configure.ac Wed Jun 18 13:52:23 2008 +0100 +++ b/configure.ac Fri Jun 20 11:09:30 2008 +0100 @@ -1,13 +1,9 @@ dnl Process this file with autoconf to produce a configure script. dnl Version information. -m4_define([lemon_version_major], [0]) -m4_define([lemon_version_minor], [99]) -m4_define([lemon_version_micro], []) -m4_define([lemon_version_nano], []) -m4_define([lemon_version_tag], [hg]) +m4_define([lemon_version_number], []) m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i]))]) -m4_define([lemon_version], [lemon_version_major().lemon_version_minor()ifelse(lemon_version_micro(), [], [], [.lemon_version_micro()])ifelse(lemon_version_nano(), [], [], [.lemon_version_nano()])ifelse(lemon_version_tag(), [], [], lemon_version_tag(), [hg], [[_]lemon_version_tag()[_]lemon_hg_revision()], [[_]lemon_version_tag()])]) +m4_define([lemon_version], [ifelse(lemon_version_number(), [], [lemon_hg_revision()], [lemon_version_number()])]) AC_PREREQ([2.59]) AC_INIT([LEMON], [lemon_version()], [lemon-devel@lemon.cs.elte.hu], [lemon]) diff -r 9c6dfb5141d3 -r 0c6556a8e105 lemon/random.h --- a/lemon/random.h Wed Jun 18 13:52:23 2008 +0100 +++ b/lemon/random.h Fri Jun 20 11:09:30 2008 +0100 @@ -66,10 +66,20 @@ #include #include #include +#include #include #include +#ifndef WIN32 +#include +#include +#include +#include +#else +#include +#endif + ///\ingroup misc ///\file ///\brief Mersenne Twister random number generator @@ -526,6 +536,14 @@ public: + ///\name Initialization + /// + /// @{ + + ///\name Initialization + /// + /// @{ + /// \brief Default constructor /// /// Constructor with constant seeding. @@ -594,6 +612,73 @@ _random_bits::Initializer::init(core, begin, end); } + /// \brief Seeding from file or from process id and time + /// + /// By default, this function calls the \c seedFromFile() member + /// function with the /dev/urandom file. If it does not success, + /// it uses the \c seedFromTime(). + /// \return Currently always true. + bool seed() { +#ifndef WIN32 + if (seedFromFile("/dev/urandom", 0)) return true; +#endif + if (seedFromTime()) return true; + return false; + } + + /// \brief Seeding from file + /// + /// Seeding the random sequence from file. The linux kernel has two + /// devices, /dev/random and /dev/urandom which + /// could give good seed values for pseudo random generators (The + /// difference between two devices is that the random may + /// block the reading operation while the kernel can give good + /// source of randomness, while the urandom does not + /// block the input, but it could give back bytes with worse + /// entropy). + /// \param file The source file + /// \param offset The offset, from the file read. + /// \return True when the seeding successes. +#ifndef WIN32 + bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0) +#else + bool seedFromFile(const std::string& file = "", int offset = 0) +#endif + { + std::ifstream rs(file.c_str()); + const int size = 4; + Word buf[size]; + if (offset != 0 && !rs.seekg(offset)) return false; + if (!rs.read(reinterpret_cast(buf), sizeof(buf))) return false; + seed(buf, buf + size); + return true; + } + + /// \brief Seding from process id and time + /// + /// Seding from process id and time. This function uses the + /// current process id and the current time for initialize the + /// random sequence. + /// \return Currently always true. + bool seedFromTime() { +#ifndef WIN32 + timeval tv; + gettimeofday(&tv, 0); + seed(getpid() + tv.tv_sec + tv.tv_usec); +#else + FILETIME time; + GetSystemTimeAsFileTime(&time); + seed(GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime); +#endif + return true; + } + + /// @} + + ///\name Uniform distributions + /// + /// @{ + /// \brief Returns a random real number from the range [0, 1) /// /// It returns a random real number from the range [0, 1). The @@ -623,6 +708,12 @@ return real() * (b - a) + a; } + /// @} + + ///\name Uniform distributions + /// + /// @{ + /// \brief Returns a random real number from the range [0, 1) /// /// It returns a random double from the range [0, 1). @@ -680,6 +771,8 @@ return _random_bits::IntConversion::convert(core); } + /// @} + unsigned int uinteger() { return uinteger(); } @@ -709,6 +802,8 @@ return bool_producer.convert(core); } + /// @} + ///\name Non-uniform distributions ///