【问题标题】:Randomizing numbers does not work [duplicate]随机数字不起作用[重复]
【发布时间】:2011-07-28 17:54:40
【问题描述】:

可能的重复:
Why does it appear that my random number generator isn't random in C#?
Random number generator not working the way I had planned (C#)

你好,
我使用这个函数(在课堂上)来随机化数字:

private int RandomNumber(int min, int max)
{
    Random random = new Random();
    return random.Next(min, max);
}

public void Init()
{
    x = RandomNumber(0,500);
}

但是,如果我稍后调用多个对象来执行此操作:

Obj[] obj = new Obj[64];
for( int i = 0 ; i < 64 ; i++ )
{
    obj[i] = new Obj();
}
...
for( int i = 0 ; i < 64 ; i++ )
{
    obj[i].Init();
}

那么每个对象都有完全相同的“x”值。

这里有什么问题?

【问题讨论】:

标签: c#


【解决方案1】:

Random 应该只创建一次,Next 在单个实例上调用。

这是因为默认情况下Random 是按当前时间播种的 - 如果在紧密循环中调用(就像您所做的那样),种子将是相同的,并且伪随机算法的结果将大部分相同。

如果你把你的代码改成这样,你会得到更好的结果:

private static Random random = new Random();
private int RandomNumber(int min, int max)
{
    return random.Next(min, max);
}

但是,这不是线程安全的。如果您尝试在多线程应用程序中使用它,预计会出现问题。对于线程安全版本,我建议阅读并关注 Jon Skeet 的 this 文章。

【讨论】:

  • 使用纯静态变量来存储对Random 实例的引用不是一个好主意,因为它不是线程安全的。有关详细信息,请参阅csharpindepth.com/Articles/Chapter12/Random.aspx
  • 没问题。不幸的是,这在 .NET 中是一个非常讨厌的“陷阱”:(
【解决方案2】:

Random 类是一个伪随机数生成器。它需要一个唯一的种子值来产生唯一的数字。

默认种子值基于当前时间,这将是相同的,因为您的所有对象都是在瞬间创建的。

将 Random 实例设为静态或为每个实例找到唯一的种子值以解决问题。

【讨论】:

  • 查看我对 Oded 答案的评论 - 使用简单的静态变量是一种糟糕 解决方案。
猜你喜欢
  • 2023-03-27
  • 2018-02-05
  • 2017-06-17
  • 2021-03-29
  • 2011-09-04
  • 1970-01-01
  • 2023-03-09
  • 2014-05-12
  • 2011-01-19
相关资源
最近更新 更多