Compilation warning resolved.
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 template <typename Iterator>
393 static void init(RandomCore<Word>& rnd, Result seed) {
398 template <typename Word>
399 struct BoolConversion {
400 static bool convert(RandomCore<Word>& rnd) {
401 return (rnd() & 1) == 1;
409 /// \brief Mersenne Twister random number generator
411 /// The Mersenne Twister is a twisted generalized feedback
412 /// shift-register generator of Matsumoto and Nishimura. The period
413 /// of this generator is \f$ 2^{19937} - 1 \f$ and it is
414 /// equi-distributed in 623 dimensions for 32-bit numbers. The time
415 /// performance of this generator is comparable to the commonly used
418 /// This implementation is specialized for both 32-bit and 64-bit
419 /// architectures. The generators differ sligthly in the
420 /// initialization and generation phase so they produce two
421 /// completly different sequences.
423 /// The generator gives back random numbers of serveral types. To
424 /// get a random number from a range of a floating point type you
425 /// can use one form of the \c operator() or the \c real() member
426 /// function. If you want to get random number from the {0, 1, ...,
427 /// n-1} integer range use the \c operator[] or the \c integer()
428 /// method. And to get random number from the whole range of an
429 /// integer type you can use the argumentless \c integer() or \c
430 /// uinteger() functions. After all you can get random bool with
431 /// equal chance of true and false or given probability of true
432 /// result with the \c boolean() member functions.
435 /// // The commented code is identical to the other
436 /// double a = rnd(); // [0.0, 1.0)
437 /// // double a = rnd.real(); // [0.0, 1.0)
438 /// double b = rnd(100.0); // [0.0, 100.0)
439 /// // double b = rnd.real(100.0); // [0.0, 100.0)
440 /// double c = rnd(1.0, 2.0); // [1.0, 2.0)
441 /// // double c = rnd.real(1.0, 2.0); // [1.0, 2.0)
442 /// int d = rnd[100000]; // 0..99999
443 /// // int d = rnd.integer(100000); // 0..99999
444 /// int e = rnd[6] + 1; // 1..6
445 /// // int e = rnd.integer(1, 1 + 6); // 1..6
446 /// int b = rnd.uinteger<int>(); // 0 .. 2^31 - 1
447 /// int c = rnd.integer<int>(); // - 2^31 .. 2^31 - 1
448 /// bool g = rnd.boolean(); // P(g = true) = 0.5
449 /// bool h = rnd.boolean(0.8); // P(h = true) = 0.8
452 /// The lemon provides a global instance of the random number
453 /// generator which name is \ref lemon::rnd "rnd". Usually it is a
454 /// good programming convenience to use this global generator to get
457 /// \author Balazs Dezso
462 typedef unsigned long Word;
464 _random_bits::RandomCore<Word> core;
468 /// \brief Constructor
470 /// Constructor with constant seeding.
471 Random() { core.initState(); }
473 /// \brief Constructor
475 /// Constructor with seed. The current number type will be converted
476 /// to the architecture word type.
477 template <typename Number>
478 Random(Number seed) {
479 _random_bits::Initializer<Number, Word>::init(core, seed);
482 /// \brief Constructor
484 /// Constructor with array seeding. The given range should contain
485 /// any number type and the numbers will be converted to the
486 /// architecture word type.
487 template <typename Iterator>
488 Random(Iterator begin, Iterator end) {
489 typedef typename std::iterator_traits<Iterator>::value_type Number;
490 _random_bits::Initializer<Number, Word>::init(core, begin, end);
493 /// \brief Copy constructor
495 /// Copy constructor. The generated sequence will be identical to
496 /// the other sequence. It can be used to save the current state
497 /// of the generator and later use it to generate the same
499 Random(const Random& other) {
500 core.copyState(other.core);
503 /// \brief Assign operator
505 /// Assign operator. The generated sequence will be identical to
506 /// the other sequence. It can be used to save the current state
507 /// of the generator and later use it to generate the same
509 Random& operator=(const Random& other) {
510 if (&other != this) {
511 core.copyState(other.core);
516 /// \brief Returns a random real number
518 /// It returns a random real number from the range [0, 1). The
519 /// default Number type is double.
520 template <typename Number>
522 return _random_bits::RealConversion<Number, Word>::convert(core);
526 return real<double>();
529 /// \brief Returns a random real number
531 /// It returns a random real number from the range [0, b).
532 template <typename Number>
533 Number real(Number b) {
534 return real<Number>() * b;
537 /// \brief Returns a random real number
539 /// It returns a random real number from the range [a, b).
540 template <typename Number>
541 Number real(Number a, Number b) {
542 return real<Number>() * (b - a) + a;
545 /// \brief Returns a random real number
547 /// It returns a random double from the range [0, 1).
548 double operator()() {
549 return real<double>();
552 /// \brief Returns a random real number
554 /// It returns a random real number from the range [0, b).
555 template <typename Number>
556 Number operator()(Number b) {
557 return real<Number>() * b;
560 /// \brief Returns a random real number
562 /// It returns a random real number from the range [a, b).
563 template <typename Number>
564 Number operator()(Number a, Number b) {
565 return real<Number>() * (b - a) + a;
568 /// \brief Returns a random integer from a range
570 /// It returns a random integer from the range {0, 1, ..., b - 1}.
571 template <typename Number>
572 Number integer(Number b) {
573 return _random_bits::Mapping<Number, Word>::map(core, b);
576 /// \brief Returns a random integer from a range
578 /// It returns a random integer from the range {a, a + 1, ..., b - 1}.
579 template <typename Number>
580 Number integer(Number a, Number b) {
581 return _random_bits::Mapping<Number, Word>::map(core, b - a) + a;
584 /// \brief Returns a random integer from a range
586 /// It returns a random integer from the range {0, 1, ..., b - 1}.
587 template <typename Number>
588 Number operator[](Number b) {
589 return _random_bits::Mapping<Number, Word>::map(core, b);
592 /// \brief Returns a random non-negative integer
594 /// It returns a random non-negative integer uniformly from the
595 /// whole range of the current \c Number type. The default result
596 /// type of this function is unsigned int.
597 template <typename Number>
599 return _random_bits::IntConversion<Number, Word>::convert(core);
602 unsigned int uinteger() {
603 return uinteger<unsigned int>();
606 /// \brief Returns a random integer
608 /// It returns a random integer uniformly from the whole range of
609 /// the current \c Number type. The default result type of this
611 template <typename Number>
613 static const int nb = std::numeric_limits<Number>::digits +
614 (std::numeric_limits<Number>::is_signed ? 1 : 0);
615 return _random_bits::IntConversion<Number, Word, nb>::convert(core);
619 return integer<int>();
622 /// \brief Returns a random bool
624 /// It returns a random bool
626 return _random_bits::BoolConversion<Word>::convert(core);
629 /// \brief Returns a random bool
631 /// It returns a random bool with given probability of true result
632 bool boolean(double p) {
633 return operator()() < p;