为“随机”的不同实例创建不同的种子

时间:2012-12-21 22:29:18

标签: c# .net random

人们通常会问为什么在使用Random时他们总是会得到相同的数字。在他们的情况下,他们每次都会无意间创建Random的新实例(而不是仅使用一个实例),这当然会导致相同的数字。但就我而言,我确实需要多个Random的实例,这些实例会返回不同的数字流。

在我看来,使用硬编码种子是一个坏主意,因为重新启动程序后会一次又一次地获得相同的值。那怎么样:

int seed1 = (int)DateTime.Now.Ticks - 13489565;
int seed2 = (int)DateTime.Now.Ticks - 5564;

我知道这看起来很傻和天真,但每次重启后都会避免相同的值,两个种子都应该不同。或者也许

Random helper = new Random();
int seed1 = helper.Next(1, int.MaxValue);
int seed2 = helper.Next(1, int.MaxValue);

正如你所看到的,我在这里有点无创,需要你的帮助。感谢。

3 个答案:

答案 0 :(得分:4)

我会用你的第二种方法:

int randomCount = 10;
Random seeder = new Random();
var randoms = Enumerable.Range(0, randomCount)
    .Select(i => new Random(seeder.Next()))
    .ToList();

这使用linq创建10个不同种子的Random实例的列表。因此,您需要using System.Linq;才能访问Select扩展程序。

您还可以将播种机重新用作您的一个实例:

int randomCount = 10;
Random seeder = new Random();
var randoms = Enumerable.Range(0, randomCount - 1)
    .Select(i => new Random(seeder.Next()))
    .Concat(new [] { seeder })
    .ToList();

答案 1 :(得分:4)

Jon Skeet建议使用辅助Random对象和锁来创建Random对象工厂。例如:

    public static Random NewRandom() 
    { 
        lock (globalLock) 
        { 
            return new Random(secondaryRandom.Next()); 
        } 
    } 

Take a look at the complete source code in Jon Skeet's blog.

答案 2 :(得分:1)

您可以使用加密生成器来创建种子,例如

public static Random CreateRandom()
{
    using (var rng = new System.Security.Cryptography.RNGCryptoServiceProvider())
    {
        byte[] bytes = new byte[4];
        rng.GetNonZeroBytes(bytes);
        int seed = BitConverter.ToInt32(bytes, 0);
        return new Random(seed);
    }
}

当然,如果您只需要整数,那么您可以使用RNGCryptoServiceProvider直接生成它们,但System.Random可能更快。