随机数概率

发布于 2024-09-18 10:27:35 字数 884 浏览 7 评论 0原文

我试图从 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# 中)时,它在统计上会更准确。我已经制作了多次重复这些代码的项目,但我不确定它会向我显示一些结果。

I am trying to randomly choose from e.g. 4 numbers. I need to compare the probability of these 2 algorithms.

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

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. But someone has told me when I use bigger range of random numbers like in code 2# it’s statistically more accurate. I’ve made project which repeats many times those codes, but I’m not sure it shows me some results.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

思念满溢 2024-09-25 10:27:35

它们完全相同(除了第一个由于在 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, 1000) 时,Random.Next(0, 4) 将准确返回 0将返回 0 到 250 之间的数字。

They are exactly equivalent (except for the fact that the first one won't compile due to using = instead of == in the if-clauses).

To prove this, look at the implementation of Random.Next(int, int). With your values, Random.Next(0, 4) is

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

and

Random.Next(0, 1000) is

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

, where Random.Sample() is a private method that returns a random 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.

舂唻埖巳落 2024-09-25 10:27:35

无论范围是多少,伪随机数应该均匀分布。在第二个示例中,如果您仅选择最后 4 位 (a & 3),那么您将获得与使用 (a>> 选择后 4 位) 相同的分布;2) & 3..即,在使用范围的第二个示例中,您在算法上所做的事情是丢弃随机生成器为您提供的大量信息。范围更大时,您将不再获得“随机性”。

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

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. I.e. 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!

荒人说梦 2024-09-25 10:27:35

分布是均匀的并且很容易验证:

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

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);
    }
}
万人眼中万个我 2024-09-25 10:27:35

我的测试如下,

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

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

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

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

$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);
?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文