2010-09-10 270 views
5

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

+1

侧面说明,你可能想else子句添加到您的IFS。一旦您取得成功,无需评估全部4个选项。 – 2010-09-10 17:59:52

回答

3

它们完全相同(除了第一个由于在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

+0

它可以编译,但它肯定不会做你想要的。 – Live 2010-09-10 17:50:31

+2

@Live,在c#中不是这样。它不会编译,并会产生编译器错误:“不能隐式地将类型'int'转换为'bool'” – 2010-09-10 17:55:30

+0

伟大的证明方法。 – 2010-09-10 18:03:11

2

伪随机数应该均匀分布,无论范围是什么之间的一个数。如果在第二个例子中,如果您只选择最后4位(a & 3),您将得到相同的分配,就像您选择(a>>2) & 3中的下4个一样。即在第二个使用范围的例子中,你在算法上做了什么,是丢弃了很多随机生成器给你的信息。你没有更多的“随机性”和更大的范围。说到这一点,伪随机生成器确实有它们的特质,但是除非你对此严肃认真,否则不值得担心!

0

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

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

我的测试如下

缺货的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); 
?> 
+0

-1假设PHP的随机数实现的实现与C#使用的实现完全相同, – 2010-09-10 18:24:33