-2

在 C# ConsoleApp 中,我创建了一个方法,该方法将根据您给它的可能性参数返回 true 或 false,所以如果您给它 5,那么您将得到 50%,对于 false,给9,你有 90% 的机会是真的,10% 的机会是假的。就是这样:(我写这篇文章是作为一个教程,我在那个 balls-ThatGotNumbers-inside-a-box 中解释它有点清楚,因此变量 BallNumber 的名称)

static public bool TrueOrFalse(int possiblity)
{
      Random rand = new Random();
      int BallNumber = rand.Next(0, 10); // BallNumber values are from the interval: [0, 10[  (0, 1, 2, ....9)
      if (possiblity <= 0)
        return false;
      if (possiblity == 1)
        return (BallNumber == 0); // any number you like.
      if (possiblity == 2)
        return (BallNumber == 0 || BallNumber == 1); // any two numbers, cuz there's a 20% chance that you might get a ball from the box that has either number n OR m.
      if (possiblity == 3)
        return (BallNumber == 0 || BallNumber == 1 || BallNumber == 2); // any three numbers ... etc you got the point.
      if (possiblity == 4)
        return (BallNumber == 0 || BallNumber == 1 || BallNumber == 2 || BallNumber == 3);
      if (possiblity == 5)
        return (BallNumber == 0 || BallNumber == 1 || BallNumber == 2 || BallNumber == 3 || BallNumber == 4);
      if (possiblity == 6)
        return (BallNumber == 0 || BallNumber == 1 || BallNumber == 2 || BallNumber == 3 || BallNumber == 4 || BallNumber == 5);
      if (possiblity == 7)
        return (BallNumber == 0 || BallNumber == 1 || BallNumber == 2 || BallNumber == 3 || BallNumber == 4 || BallNumber == 5 || BallNumber == 6);
      if (possiblity == 8)
        return (BallNumber == 0 || BallNumber == 1 || BallNumber == 2 || BallNumber == 3 || BallNumber == 4 || BallNumber == 5 || BallNumber == 6 || BallNumber == 7);
      if (possiblity == 9)
        return (BallNumber == 0 || BallNumber == 1 || BallNumber == 2 || BallNumber == 3 || BallNumber == 4 || BallNumber == 5 || BallNumber == 6 || BallNumber == 7 || BallNumber == 8);

      return true; // if you give it a number higher than 10, it will return true ..
}

现在该方法运行良好,但我想证明它。所以我想出了这个主意:

int TruePossiblity = 0, FalsePossiblity = 0;
for (int i = 0; i < 100; i++)
{
  bool _TRUE = TrueOrFalse(5);
  if (_TRUE) TruePossiblity  += 1;
  else FalsePossiblity  += 1;
}
Console.WriteLine(x);
Console.WriteLine(y);

现在,应该打印的是:

50
50

问题是它要么打印:

100
0

或者

0
100

所以,我调试了它,一步一步地走过它,惊讶地发现它最终打印出来了:

50
50

System.Threading.Thread.Sleep(1); 我在分配变量后立即插入_TRUE 我得到了更好的结果,但不是那么好,我增加的时间越多,我得到的结果就越好(更接近它应该打印的结果,即 50,50)。当我使用 200 毫秒时,我实际上得到了所需的结果 50,50 !

现在,只有一个线程在运行,它是主线程,所以线程之间没有竞争,所以事情可能会搞砸并产生那些不需要的结果。

怎么回事?有人可以解释一下吗?我可以避免使用 Sleep 吗?

感谢您提供的任何提示。

4

1 回答 1

4

Random当前时间为实例播种。因为循环执行太快,它使用相同的时间,因此您总是得到相同的“随机”值。

Random您应该将其作为参数传递或在类中使用成员变量,而不是在方法本身中创建。

例如:

static Random rand = new Random();

static public bool TrueOrFalse(int possiblity)
{
      int BallNumber = rand.Next(0, 10); // BallNumber values are from the interval: [0, 10[  (0, 1, 2, ....9)
      // ...

      return true; // if you give it a number higher than 10, it will return true ..
}

来自MSDN 的评论:

为不同的 Random 对象提供相同的种子值会导致每个实例产生相同的随机数序列

如果您的应用程序需要不同的随机数序列,请使用不同的种子值重复调用此构造函数。产生唯一种子值的一种方法是使其具有时间依赖性。例如,从系统时钟派生种子值。但是,系统时钟可能没有足够的分辨率来为这个构造函数的不同调用提供不同的种子值。这导致随机数生成器生成相同的伪随机数序列,如以下示例中的前两个 Random 对象所示。为防止这种情况,请应用一种算法来区分每次调用中的种子值,或调用 Thread.Sleep 方法以确保为每个构造函数提供不同的种子值。

于 2012-08-18T22:43:20.687 回答