随机不是随机的

时间:2011-02-01 04:09:57

标签: c# .net random

我使用Random来生成随机数序列。我只构造一次随机对象,然后在循环内生成随机值(其中300个)。问题是,一旦我获得所有值并对它们进行排序,我就会发现其中一些是相同的和/或顺序的:我生成的数字从0到50000。

这是我的剧本:

Random rnd = new Random();
for (int n=0; n < 300; n++)
{
    int RndNumber = rnd.Next(0, 50000);
    System.Threading.Thread.Sleep(3);
}

有人能够知道为什么会发生这种情况,我该如何改进这一点以使其更随机?

3 个答案:

答案 0 :(得分:21)

所以这就是生日悖论 * 。当您从50000中抽取300个数字时,其中至少两个相等的概率是

p(300) = 1 - exp(-300 * 300 / (2 * 50000))
       = 0.59

(我可以算出确切的概率,但我懒得。)

所以,你很可能会发生碰撞。顺序更有可能(现在你不需要碰撞,你只需要n - 1nnn + 1来点击某些{{1} })。

随机是善变的。

* :如果你不熟悉它,它会说如果你在一个房间里有二十三个人,那么房间里至少有两个人就更有可能分享同一个生日。

:好的,我把它解决了。这是0.5953830515549951746819986449 ....

答案 1 :(得分:12)

<强>研究

大家好,

如果使用不带参数new Random()的构造函数,则种子取决于当前的servertime。

  

Random():“使用时间依赖性初始化Random类的新实例”   http://msdn.microsoft.com/en-us/library/system.random.aspx

所以,如果我这样试试:

for(int i = 0; i < 1000; i++)
{
   Random ran = new Random();
   Console.WriteLine(ran.Next(50001));
}

我在一千个电话中只得到3个不同的数字约300次!不是那么随意......

在构造函数new Random(0)中设置种子会返回一组数字修复。

e.g。 new Random(0).Next(50) 永远!返回36.如果您不信任我,请自行尝试;

我们对“真实”随机数的需求是变化的种子,这与时间无关。

我正在使用更改值的Hashcode:

e.g。 Guid.NewGuid().GetHashCode()DateTime.Now.GetHashCode()


<强>结果:

Random ran = new Random(Guid.NewGuid().GetHashCode());
for(int i = 0; i < 1000; i++)
{       
   Console.WriteLine(ran.Next(50001));
}

或(为了更好的表现):

for(int i = 0; i < 1000; i++)
{
     int val = Guid.NewGuid().GetHashCode() % 50001;
     val = val > 0 ? val : -val;
     Console.WriteLine(val);
}

PS:Next(max)方法的最大值总是max - 1;

- &GT; ran.Next(11)可以返回0,1,2,...,8,9,10。不是11!

Greets Bahamut =)

答案 2 :(得分:11)

作为对为什么的解释,您偶尔会看到重复,Jason's answer就是正确的。

如果您想要的是300个不同的随机数,那么这样的事情呢?

static IEnumerable<int> GetRandoms(int min, int max)
{
    var rand = new Random();
    while (true)
    {
        yield return rand.Next(min, max);
    }
}

var distinctRandoms = GetRandoms(0, 50000).Distinct().Take(300);