C# 随机的不是那么随机的

C# 随机的不是那么随机的,c#,.net,random,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.Slee

我用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);
}
Random rnd=new Random();
对于(int n=0;n<300;n++)
{
int RndNumber=rnd.Next(0,50000);
系统.线程.线程.睡眠(3);
}

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

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

p(300) = 1 - exp(-300 * 300 / (2 * 50000))
       = 0.59
(我能算出确切的概率,但我很懒!)

因此,发生碰撞的可能性更大。Sequential的可能性更大(现在您不需要碰撞,只需要碰撞
n-1
n
n
n+1

随机是变化无常的

*当前位置如果你不熟悉它,它说如果一个房间里有23个人,那么房间里至少有两个人共享同一个生日的可能性更大

!:好的,我解决了。它是0.59538305155454951746819986449….

作为你为什么会看到偶尔的复制品的解释,是正确的

如果你想要的是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);
静态IEnumerable GetRandoms(int-min,int-max)
{
var rand=new Random();
while(true)
{
下一步收益率回报率(最小值、最大值);
}
}
var distinctRandoms=GetRandoms(0,50000).Distinct().Take(300);

研究:

Random ran = new Random(Guid.NewGuid().GetHashCode());
for(int i = 0; i < 1000; i++)
{       
   Console.WriteLine(ran.Next(50001));
}
如果使用不带参数的构造函数
new Random()
,则种子取决于当前服务器时间

Random():“使用依赖于时间的函数初始化Random类的新实例”

因此,如果我这样尝试:

for(int i = 0; i < 1000; i++)
{
   Random ran = new Random();
   Console.WriteLine(ran.Next(50001));
}
或(为了更好的性能):

for(int i=0;i<1000;i++)
{
int val=Guid.NewGuid().GetHashCode()%50001;
val=val>0?val:-val;
控制台写入线(val);
}
PS:下一个(max)-方法的最大值始终为max-1


->下一步(11)可以返回0,1,2,…,8,9,10。不是11

你需要明确如何定义“更随机”为什么要对随机数进行排序?这不是违背了生成随机数的目的吗?我不是数学家,但在我看来,在对300个介于0和50000之间的随机数进行排序后,至少有两个随机数不相等或不连续。为什么要对随机值进行排序?这只是为了测试它们的分布吗?这可能与数字的大小有关,您是否希望数字在10、110、210、310等范围内的间隔相等?这似乎不那么随机。是的,它给出了不同的数字,但它仍然有连接数,这是因为我相信生日悖论。这似乎满足了我需要做的事情。谢谢Dan Tao记住,通过强制区分,你实际上是在损害“随机性”——分布不再(伪)均匀。@bavaza:不确定该评论是针对我还是针对OP,但我认为OP实际上并不想要真正的随机性;否则他就不会问这个问题了。当然你是对的,消除重复会损害数据的随机性,就像排序一样。@Dan:它是针对OP和其他吸毒者的。我决定加上它,因为我经常发现人们倾向于滥用统计数据。无论如何,谢谢你的回答:-)。非常适合psuedo随机列表,谢谢DanTao
DateTime。现在。GetHashCode()
并不比默认的种子好多少。+1这对我来说是“随机”的:)当我试图生成2000个数字时,没有一堆数字。@code在你的右边。我不知道Random的默认构造函数是否使用DateTimes哈希代码或毫秒或其他什么,但它根本不是随机的,我喜欢它,一个非常简单和模块化的构造函数solution@Bahamut你意识到不是你的新种子价值决定了它吗,您将
Random
实例的初始化移出了循环,这是事实吗?当试验之间只有一个变量发生变化时,试验最有效。
for(int i = 0; i < 1000; i++)
{
     int val = Guid.NewGuid().GetHashCode() % 50001;
     val = val > 0 ? val : -val;
     Console.WriteLine(val);
}