我使用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);
}
Run Code Online (Sandbox Code Playgroud)
有人可以知道为什么会发生这种情况,我该如何改进它以使其更随机?
jas*_*son 21
所以这就是生日悖论*.当你从50000中抽取300个数字时,它们中至少有两个相等的概率是
p(300) = 1 - exp(-300 * 300 / (2 * 50000))
= 0.59
Run Code Online (Sandbox Code Playgroud)
(我可以算出确切的概率,但我很懒!)
所以,你很可能会发生碰撞.顺序是更可能(现在你不需要的碰撞,你只需要n - 1和n或n和n + 1被打了一些n).
随机是善变的.
*:如果你不熟悉它,它说如果你在一个房间里有二十三个人,那么房间里至少有两个人共享同一个生日的可能性更大.
!:好的,我把它解决了.这是0.5953830515549951746819986449 ....
Bah*_*mut 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));
}
Run Code Online (Sandbox Code Playgroud)
我只在一千个电话中得到3个不同的数字,大约300次!不是那么随意......
在构造函数中设置种子会new Random(0)返回一组数字修复.
例如,new Random(0).Next(50) 永远幸福!如果你不信任我,请自己尝试一下;
我们对"真实"随机数的需求是变化的种子,这与时间无关.
我正在使用更改值的Hashcode:
例如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));
}
Run Code Online (Sandbox Code Playgroud)
或(为了更好的表现):
for(int i = 0; i < 1000; i++)
{
int val = Guid.NewGuid().GetHashCode() % 50001;
val = val > 0 ? val : -val;
Console.WriteLine(val);
}
Run Code Online (Sandbox Code Playgroud)
PS:Next(max)方法的最大值总是max - 1;
- > ran.Next(11)可以返回0,1,2,...,8,9,10.不是11!
迎接Bahamut =)
Dan*_*Tao 11
作为你偶然看到重复的原因的解释,杰森的回答是正确的.
如果你想要的是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);
Run Code Online (Sandbox Code Playgroud)