简体   繁体   English

随机数概率

[英]Random numbers probability

I am trying to randomly choose from eg 4 numbers. 我试图从4个数字中随机选择。 I need to compare the probability of these 2 algorithms. 我需要比较这两种算法的概率。

1# 1#

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

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

2# 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

Am I right if I think that it is the same ? 如果我认为它是相同的,我是对的吗? The probability of statement1 in the first code is 1/4 and in the second code it is 250/1000 so it's 1/4 too. 第一个代码中statement1的概率是1/4,第二个代码中的概率是250/1000,所以它也是1/4。 But someone has told me when I use bigger range of random numbers like in code 2# it's statistically more accurate. 但有人告诉我,当我使用更大范围的随机数时,如代码2#,它在统计上更准确。 I've made project which repeats many times those codes, but I'm not sure it shows me some results. 我已经制作了多次重复这些代码的项目,但我不确定它能给我看一些结果。

They are exactly equivalent (except for the fact that the first one won't compile due to using = instead of == in the if-clauses). 它们完全相同(除了第一个不能编译的事实,因为在if子句中使用=而不是== )。

To prove this, look at the implementation of Random.Next(int, int) . 为了证明这一点,请查看Random.Next(int, int) With your values, Random.Next(0, 4) is 使用您的值, Random.Next(0, 4)

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

and

Random.Next(0, 1000) is Random.Next(0, 1000)

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

, where Random.Sample() is a private method that returns a random double. ,其中Random.Sample()是一个返回随机double的私有方法。

It should now be easy to see that Random.Next(0, 4) will return 0 exactly when Random.Next(0, 1000) will return a number between 0 and 250. 现在应该很容易看出, Random.Next(0, 4)将返回0 什么时候Random.Next(0, 1000)将返回0和250之间的数字。

Pseudorandom numbers should be evenly distributed no matter what the range is. 无论范围是什么,伪随机数均匀分布。 If, in your second example, if you just choose the last 4 bits ( a & 3 ), you will get the same distribution as if you choose the next 4 with (a>>2) & 3 . 如果在第二个示例中,如果您只选择最后4位( a & 3 ),您将得到相同的分布,就像您选择下一个4 (a>>2) & 3 Ie what you are algorithmically doing in the second example using ranges, is discarding a lot of the information the random generator has given you. 即你在第二个例子中使用范围在算法上做的是丢弃随机生成器给你的很多信息。 You get no more "randomness" with a larger range. 你不再拥有更大范围的“随机性”。

Having said this, pseudorandom generators do have their idiosyncracies, but unless you are serious about this it's not worth worrying about! 话虽如此,伪随机生成器确实有它们的特性,但除非你认真对待它,否则不值得担心!

The distribution is uniform and it's easy to verify: 分布是统一的,很容易验证:

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

My tests are as follows 我的测试如下

Out of a 10K loop 2 tests was run with a range 1-4 and a range 1-1000 , heres the results 在10K循环中,2个测试运行范围为1-4 ,范围为1-1000 ,结果如下

1-4 1-4

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

0 - 1000 0 - 1000

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

my conclusion is that they make no difference what so ever, you have to get into matrix's and so forth to have some control over random number generation and so forth. 我的结论是,他们没有任何区别,你必须进入矩阵等等,以控制随机数生成等等。

Note: my tests was done with PHP and source code is below. 注意:我的测试是用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);
?>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM