12

人们通常会问为什么他们在使用 . 时总是得到相同的数字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);

如您所见,我在这里有点缺乏创造力,需要您的帮助。谢谢。

4

3 回答 3

4

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

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

查看 Jon Skeet 博客中的完整源代码。

于 2012-12-21T22:38:12.827 回答
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();
于 2012-12-21T22:34:18.517 回答
1

You could use a cryptographic generator to create your seeds e.g.

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

Of course, if you just need ints then you could use RNGCryptoServiceProvider to generate them directly, although System.Random is probably faster.

于 2012-12-21T22:55:33.307 回答