【问题标题】:Random.Next returns always the same values [duplicate]Random.Next 总是返回相同的值[重复]
【发布时间】:2010-12-11 21:52:12
【问题描述】:

这真的很奇怪,我不明白为什么会这样。在 foreach 循环中,我正在遍历 A 类集合,并且对于每个类,我调用 Count() 方法,其中 r1r2 数字是从范围 [-1,1] 生成的。问题是Random.Next 为每个实例返回相同的“随机”数字。当第一个实例的结果为 0 和 -1 时,后续实例将返回相同的结果。拜托,你能告诉我为什么会这样吗?此外,我无法在每个 A 类实例中得到不同的结果。这是代码:

class a
{
 Random rnd = new Random();
 private void Count()
 {
  int r1 = rnd.Next(-1, 1);
  int r2 = rnd.Next(-1, 1);
 }
}
class b
{
 List<a> listofA=new list<a>();
 foreach (a ACLASS in listofA)
 {
  ACLASS.Count();
 }
}

【问题讨论】:

    标签: c# math random


    【解决方案1】:

    问题是您创建 Random 类的实例的时间太近了。

    当您创建 Random 对象时,它会使用来自系统时钟的值作为种子。如果您创建 Random 实例的时间太近,它们都将使用相同的随机序列播种。

    创建一个 Random 对象并在创建“a”类的实例时将其引用传递给构造函数,而不是为每个“a”实例创建一个 Random 对象。

    【讨论】:

    • 我也忘记了,以前我在为俱乐部制作 Bingo 纸箱时也遇到过同样的问题,当时,我使用了人类所知道的最糟糕的技巧:暂停线程 2女士。缺乏经验和疯狂......够疯狂的,我有一个类可以创建随机名称,并在所有内容之上添加一个静态随机声明。
    【解决方案2】:

    您为每个 A 实例包含一个随机实例。听起来他们都获得了相同的默认种子值。您可能希望为所有 A 实例创建一个静态随机数并重复使用它,或者为 A 构造函数中的 Random() 实例提供一个种子值。

    【讨论】:

      【解决方案3】:

      您正在创建Random 的新实例,它们非常靠近(您的循环非常紧凑),因此每个实例都有效地使用了相同的种子值。

      更好的方法是创建一个实例并将其传递给您的 Count 方法。

      你可能知道下一点,但为了完整起见,我将其包含在此处:

      MSDN 有这方面的详细信息,但基本上你的问题是你使用的 Random.Next 方法生成:

      大于或等于 minValue 且小于 maxValue 的 32 位有符号整数;即返回值的范围包括minValue,但不包括maxValue。如果 minValue 等于 maxValue,则返回 minValue。

      因此,您的调用将返回 -1 或 0。

      【讨论】:

        【解决方案4】:

        为类的所有实例使用单个静态随机数生成器。

        class a
        {
          private static Random rnd;
          static a() {
              rnd = new Random();
          }
          private void Count()
          {
            int r1 = rnd.Next(-1, 2);
            int r2 = rnd.Next(-1, 2);
          }
        }
        

        注意更改为您提供 -1,1 而不是 -1,0 范围内的数字

        【讨论】:

        • 我认为在这个范围内它也可以返回 1,而他们只想要 0 和 -1?
        • @Svante 编辑了问题以使间隔打开以匹配代码示例。最初的问题指定了一个封闭区间,尽管没有使用精确的语言。我认为代码不正确,我将恢复问题以指定封闭间隔。
        • @tvanfosson 你能告诉我为什么会这样吗?我不明白如何制作这种静力学会给你带来随机性。我知道它有效,但不知道为什么。他们在时间上仍然非常接近。谢谢。
        • @johnny 当它被创建为实例变量时,Random 的构造函数会快速连续执行两次。由于它使用当前时间作为种子,这可能导致两个随机数生成器使用相同的伪随机数序列,因此它们都在锁定步骤中返回相同的值。使用单个随机数生成器,在类的静态构造函数中初始化一次,从单个伪随机序列中返回不同的数字,给出您期望从随机数生成器获得的行为。
        猜你喜欢
        • 2013-04-17
        • 2011-07-12
        • 2013-12-23
        • 1970-01-01
        • 1970-01-01
        • 2019-10-22
        相关资源
        最近更新 更多