lemon/random.h
changeset 1380 04f57dad1b07
parent 1379 db1d342a1087
child 1404 c8d0179a32a2
equal deleted inserted replaced
33:a9e50492b20e 34:82881bf52c2b
   108       static const Word arrayMul2 = 0x5D588B65u;
   108       static const Word arrayMul2 = 0x5D588B65u;
   109 
   109 
   110       static const Word mask = 0x9908B0DFu;
   110       static const Word mask = 0x9908B0DFu;
   111       static const Word loMask = (1u << 31) - 1;
   111       static const Word loMask = (1u << 31) - 1;
   112       static const Word hiMask = ~loMask;
   112       static const Word hiMask = ~loMask;
   113 
       
   114 
   113 
   115       static Word tempering(Word rnd) {
   114       static Word tempering(Word rnd) {
   116         rnd ^= (rnd >> 11);
   115         rnd ^= (rnd >> 11);
   117         rnd ^= (rnd << 7) & 0x9D2C5680u;
   116         rnd ^= (rnd << 7) & 0x9D2C5680u;
   118         rnd ^= (rnd << 15) & 0xEFC60000u;
   117         rnd ^= (rnd << 15) & 0xEFC60000u;
   240         Word rnd = *current;
   239         Word rnd = *current;
   241         return RandomTraits<Word>::tempering(rnd);
   240         return RandomTraits<Word>::tempering(rnd);
   242       }
   241       }
   243 
   242 
   244     private:
   243     private:
   245 
       
   246 
   244 
   247       void fillState() {
   245       void fillState() {
   248         static const Word mask[2] = { 0x0ul, RandomTraits<Word>::mask };
   246         static const Word mask[2] = { 0x0ul, RandomTraits<Word>::mask };
   249         static const Word loMask = RandomTraits<Word>::loMask;
   247         static const Word loMask = RandomTraits<Word>::loMask;
   250         static const Word hiMask = RandomTraits<Word>::hiMask;
   248         static const Word hiMask = RandomTraits<Word>::hiMask;
   269         state[0] = (((state[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^
   267         state[0] = (((state[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^
   270           curr[length - shift] ^ mask[curr[length - 1] & 1ul];
   268           curr[length - shift] ^ mask[curr[length - 1] & 1ul];
   271 
   269 
   272       }
   270       }
   273 
   271 
   274 
       
   275       Word *current;
   272       Word *current;
   276       Word state[length];
   273       Word state[length];
   277 
   274 
   278     };
   275     };
   279 
   276 
   469     ///
   466     ///
   470     /// \brief Mersenne Twister random number generator
   467     /// \brief Mersenne Twister random number generator
   471     ///
   468     ///
   472     /// The Mersenne Twister is a twisted generalized feedback
   469     /// The Mersenne Twister is a twisted generalized feedback
   473     /// shift-register generator of Matsumoto and Nishimura. The period
   470     /// shift-register generator of Matsumoto and Nishimura. The period
   474     /// of this generator is \f$ 2^{19937} - 1 \f$ and it is
   471     /// of this generator is \f$ 2^{19937} - 1\f$ and it is
   475     /// equi-distributed in 623 dimensions for 32-bit numbers. The time
   472     /// equi-distributed in 623 dimensions for 32-bit numbers. The time
   476     /// performance of this generator is comparable to the commonly used
   473     /// performance of this generator is comparable to the commonly used
   477     /// generators.
   474     /// generators.
   478     ///
   475     ///
   479     /// This is a template version implementation both 32-bit and
   476     /// This is a template implementation of both 32-bit and
   480     /// 64-bit architecture optimized versions. The generators differ
   477     /// 64-bit architecture optimized versions. The generators differ
   481     /// sligthly in the initialization and generation phase so they
   478     /// sligthly in the initialization and generation phase so they
   482     /// produce two completly different sequences.
   479     /// produce two completly different sequences.
   483     ///
   480     ///
   484     /// \alert Do not use this class directly, but instead one of \ref
   481     /// \alert Do not use this class directly, but instead one of \ref
   485     /// Random, \ref Random32 or \ref Random64.
   482     /// Random, \ref Random32 or \ref Random64.
   486     ///
   483     ///
   487     /// The generator gives back random numbers of serveral types. To
   484     /// The generator gives back random numbers of serveral types. To
   488     /// get a random number from a range of a floating point type you
   485     /// get a random number from a range of a floating point type, you
   489     /// can use one form of the \c operator() or the \c real() member
   486     /// can use one form of the \c operator() or the \c real() member
   490     /// function. If you want to get random number from the {0, 1, ...,
   487     /// function. If you want to get random number from the {0, 1, ...,
   491     /// n-1} integer range use the \c operator[] or the \c integer()
   488     /// n-1} integer range, use the \c operator[] or the \c integer()
   492     /// method. And to get random number from the whole range of an
   489     /// method. And to get random number from the whole range of an
   493     /// integer type you can use the argumentless \c integer() or \c
   490     /// integer type, you can use the argumentless \c integer() or
   494     /// uinteger() functions. After all you can get random bool with
   491     /// \c uinteger() functions. Finally, you can get random bool with
   495     /// equal chance of true and false or given probability of true
   492     /// equal chance of true and false or with given probability of true
   496     /// result with the \c boolean() member functions.
   493     /// result using the \c boolean() member functions.
       
   494     ///
       
   495     /// Various non-uniform distributions are also supported: normal (Gauss),
       
   496     /// exponential, gamma, Poisson, etc.; and a few two-dimensional
       
   497     /// distributions, too.
   497     ///
   498     ///
   498     ///\code
   499     ///\code
   499     /// // The commented code is identical to the other
   500     /// // The commented code is identical to the other
   500     /// double a = rnd();                     // [0.0, 1.0)
   501     /// double a = rnd();                     // [0.0, 1.0)
   501     /// // double a = rnd.real();             // [0.0, 1.0)
   502     /// // double a = rnd.real();             // [0.0, 1.0)
   511     /// int c = rnd.integer<int>();           // - 2^31 .. 2^31 - 1
   512     /// int c = rnd.integer<int>();           // - 2^31 .. 2^31 - 1
   512     /// bool g = rnd.boolean();               // P(g = true) = 0.5
   513     /// bool g = rnd.boolean();               // P(g = true) = 0.5
   513     /// bool h = rnd.boolean(0.8);            // P(h = true) = 0.8
   514     /// bool h = rnd.boolean(0.8);            // P(h = true) = 0.8
   514     ///\endcode
   515     ///\endcode
   515     ///
   516     ///
   516     /// LEMON provides a global instance of the random number
   517     /// LEMON provides a global instance of the random number generator:
   517     /// generator which name is \ref lemon::rnd "rnd". Usually it is a
   518     /// \ref lemon::rnd "rnd". In most cases, it is a good practice
   518     /// good programming convenience to use this global generator to get
   519     /// to use this global generator to get random numbers.
   519     /// random numbers.
       
   520     ///
   520     ///
   521     /// \sa \ref Random, \ref Random32 or \ref Random64.
   521     /// \sa \ref Random, \ref Random32 or \ref Random64.
   522     ///
       
   523     template<class Word>
   522     template<class Word>
   524     class Random {
   523     class Random {
   525     private:
   524     private:
   526 
   525 
   527       _random_bits::RandomCore<Word> core;
   526       _random_bits::RandomCore<Word> core;
   642         if (!rs.read(reinterpret_cast<char*>(buf), sizeof(buf))) return false;
   641         if (!rs.read(reinterpret_cast<char*>(buf), sizeof(buf))) return false;
   643         seed(buf, buf + size);
   642         seed(buf, buf + size);
   644         return true;
   643         return true;
   645       }
   644       }
   646 
   645 
   647       /// \brief Seding from process id and time
   646       /// \brief Seeding from process id and time
   648       ///
   647       ///
   649       /// Seding from process id and time. This function uses the
   648       /// Seeding from process id and time. This function uses the
   650       /// current process id and the current time for initialize the
   649       /// current process id and the current time for initialize the
   651       /// random sequence.
   650       /// random sequence.
   652       /// \return Currently always \c true.
   651       /// \return Currently always \c true.
   653       bool seedFromTime() {
   652       bool seedFromTime() {
   654 #ifndef LEMON_WIN32
   653 #ifndef LEMON_WIN32
   940         return k-1;
   939         return k-1;
   941       }
   940       }
   942 
   941 
   943       ///@}
   942       ///@}
   944 
   943 
   945       ///\name Two Dimensional Distributions
   944       ///\name Two-Dimensional Distributions
   946       ///
   945       ///
   947       ///@{
   946       ///@{
   948 
   947 
   949       /// Uniform distribution on the full unit circle
   948       /// Uniform distribution on the full unit circle
   950 
   949 
   958           V2=2*real<double>()-1;
   957           V2=2*real<double>()-1;
   959 
   958 
   960         } while(V1*V1+V2*V2>=1);
   959         } while(V1*V1+V2*V2>=1);
   961         return dim2::Point<double>(V1,V2);
   960         return dim2::Point<double>(V1,V2);
   962       }
   961       }
   963       /// A kind of two dimensional normal (Gauss) distribution
   962       /// A kind of two-dimensional normal (Gauss) distribution
   964 
   963 
   965       /// This function provides a turning symmetric two-dimensional distribution.
   964       /// This function provides a turning symmetric two-dimensional distribution.
   966       /// Both coordinates are of standard normal distribution, but they are not
   965       /// Both coordinates are of standard normal distribution, but they are not
   967       /// independent.
   966       /// independent.
   968       ///
   967       ///
   977           S=V1*V1+V2*V2;
   976           S=V1*V1+V2*V2;
   978         } while(S>=1);
   977         } while(S>=1);
   979         double W=std::sqrt(-2*std::log(S)/S);
   978         double W=std::sqrt(-2*std::log(S)/S);
   980         return dim2::Point<double>(W*V1,W*V2);
   979         return dim2::Point<double>(W*V1,W*V2);
   981       }
   980       }
   982       /// A kind of two dimensional exponential distribution
   981       /// A kind of two-dimensional exponential distribution
   983 
   982 
   984       /// This function provides a turning symmetric two-dimensional distribution.
   983       /// This function provides a turning symmetric two-dimensional distribution.
   985       /// The x-coordinate is of conditionally exponential distribution
   984       /// The x-coordinate is of conditionally exponential distribution
   986       /// with the condition that x is positive and y=0. If x is negative and
   985       /// with the condition that x is positive and y=0. If x is negative and
   987       /// y=0 then, -x is of exponential distribution. The same is true for the
   986       /// y=0 then, -x is of exponential distribution. The same is true for the
  1006 
  1005 
  1007   /// \ingroup misc
  1006   /// \ingroup misc
  1008   ///
  1007   ///
  1009   /// \brief Mersenne Twister random number generator
  1008   /// \brief Mersenne Twister random number generator
  1010   ///
  1009   ///
  1011   /// This class implements either the 32 bit or the 64 bit version of
  1010   /// This class implements either the 32-bit or the 64-bit version of
  1012   /// the Mersenne Twister random number generator algorithm
  1011   /// the Mersenne Twister random number generator algorithm
  1013   /// depending the the system architecture.
  1012   /// depending on the system architecture.
  1014   /// 
  1013   /// 
  1015   /// For the API description, see its base class \ref
  1014   /// For the API description, see its base class
  1016   /// _random_bits::Random
  1015   /// \ref _random_bits::Random.
  1017   ///
  1016   ///
  1018   /// \sa \ref _random_bits::Random
  1017   /// \sa \ref _random_bits::Random
  1019   typedef _random_bits::Random<unsigned long> Random;
  1018   typedef _random_bits::Random<unsigned long> Random;
       
  1019 
  1020   /// \ingroup misc
  1020   /// \ingroup misc
  1021   ///
  1021   ///
  1022   /// \brief Mersenne Twister random number generator (32 bit version)
  1022   /// \brief Mersenne Twister random number generator (32-bit version)
  1023   ///
  1023   ///
  1024   /// This class implements the 32 bit version of the Mersenne Twister
  1024   /// This class implements the 32-bit version of the Mersenne Twister
  1025   /// random number generator algorithm. It is recommended to be used
  1025   /// random number generator algorithm. It is recommended to be used
  1026   /// when someone wants to make sure that the \e same pseudo random
  1026   /// when someone wants to make sure that the \e same pseudo random
  1027   /// sequence will be generated on every platfrom.
  1027   /// sequence will be generated on every platfrom.
  1028   ///
  1028   ///
  1029   /// For the API description, see its base class \ref
  1029   /// For the API description, see its base class
  1030   /// _random_bits::Random
  1030   /// \ref _random_bits::Random.
  1031   ///
  1031   ///
  1032   /// \sa \ref _random_bits::Random
  1032   /// \sa \ref _random_bits::Random
  1033 
       
  1034   typedef _random_bits::Random<unsigned int> Random32;
  1033   typedef _random_bits::Random<unsigned int> Random32;
       
  1034 
  1035   /// \ingroup misc
  1035   /// \ingroup misc
  1036   ///
  1036   ///
  1037   /// \brief Mersenne Twister random number generator (64 bit version)
  1037   /// \brief Mersenne Twister random number generator (64-bit version)
  1038   ///
  1038   ///
  1039   /// This class implements the 64 bit version of the Mersenne Twister
  1039   /// This class implements the 64-bit version of the Mersenne Twister
  1040   /// random number generator algorithm. (Even though it will run
  1040   /// random number generator algorithm. (Even though it runs
  1041   /// on 32 bit architectures, too.) It is recommended to ber used when
  1041   /// on 32-bit architectures, too.) It is recommended to be used when
  1042   /// someone wants to make sure that the \e same pseudo random sequence
  1042   /// someone wants to make sure that the \e same pseudo random sequence
  1043   /// will be generated on every platfrom.
  1043   /// will be generated on every platfrom.
  1044   ///
  1044   ///
  1045   /// For the API description, see its base class \ref
  1045   /// For the API description, see its base class
  1046   /// _random_bits::Random
  1046   /// \ref _random_bits::Random.
  1047   ///
  1047   ///
  1048   /// \sa \ref _random_bits::Random
  1048   /// \sa \ref _random_bits::Random
  1049   typedef _random_bits::Random<unsigned long long> Random64;
  1049   typedef _random_bits::Random<unsigned long long> Random64;
  1050 
  1050 
  1051 
       
  1052   extern Random rnd;
  1051   extern Random rnd;
  1053 
       
  1054   
  1052   
  1055 }
  1053 }
  1056 
  1054 
  1057 #endif
  1055 #endif