3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_RANDOM_H
20 #define LEMON_RANDOM_H
32 ///\brief Mersenne Twister random number generator
34 ///\author Balazs Dezso
38 namespace _random_bits {
40 template <typename _Word, int _bits = std::numeric_limits<_Word>::digits>
41 struct RandomTraits {};
43 template <typename _Word>
44 struct RandomTraits<_Word, 32> {
47 static const int bits = 32;
49 static const int length = 624;
50 static const int shift = 397;
52 static const Word mul = 0x6c078965u;
53 static const Word arrayInit = 0x012BD6AAu;
54 static const Word arrayMul1 = 0x0019660Du;
55 static const Word arrayMul2 = 0x5D588B65u;
57 static const Word mask = 0x9908B0DFu;
58 static const Word loMask = (1u << 31) - 1;
59 static const Word hiMask = ~loMask;
62 static Word tempering(Word rnd) {
64 rnd ^= (rnd << 7) & 0x9D2C5680u;
65 rnd ^= (rnd << 15) & 0xEFC60000u;
72 template <typename _Word>
73 struct RandomTraits<_Word, 64> {
76 static const int bits = 64;
78 static const int length = 312;
79 static const int shift = 156;
81 static const Word mul = (Word)0x5851F42Du << 32 | (Word)0x4C957F2Du;
82 static const Word arrayInit = (Word)0x00000000u << 32 |(Word)0x012BD6AAu;
83 static const Word arrayMul1 = (Word)0x369DEA0Fu << 32 |(Word)0x31A53F85u;
84 static const Word arrayMul2 = (Word)0x27BB2EE6u << 32 |(Word)0x87B0B0FDu;
86 static const Word mask = (Word)0xB5026F5Au << 32 | (Word)0xA96619E9u;
87 static const Word loMask = ((Word)1u << 31) - 1;
88 static const Word hiMask = ~loMask;
90 static Word tempering(Word rnd) {
91 rnd ^= (rnd >> 29) & ((Word)0x55555555u << 32 | (Word)0x55555555u);
92 rnd ^= (rnd << 17) & ((Word)0x71D67FFFu << 32 | (Word)0xEDA60000u);
93 rnd ^= (rnd << 37) & ((Word)0xFFF7EEE0u << 32 | (Word)0x00000000u);
100 template <typename _Word>
108 static const int bits = RandomTraits<Word>::bits;
110 static const int length = RandomTraits<Word>::length;
111 static const int shift = RandomTraits<Word>::shift;
116 static const Word seedArray[4] = {
117 0x12345u, 0x23456u, 0x34567u, 0x45678u
120 initState(seedArray, seedArray + 4);
123 void initState(Word seed) {
125 static const Word mul = RandomTraits<Word>::mul;
129 Word *curr = state + length - 1;
130 curr[0] = seed; --curr;
131 for (int i = 1; i < length; ++i) {
132 curr[0] = (mul * ( curr[1] ^ (curr[1] >> (bits - 2)) ) + i);
137 template <typename Iterator>
138 void initState(Iterator begin, Iterator end) {
140 static const Word init = RandomTraits<Word>::arrayInit;
141 static const Word mul1 = RandomTraits<Word>::arrayMul1;
142 static const Word mul2 = RandomTraits<Word>::arrayMul2;
145 Word *curr = state + length - 1; --curr;
146 Iterator it = begin; int cnt = 0;
151 num = length > end - begin ? length : end - begin;
153 curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul1))
160 curr = state + length - 1; curr[0] = state[0];
165 num = length - 1; cnt = length - (curr - state) - 1;
167 curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul2))
171 curr = state + length - 1; curr[0] = state[0]; --curr;
176 state[length - 1] = (Word)1 << (bits - 1);
179 void copyState(const RandomCore& other) {
180 std::copy(other.state, other.state + length, state);
181 current = state + (other.current - other.state);
185 if (current == state) fillState();
188 return RandomTraits<Word>::tempering(rnd);
195 static const Word mask[2] = { 0x0ul, RandomTraits<Word>::mask };
196 static const Word loMask = RandomTraits<Word>::loMask;
197 static const Word hiMask = RandomTraits<Word>::hiMask;
199 current = state + length;
201 register Word *curr = state + length - 1;
204 num = length - shift;
206 curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
207 curr[- shift] ^ mask[curr[-1] & 1ul];
212 curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
213 curr[length - shift] ^ mask[curr[-1] & 1ul];
216 curr[0] = (((curr[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^
217 curr[length - shift] ^ mask[curr[length - 1] & 1ul];
228 template <typename Result,
229 int shift = (std::numeric_limits<Result>::digits + 1) / 2>
231 static Result mask(const Result& result) {
232 return Masker<Result, (shift + 1) / 2>::
233 mask((Result)(result | (result >> shift)));
237 template <typename Result>
238 struct Masker<Result, 1> {
239 static Result mask(const Result& result) {
240 return (Result)(result | (result >> 1));
244 template <typename Result, typename Word,
245 int rest = std::numeric_limits<Result>::digits, int shift = 0,
246 bool last = rest <= std::numeric_limits<Word>::digits>
247 struct IntConversion {
248 static const int bits = std::numeric_limits<Word>::digits;
250 static Result convert(RandomCore<Word>& rnd) {
251 return (Result)(rnd() >> (bits - rest)) << shift;
256 template <typename Result, typename Word, int rest, int shift>
257 struct IntConversion<Result, Word, rest, shift, false> {
258 static const int bits = std::numeric_limits<Word>::digits;
260 static Result convert(RandomCore<Word>& rnd) {
261 return ((Result)rnd() << shift) |
262 IntConversion<Result, Word, rest - bits, shift + bits>::convert(rnd);
267 template <typename Result, typename Word,
268 bool one_word = std::numeric_limits<Word>::digits <
269 std::numeric_limits<Result>::digits>
271 static Result map(RandomCore<Word>& rnd, const Result& bound) {
272 Word max = (Word)(bound - 1);
273 Result mask = Masker<Result>::mask(bound - 1);
276 num = IntConversion<Result, Word>::convert(rnd) & mask;
282 template <typename Result, typename Word>
283 struct Mapping<Result, Word, false> {
284 static Result map(RandomCore<Word>& rnd, const Result& bound) {
285 Word max = (Word)(bound - 1);
286 Word mask = Masker<Word, (std::numeric_limits<Result>::digits + 1) / 2>
296 template <typename Result, int exp, bool pos = (exp >= 0)>
297 struct ShiftMultiplier {
298 static const Result multiplier() {
299 Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
301 if ((exp & 1) == 1) res *= (Result)2.0;
306 template <typename Result, int exp>
307 struct ShiftMultiplier<Result, exp, false> {
308 static const Result multiplier() {
309 Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
311 if ((exp & 1) == 1) res *= (Result)0.5;
316 template <typename Result>
317 struct ShiftMultiplier<Result, 0, true> {
318 static const Result multiplier() {
323 template <typename Result>
324 struct ShiftMultiplier<Result, -20, true> {
325 static const Result multiplier() {
326 return (Result)(1.0/1048576.0);
330 template <typename Result>
331 struct ShiftMultiplier<Result, -32, true> {
332 static const Result multiplier() {
333 return (Result)(1.0/424967296.0);
337 template <typename Result>
338 struct ShiftMultiplier<Result, -53, true> {
339 static const Result multiplier() {
340 return (Result)(1.0/9007199254740992.0);
344 template <typename Result>
345 struct ShiftMultiplier<Result, -64, true> {
346 static const Result multiplier() {
347 return (Result)(1.0/18446744073709551616.0);
351 template <typename Result, int exp>
353 static Result shift(const Result& result) {
354 return result * ShiftMultiplier<Result, exp>::multiplier();
358 template <typename Result, typename Word,
359 int rest = std::numeric_limits<Result>::digits, int shift = 0,
360 bool last = rest <= std::numeric_limits<Word>::digits>
361 struct RealConversion{
362 static const int bits = std::numeric_limits<Word>::digits;
364 static Result convert(RandomCore<Word>& rnd) {
365 return Shifting<Result, - shift - rest>::
366 shift((Result)(rnd() >> (bits - rest)));
370 template <typename Result, typename Word, int rest, int shift>
371 struct RealConversion<Result, Word, rest, shift, false> {
372 static const int bits = std::numeric_limits<Word>::digits;
374 static Result convert(RandomCore<Word>& rnd) {
375 return Shifting<Result, - shift - bits>::shift((Result)rnd()) +
376 RealConversion<Result, Word, rest-bits, shift + bits>::convert(rnd);
380 template <typename Result, typename Word>
383 template <typename Iterator>
384 static void init(RandomCore<Word>& rnd, Iterator begin, Iterator end) {
385 std::vector<Word> ws;
386 for (Iterator it = begin; it != end; ++it) {
387 ws.push_back((Word)*it);
389 rnd.initState(ws.begin(), ws.end());
392 static void init(RandomCore<Word>& rnd, Result seed) {
397 template <typename Word>
398 struct BoolConversion {
399 static bool convert(RandomCore<Word>& rnd) {
400 return (rnd() & 1) == 1;
408 /// \brief Mersenne Twister random number generator
410 /// The Mersenne Twister is a twisted generalized feedback
411 /// shift-register generator of Matsumoto and Nishimura. The period
412 /// of this generator is \f$ 2^{19937} - 1 \f$ and it is
413 /// equi-distributed in 623 dimensions for 32-bit numbers. The time
414 /// performance of this generator is comparable to the commonly used
417 /// This implementation is specialized for both 32-bit and 64-bit
418 /// architectures. The generators differ sligthly in the
419 /// initialization and generation phase so they produce two
420 /// completly different sequences.
422 /// The generator gives back random numbers of serveral types. To
423 /// get a random number from a range of a floating point type you
424 /// can use one form of the \c operator() or the \c real() member
425 /// function. If you want to get random number from the {0, 1, ...,
426 /// n-1} integer range use the \c operator[] or the \c integer()
427 /// method. And to get random number from the whole range of an
428 /// integer type you can use the argumentless \c integer() or \c
429 /// uinteger() functions. After all you can get random bool with
430 /// equal chance of true and false or given probability of true
431 /// result with the \c boolean() member functions.
434 /// // The commented code is identical to the other
435 /// double a = rnd(); // [0.0, 1.0)
436 /// // double a = rnd.real(); // [0.0, 1.0)
437 /// double b = rnd(100.0); // [0.0, 100.0)
438 /// // double b = rnd.real(100.0); // [0.0, 100.0)
439 /// double c = rnd(1.0, 2.0); // [1.0, 2.0)
440 /// // double c = rnd.real(1.0, 2.0); // [1.0, 2.0)
441 /// int d = rnd[100000]; // 0..99999
442 /// // int d = rnd.integer(100000); // 0..99999
443 /// int e = rnd[6] + 1; // 1..6
444 /// // int e = rnd.integer(1, 1 + 6); // 1..6
445 /// int b = rnd.uinteger<int>(); // 0 .. 2^31 - 1
446 /// int c = rnd.integer<int>(); // - 2^31 .. 2^31 - 1
447 /// bool g = rnd.boolean(); // P(g = true) = 0.5
448 /// bool h = rnd.boolean(0.8); // P(h = true) = 0.8
451 /// The lemon provides a global instance of the random number
452 /// generator which name is \ref lemon::rnd "rnd". Usually it is a
453 /// good programming convenience to use this global generator to get
456 /// \author Balazs Dezso
461 typedef unsigned long Word;
463 _random_bits::RandomCore<Word> core;
467 /// \brief Constructor
469 /// Constructor with constant seeding.
470 Random() { core.initState(); }
472 /// \brief Constructor
474 /// Constructor with seed. The current number type will be converted
475 /// to the architecture word type.
476 template <typename Number>
477 Random(Number seed) {
478 _random_bits::Initializer<Number, Word>::init(core, seed);
481 /// \brief Constructor
483 /// Constructor with array seeding. The given range should contain
484 /// any number type and the numbers will be converted to the
485 /// architecture word type.
486 template <typename Iterator>
487 Random(Iterator begin, Iterator end) {
488 typedef typename std::iterator_traits<Iterator>::value_type Number;
489 _random_bits::Initializer<Number, Word>::init(core, begin, end);
492 /// \brief Copy constructor
494 /// Copy constructor. The generated sequence will be identical to
495 /// the other sequence. It can be used to save the current state
496 /// of the generator and later use it to generate the same
498 Random(const Random& other) {
499 core.copyState(other.core);
502 /// \brief Assign operator
504 /// Assign operator. The generated sequence will be identical to
505 /// the other sequence. It can be used to save the current state
506 /// of the generator and later use it to generate the same
508 Random& operator=(const Random& other) {
509 if (&other != this) {
510 core.copyState(other.core);
515 /// \brief Returns a random real number from the range [0, 1)
517 /// It returns a random real number from the range [0, 1). The
518 /// default Number type is double.
519 template <typename Number>
521 return _random_bits::RealConversion<Number, Word>::convert(core);
525 return real<double>();
528 /// \brief Returns a random real number the range [0, b)
530 /// It returns a random real number from the range [0, b).
531 template <typename Number>
532 Number real(Number b) {
533 return real<Number>() * b;
536 /// \brief Returns a random real number from the range [a, b)
538 /// It returns a random real number from the range [a, b).
539 template <typename Number>
540 Number real(Number a, Number b) {
541 return real<Number>() * (b - a) + a;
544 /// \brief Returns a random real number from the range [0, 1)
546 /// It returns a random double from the range [0, 1).
547 double operator()() {
548 return real<double>();
551 /// \brief Returns a random real number from the range [0, b)
553 /// It returns a random real number from the range [0, b).
554 template <typename Number>
555 Number operator()(Number b) {
556 return real<Number>() * b;
559 /// \brief Returns a random real number from the range [a, b)
561 /// It returns a random real number from the range [a, b).
562 template <typename Number>
563 Number operator()(Number a, Number b) {
564 return real<Number>() * (b - a) + a;
567 /// \brief Returns a random integer from a range
569 /// It returns a random integer from the range {0, 1, ..., b - 1}.
570 template <typename Number>
571 Number integer(Number b) {
572 return _random_bits::Mapping<Number, Word>::map(core, b);
575 /// \brief Returns a random integer from a range
577 /// It returns a random integer from the range {a, a + 1, ..., b - 1}.
578 template <typename Number>
579 Number integer(Number a, Number b) {
580 return _random_bits::Mapping<Number, Word>::map(core, b - a) + a;
583 /// \brief Returns a random integer from a range
585 /// It returns a random integer from the range {0, 1, ..., b - 1}.
586 template <typename Number>
587 Number operator[](Number b) {
588 return _random_bits::Mapping<Number, Word>::map(core, b);
591 /// \brief Returns a random non-negative integer
593 /// It returns a random non-negative integer uniformly from the
594 /// whole range of the current \c Number type. The default result
595 /// type of this function is unsigned int.
596 template <typename Number>
598 return _random_bits::IntConversion<Number, Word>::convert(core);
601 unsigned int uinteger() {
602 return uinteger<unsigned int>();
605 /// \brief Returns a random integer
607 /// It returns a random integer uniformly from the whole range of
608 /// the current \c Number type. The default result type of this
610 template <typename Number>
612 static const int nb = std::numeric_limits<Number>::digits +
613 (std::numeric_limits<Number>::is_signed ? 1 : 0);
614 return _random_bits::IntConversion<Number, Word, nb>::convert(core);
618 return integer<int>();
621 /// \brief Returns a random bool
623 /// It returns a random bool
625 return _random_bits::BoolConversion<Word>::convert(core);
628 /// \brief Returns a random bool
630 /// It returns a random bool with given probability of true result
631 bool boolean(double p) {
632 return operator()() < p;