0

I'm using A C-program for MT19937, with initialization improved 2002/1/26.Coded by Takuji Nishimura and Makoto Matsumoto. taken from Codeproject link when after copying the source files and ran the random functions, i always get the same numbers. In the file instructions mentioned

Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).

How can i init the seed,

the constructor initilized it this way, which cause the random numbers always be the same:

            ulong [] init = new ulong[4];
        init[0]= 0x123;
        init[1]= 0x234;
        init[2]= 0x345;
        init[3] =0x456;
        ulong length = 4;
        init_by_array(init, length);
Liad Livnat
  • 7,435
  • 16
  • 60
  • 98
  • 1
    Initialize it with a value that changes each time your start the program (like the current time). – Blender Jan 12 '13 at 17:48

2 Answers2

2

To seed a random generator you need a number that is different for each execution. Usually a number based on the system clock is used, for example:

init_genrand((ulong)DateTime.UtcNow.Ticks);

or:

ulong[] init = { (ulong)DateTime.UtcNow.Ticks };
ulong length = init.Length;
init_by_array(init, length);
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • the function init_genrand doesn't get any value as parameter i need to use init_by_array function to initilize it – Liad Livnat Jan 12 '13 at 18:15
  • @LiadLivnat: Ok, it looked like it did from your description. I added a version using an array above. – Guffa Jan 12 '13 at 18:20
1

This seems to work for me:

var rng = new RNGCryptoServiceProvider();
var buffer = new byte[4];

rng.GetBytes(buffer);
uint result = BitConverter.ToUInt32(buffer, 0);

var random = MersenneTwister(result).Next(min, max);

A friend of mine ran a simulation on similar code about a million times (not kidding) and got a good distribution of numbers across the min/max range.

EDIT: Not sure what version you're using, but the implementation I have has this overloaded constructor:

/// <summary>
/// Initializes a new instance of the <see cref="MersenneTwister"/> class.
/// </summary>
/// <param name="seed">The NONZERO seed.</param>
public MersenneTwister( uint seed )
{
    /* Setting initial seeds to mt[N] using the generator Line 25 of Table 1 in [KNUTH 1981, The Art of Computer Programming Vol. 2 (2nd Ed.), pp102] */
    mt[0] = seed & 0xffffffffU;
    for ( mti = 1; mti < N; ++mti )
    {
        mt[mti] = ( 69069 * mt[mti - 1] ) & 0xffffffffU;
    }
}
Tieson T.
  • 20,774
  • 6
  • 77
  • 92
  • 1
    It's just damn slow, since `RNGCryptoServiceProvider` has a large per-call overhead. When I was using `RNGCryptoServiceProvider` I requested 4KiB or so at a time, and then managed that buffer myself. – CodesInChaos Jan 12 '13 at 18:08
  • +1: @CodesInChaos True. My need was a once-in-a-while random index from an array of numbers, so speed wasn't an issue. Good point, though. – Tieson T. Jan 12 '13 at 18:10
  • Sorry but i want to use MersenneTwister and there is no constructor there that gets a parameter – Liad Livnat Jan 12 '13 at 18:16