lemon/random.h
changeset 177 b685e12e08c0
parent 116 b6bede534255
child 178 d2bac07f1742
equal deleted inserted replaced
12:90f288a33d28 13:36a7fcf2e8bc
    64 
    64 
    65 #include <algorithm>
    65 #include <algorithm>
    66 #include <iterator>
    66 #include <iterator>
    67 #include <vector>
    67 #include <vector>
    68 #include <limits>
    68 #include <limits>
       
    69 #include <fstream>
    69 
    70 
    70 #include <lemon/math.h>
    71 #include <lemon/math.h>
    71 #include <lemon/dim2.h>
    72 #include <lemon/dim2.h>
       
    73 
       
    74 #ifndef WIN32
       
    75 #include <sys/time.h>
       
    76 #include <ctime>
       
    77 #include <sys/types.h>
       
    78 #include <unistd.h>
       
    79 #else
       
    80 #include <windows.h>
       
    81 #endif
    72 
    82 
    73 ///\ingroup misc
    83 ///\ingroup misc
    74 ///\file
    84 ///\file
    75 ///\brief Mersenne Twister random number generator
    85 ///\brief Mersenne Twister random number generator
    76 
    86 
   524     _random_bits::BoolProducer<Word> bool_producer;
   534     _random_bits::BoolProducer<Word> bool_producer;
   525     
   535     
   526 
   536 
   527   public:
   537   public:
   528 
   538 
       
   539     ///\name Initialization
       
   540     ///
       
   541     /// @{
       
   542 
   529     /// \brief Default constructor
   543     /// \brief Default constructor
   530     ///
   544     ///
   531     /// Constructor with constant seeding.
   545     /// Constructor with constant seeding.
   532     Random() { core.initState(); }
   546     Random() { core.initState(); }
   533 
   547 
   592     void seed(Iterator begin, Iterator end) { 
   606     void seed(Iterator begin, Iterator end) { 
   593       typedef typename std::iterator_traits<Iterator>::value_type Number;
   607       typedef typename std::iterator_traits<Iterator>::value_type Number;
   594       _random_bits::Initializer<Number, Word>::init(core, begin, end);
   608       _random_bits::Initializer<Number, Word>::init(core, begin, end);
   595     }
   609     }
   596 
   610 
       
   611     /// \brief Seeding from file or from process id and time
       
   612     ///
       
   613     /// By default, this function calls the \c seedFromFile() member
       
   614     /// function with the <tt>/dev/urandom</tt> file. If it is not success,
       
   615     /// it uses the \c seedFromTime().
       
   616     /// \return Currently always true.
       
   617     bool seed() {
       
   618 #ifndef WIN32
       
   619       if (seedFromFile("/dev/urandom", 0)) return true;
       
   620 #endif
       
   621       if (seedFromTime()) return true;
       
   622       return false;
       
   623     }
       
   624     
       
   625     /// \brief Seeding from file
       
   626     ///
       
   627     /// Seeding the random sequence from file. The linux kernel has two
       
   628     /// devices, <tt>/dev/random</tt> and <tt>/dev/urandom</tt> which
       
   629     /// could give good seed values for pseudo random generators (The
       
   630     /// difference between two devices is that the <tt>random</tt> may
       
   631     /// block the reading operation while the kernel can give good
       
   632     /// source of randomness, while the <tt>urandom</tt> does not
       
   633     /// block the input, but it could give back bytes with worse
       
   634     /// entropy).
       
   635     /// \param file The source file
       
   636     /// \param offset The offset, from the file read.
       
   637     /// \return True when the seeding is success.
       
   638 #ifndef WIN32
       
   639     bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0) 
       
   640 #else
       
   641     bool seedFromFile(const std::string& file = "", int offset = 0) 
       
   642 #endif
       
   643     {
       
   644       std::ifstream rs(file.c_str());
       
   645       const int size = 4;
       
   646       Word buf[size];
       
   647       if (offset != 0 && !rs.seekg(offset)) return false;
       
   648       if (!rs.read(reinterpret_cast<char*>(buf), sizeof(buf))) return false;
       
   649       seed(buf, buf + size);
       
   650       return true;
       
   651     }
       
   652 
       
   653     /// \brief Seding from process id and time
       
   654     ///
       
   655     /// Seding from process id and time. This function uses the
       
   656     /// current process id and the current time for initialize the
       
   657     /// random sequence.
       
   658     /// \return Currently always true.
       
   659     bool seedFromTime() { 	
       
   660 #ifndef WIN32
       
   661       timeval tv;
       
   662       gettimeofday(&tv, 0);
       
   663       seed(getpid() + tv.tv_sec + tv.tv_usec);
       
   664 #else
       
   665       FILETIME time;
       
   666       GetSystemTimeAsFileTime(&time);
       
   667       seed(GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime);
       
   668 #endif
       
   669       return true;
       
   670     }
       
   671 
       
   672     /// @}
       
   673 
       
   674     ///\name Uniform distributions
       
   675     ///
       
   676     /// @{
       
   677 
   597     /// \brief Returns a random real number from the range [0, 1)
   678     /// \brief Returns a random real number from the range [0, 1)
   598     ///
   679     ///
   599     /// It returns a random real number from the range [0, 1). The
   680     /// It returns a random real number from the range [0, 1). The
   600     /// default Number type is \c double.
   681     /// default Number type is \c double.
   601     template <typename Number>
   682     template <typename Number>
   706     /// random bits. Every time when it become empty the generator makes
   787     /// random bits. Every time when it become empty the generator makes
   707     /// a new random word and fill the buffer up.
   788     /// a new random word and fill the buffer up.
   708     bool boolean() {
   789     bool boolean() {
   709       return bool_producer.convert(core);
   790       return bool_producer.convert(core);
   710     }
   791     }
       
   792 
       
   793     /// @}
   711 
   794 
   712     ///\name Non-uniform distributions
   795     ///\name Non-uniform distributions
   713     ///
   796     ///
   714     
   797     
   715     ///@{
   798     ///@{