【问题标题】:Create different seeds for different instances of "Random"为“随机”的不同实例创建不同的种子
【发布时间】:2012-12-09 11:57:34
【问题描述】:

人们通常会问为什么他们在使用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);

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

【问题讨论】:

  • 需要创意吗?我看不出你的任何一种方法有任何问题。
  • 您对使用随机数为不同的随机数生成器创建种子的想法对我来说似乎很好。在我读完这篇文章之前,这是我要建议的。
  • 现在我想起来了,如果 PRNG 不是很聪明,那么可能第二种方法会出现问题
  • 我仍然想不出为什么你需要两个不同的随机生成器,而不是一个提供两个流的随机生成器......
  • 不,抱歉不准确。我只是不知道如何产生“强种子”。我的应用程序不需要在随机数方面非常精确,但我认为我的解决方案过于简单。

标签: c# .net random


【解决方案1】:

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】:

    我会使用你的第二种方法:

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

    【讨论】:

      【解决方案3】:

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

      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 可能更快。

      【讨论】:

        猜你喜欢
        • 2020-11-03
        • 2011-06-13
        • 1970-01-01
        • 2019-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-31
        相关资源
        最近更新 更多