【问题标题】:Random numbers probability随机数概率
【发布时间】:2011-04-10 20:31:26
【问题描述】:

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

1#

                int a = random.Next(0, 4);

                if (a = 0)
                    statement1
                if (a = 1) 
                    statement2
                if (a = 2)
                    statement3
                if (a = 3) 
                    statement4

2#

                int a = random.Next(0, 1000)

                if (a < 250)
                    statement1
                if (a >= 250 && a < 500) 
                    statement2
                if (a >= 500 && a < 750)
                    statement3
                if (a >= 750) 
                    statement4

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

【问题讨论】:

  • 旁注,您可能希望在 if 中添加 else 子句。成功后无需评估所有 4 个选项。

标签: c# random statistics probability


【解决方案1】:

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

为了证明这一点,看看Random.Next(int, int) 的实现。以你的价值观,Random.Next(0, 4)

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

Random.Next(0, 1000)

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

,其中Random.Sample() 是返回随机双精度的私有方法。

现在应该很容易看出 Random.Next(0, 4) 将返回 0 完全,而 Random.Next(0, 1000) 将返回 0 到 250 之间的数字。

【讨论】:

  • 它可以编译,但它肯定不会做你想要的。
  • @Live,这在 c# 中是不正确的。它不会编译并会产生编译器错误:“无法将类型'int'隐式转换为'bool'”
  • 证明方法很好。
【解决方案2】:

伪随机数应该均匀分布,无论范围是多少。如果在您的第​​二个示例中,如果您只选择最后 4 位 (a &amp; 3),您将获得与使用(a&gt;&gt;2) &amp; 3 选择下 4 位相同的分布。 IE。在使用范围的第二个示例中,您在算法上所做的是丢弃随机生成器提供给您的大量信息。范围越大,您就不会再获得“随机性”了。

话虽如此,伪随机生成器确实有其特点,但除非你认真对待这一点,否则不值得担心!

【讨论】:

    【解决方案3】:

    分布均匀,易于验证:

    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);
        }
    }
    

    【讨论】:

      【解决方案4】:

      我的测试如下

      在 10K 循环中运行了 2 次测试,范围为 1-4 和范围为 1-1000,结果如下

      1-4

        1 > 2484 times
        2 > 2519 times
        3 > 2511 times
        4 > 2487 times
      

      0 - 1000

        1 - 250    > 2421 times
        250 - 500  > 2531 times
        500 - 750  > 2529 times
        750 - 1000 > 2490 times
      

      我的结论是,它们没有任何区别,你必须进入矩阵等等才能对随机数生成等进行一些控制。

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


      <?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);
      ?>
      

      【讨论】:

      • -1 说php随机数的实现和C#使用的完全一样的假设太大了
      猜你喜欢
      • 2017-11-26
      • 2013-12-18
      • 2018-01-09
      • 2017-05-16
      • 1970-01-01
      • 2011-12-25
      • 2011-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多