gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Seeding from file source or from pid and time (ticket #19)
0 1 0
default
1 file changed with 83 insertions and 0 deletions:
↑ Collapse diff ↑
Ignore white space 12 line context
... ...
@@ -63,16 +63,26 @@
63 63
#define LEMON_RANDOM_H
64 64

	
65 65
#include <algorithm>
66 66
#include <iterator>
67 67
#include <vector>
68 68
#include <limits>
69
#include <fstream>
69 70

	
70 71
#include <lemon/math.h>
71 72
#include <lemon/dim2.h>
72 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
82

	
73 83
///\ingroup misc
74 84
///\file
75 85
///\brief Mersenne Twister random number generator
76 86

	
77 87
namespace lemon {
78 88

	
... ...
@@ -523,12 +533,16 @@
523 533
    _random_bits::RandomCore<Word> core;
524 534
    _random_bits::BoolProducer<Word> bool_producer;
525 535
    
526 536

	
527 537
  public:
528 538

	
539
    ///\name Initialization
540
    ///
541
    /// @{
542

	
529 543
    /// \brief Default constructor
530 544
    ///
531 545
    /// Constructor with constant seeding.
532 546
    Random() { core.initState(); }
533 547

	
534 548
    /// \brief Constructor with seed
... ...
@@ -591,12 +605,79 @@
591 605
    template <typename Iterator>
592 606
    void seed(Iterator begin, Iterator end) { 
593 607
      typedef typename std::iterator_traits<Iterator>::value_type Number;
594 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 678
    /// \brief Returns a random real number from the range [0, 1)
598 679
    ///
599 680
    /// It returns a random real number from the range [0, 1). The
600 681
    /// default Number type is \c double.
601 682
    template <typename Number>
602 683
    Number real() {
... ...
@@ -706,12 +787,14 @@
706 787
    /// random bits. Every time when it become empty the generator makes
707 788
    /// a new random word and fill the buffer up.
708 789
    bool boolean() {
709 790
      return bool_producer.convert(core);
710 791
    }
711 792

	
793
    /// @}
794

	
712 795
    ///\name Non-uniform distributions
713 796
    ///
714 797
    
715 798
    ///@{
716 799
    
717 800
    /// \brief Returns a random bool
0 comments (0 inline)