C# 随机数概率

C# 随机数概率,c#,random,statistics,probability,C#,Random,Statistics,Probability,我尝试从例如4个数字中随机选择。我需要比较这两种算法的概率 一,# 二,# inta=random.Next(0,1000) 如果(a=250&&a=500&&a=750) 声明4 如果我认为它是一样的,我是对的吗?第一个代码中语句1的概率是1/4,第二个代码中语句1的概率是250/1000,所以也是1/4。但有人告诉我,当我使用更大范围的随机数时,比如在代码2中,统计上更准确。我做了一个项目,它多次重复这些代码,但我不确定它是否显示了一些结果。它们完全相同(除了第一个项目由于在if子句中使用

我尝试从例如4个数字中随机选择。我需要比较这两种算法的概率

一,#

二,#

inta=random.Next(0,1000)
如果(a<250)
声明1
如果(a>=250&&a<500)
声明2
如果(a>=500&&a<750)
声明3
如果(a>=750)
声明4

如果我认为它是一样的,我是对的吗?第一个代码中语句1的概率是1/4,第二个代码中语句1的概率是250/1000,所以也是1/4。但有人告诉我,当我使用更大范围的随机数时,比如在代码2中,统计上更准确。我做了一个项目,它多次重复这些代码,但我不确定它是否显示了一些结果。

它们完全相同(除了第一个项目由于在if子句中使用
=
而不是
=
而无法编译)

为了证明这一点,请查看
Random.Next(int,int)
的实现。使用您的值,
Random。下一个(0,4)

(int) (Random.Sample() * 4)
(int) (Random.Sample() * 1000)

随机。下一个(0,1000)

(int) (Random.Sample() * 4)
(int) (Random.Sample() * 1000)
,其中,
Random.Sample()
是一个私有方法,返回一个随机双精度


现在应该很容易看到
Random。Next(0,4)
将在
Random时准确返回0。Next(0,1000)
将返回一个介于0和250之间的数字。

伪随机数应该均匀分布,无论范围是什么。在第二个示例中,如果您只选择最后4位(
a&3
),您将获得与使用
(a>>2)&3
选择下4位相同的分布。也就是说,在第二个例子中,使用范围的算法是丢弃随机生成器提供给您的大量信息。在更大的范围内,你不会得到更多的“随机性”


话虽如此,伪随机发生器确实有其特殊性,但除非你对此认真对待,否则就不值得担心了

分布均匀且易于验证:

public class Program
{
    static void Main(string[] args)
    {
        var random = new Random();
        const int iterations = 10000000;

        var hits1 = 1.0 * Enumerable.Range(1, iterations)
                                     .Select(i => random.Next(0, 4))
                                     .Where(i => i == 0).Count();
        Console.WriteLine(hits1 / iterations);

        var hits2 = 1.0 * Enumerable.Range(1, iterations)
                                     .Select(i => random.Next(0, 1000))
                                     .Where(i => i < 250)
                                     .Count();
        Console.WriteLine(hits2 / iterations);
    }
}
公共类程序
{
静态void Main(字符串[]参数)
{
var random=新的random();
const int迭代次数=10000000;
var hits1=1.0*可枚举范围(1,迭代次数)
.Select(i=>random.Next(0,4))
其中(i=>i==0).Count();
控制台写入线(hits1/迭代);
var hits2=1.0*可枚举范围(1,迭代次数)
.Select(i=>random.Next(0,1000))
.其中(i=>i<250)
.Count();
控制台写入线(hits2/迭代);
}
}

我的测试如下

在10K环路外,以
1-4
范围和
1-1000
范围运行2次测试,结果如下

1-4

0-1000

  1 - 250    > 2421 times
  250 - 500  > 2531 times
  500 - 750  > 2529 times
  750 - 1000 > 2490 times
我的结论是,它们没有什么区别,你必须进入矩阵,等等,来控制随机数的生成等等

注意:我的测试是用PHP完成的,下面是源代码




它可以编译,但它肯定不会做您希望它做的事情。@Live,这在c#中是不正确的。它不会编译,并且会产生编译器错误:“无法隐式地将类型‘int’转换为‘bool’”。对于证明方法来说,这很好。请注意,您可能希望在ifs中添加else子句。一旦成功,就无需评估所有4个选项。-1假设php随机数实现与C使用的实现完全相同,这一假设太大了#
  1 - 250    > 2421 times
  250 - 500  > 2531 times
  500 - 750  > 2529 times
  750 - 1000 > 2490 times
<?php

$first = array(1=>0,2=>0,3=>0,4=>0);
$second = array('0 - 250' => 0, '250 - 500' => 0, '500 - 750' => 0,'750 - 1000' => 0);

for($i=0;$i<=10000;$i++)  //10K
{
    //First
    $f_number = rand(1,4);
    switch($f_number)
    {
        case 1: $first[$f_number]++; break;
        case 2: $first[$f_number]++; break;
        case 3: $first[$f_number]++; break;
        case 4: $first[$f_number]++; break;
    }

    //Second
    $s_number = rand(1,1000);
    if($s_number < 250) $second['0 - 250']++;
    if($s_number > 250 && $s_number < 500) $second['250 - 500']++;
    if($s_number > 500 && $s_number < 750) $second['500 - 750']++;
    if($s_number > 750) $second['750 - 1000']++;
}

var_dump($first,$second);
?>