Mersenne Twister随机算法我怎样才能播种init_genrand,随机数总是相同的C#

时间:2013-01-12 17:43:48

标签: c# random random-sample mersenne-twister

我正在使用MT19937的C程序,初始化改进了2002/1 / 26.由Takuji Nishimura和Makoto Matsumoto编写。取自Codeproject link 在复制源文件并运行随机函数后,我总是得到相同的数字。 在提到的文件说明中

  

使用前,使用init_genrand(种子)初始化状态      或init_by_array(init_key,key_length)。

我如何启动种子,

构造函数以这种方式启动它,这导致随机数始终相同:

            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);

2 个答案:

答案 0 :(得分:2)

要为随机生成器播种,您需要为每次执行添加不同的数字。通常使用基于系统时钟的数字,例如:

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

或:

ulong[] init = { (ulong)DateTime.UtcNow.Ticks };
ulong length = init.Length;
init_by_array(init, length);

答案 1 :(得分:1)

这似乎对我有用:

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);

我的一位朋友在相似的代码上进行了大约一百万次的仿真(不是开玩笑),并在最小/最大范围内获得了良好的数字分布。

编辑:不确定您使用的是哪个版本,但我的实现有这个重载的构造函数:

/// <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;
    }
}