2009-08-16 28 views
7

这是PHP如何实现随机数生成?PHP - rand(1,1000)= 1000很可能是rand(1,1000)= rand(1,1000)?

说我想计算一个是或否。每次我都有一定的概率百分比(例如:这个例子为0,05%)。

我做的:

$possibilities = 100/$probabilityPercentage; //$possibilities = 2000 
$yes = rand(1,$possibilities); 

$yesCheck = $possiblities;   //OPTION 1 
$yesCheck = rand(1,$possibilities); //OPTION 2 


($yesCheck == $yes) ? return true : return false; 

它是否给与这两种选择同样的结果?

回答

11

让数据为自己说话。

代码

[email protected]ot:~$ more rand.php 
<?php 

$randrandsum = 0; 
$randconstsum = 0; 
$count = 20; 
for ($j = 0; $j < $count; $j++) { 
     $randrand = 0; 
     $randconst = 0; 
     for ($i = 0; $i < 10000000; $i++){ 
       $a = rand(1,1000); 
       $b = rand(1,1000); 
       if ($a == $b) $randrand++; 
     } 
     for ($i = 0; $i < 10000000; $i++){ 
       $a = rand(1,1000); 
       $c = 1000; 
       if ($c == $a) $randconst++; 
     } 
     $randrandsum += $randrand; 
     $randconstsum += $randconst; 
     print ($j+1)." RAND-RAND: $randrand RAND-CONST: $randconst\n"; 
} 
print "AVG RAND-RAND: ".($randrandsum/$count); 
print " AVG RAND-CONST: ".($randconstsum/$count)."\n"; 
?> 

试运行

[email protected]:~$ php rand.php 
1 RAND-RAND: 10043 RAND-CONST: 10018 
2 RAND-RAND: 9940 RAND-CONST: 10132 
3 RAND-RAND: 9879 RAND-CONST: 10042 
4 RAND-RAND: 9878 RAND-CONST: 9965 
5 RAND-RAND: 10226 RAND-CONST: 9867 
6 RAND-RAND: 9866 RAND-CONST: 9992 
7 RAND-RAND: 10069 RAND-CONST: 9953 
8 RAND-RAND: 9967 RAND-CONST: 9862 
9 RAND-RAND: 10009 RAND-CONST: 10060 
10 RAND-RAND: 9809 RAND-CONST: 9985 
11 RAND-RAND: 9939 RAND-CONST: 10057 
12 RAND-RAND: 9945 RAND-CONST: 10013 
13 RAND-RAND: 10090 RAND-CONST: 9936 
14 RAND-RAND: 10000 RAND-CONST: 9867 
15 RAND-RAND: 10055 RAND-CONST: 10088 
16 RAND-RAND: 10129 RAND-CONST: 9875 
17 RAND-RAND: 9846 RAND-CONST: 10056 
18 RAND-RAND: 9961 RAND-CONST: 9930 
19 RAND-RAND: 10063 RAND-CONST: 10001 
20 RAND-RAND: 10047 RAND-CONST: 10037 
AVG RAND-RAND: 9988.05 AVG RAND-CONST: 9986.8 

鉴于上述结果我会说,对于所有的实际目的,这两个选项是等效的,给人的两种情况下,预计1/1000结果。

+2

+1,虽然我必须回答你的“让数据自己说话”与http://www.dilbert.com/dyn/str_strip/000000000/00000000/0000000/000000/00000/2000/300/2318/2318 .strip.gif – balpha 2009-08-16 15:32:44

+0

嗯,在这种情况下,两种结果都是预期的1/1000,所以没有异味 – 2009-08-16 15:35:19

+2

这种测试方法真的不正确,因为它总是在每次迭代中调用rand()两次。更准确的测试将运行一个循环测试rand(1,1000)== 1000和第二个循环测试rand(1,1000)== rand(1,1000)。 – 2009-08-16 15:40:25

1

最随机生成的工作方式,输出不是真正随机的,而是基于一个算法,应该使返回的值出现随机和分发。基于此,如果您有两个完全不相关的“随机生成器”,那么您实际上连续两次获得相同数字的真实概率甚至比现实世界中的要小。

编辑:话虽如此,我没有任何关于如何在PHP中的默认随机生成器的作品。

+0

+1用于指出大多数PRNG的非随机性。 – paxdiablo 2009-11-03 03:16:53

0

选项1保证是正确的。

我不认为我学到足够的概率统计,早在天说选项2是否正确。

我没有,但是,学会一个人决不应该相信别人的随机数生成器,而不在其上运行测试程序,以获得它确实是多么随机的想法。

在你的情况,我想通过这两个选项运行了几百万的测试用例,并查看选项2是否想出了类似的统计选项1

+0

*理论*它们是相同的。 – 2009-08-16 15:26:24

-3

从理论上说,是的,这两个词语具有完全同样的真实可能性。这是假设PHP的随机数发生器实际上是随机的 - 如果不是,那么其中一个比另一个更可能。

最好的办法是进行实验(千迭代),看看会发生什么。

+1

这当然不是最好的方法。实验证据最多只能提供一个指示,即使有*数百万次的迭代。最好的方法是确定性的方法,您可以在其中检查算法。 – paxdiablo 2009-11-03 03:05:29

3

IF随机数生成器是真正随机的,然后这两种方法产生相同的结果。但是,计算机随机数发生器并不完美。我怀疑这些缺陷是否足够重要,但唯一可以肯定的方法就是尝试一下 - 尽可能长时间地进行测试,看看它是否有偏差。你至少需要数百万的随机数。

+0

+1用于考虑大多数基于计算机的“随机”数字生成器的非随机性。 – paxdiablo 2009-11-03 03:12:37

8

是,兰特(1,1000)= 1000是一样兰特(1,1000)=兰特(1,1000)为可能。

想象一下,滚动两个骰子。在第一个滚动后,第二个滚动的概率等于第一个滚动的概率? 1/6。

现在写下一个介于1和6之间的数字并掷骰子。骰子的概率等于你刚刚写的东西的概率是多少? 1/6。

+0

很好的解释,但我无法确定如果掷骰子一次并让它匹配一个数字更可能然后滚动它两次(或掷两个骰子),并使其显示相同的数字... – Ropstah 2009-08-17 22:36:48

+0

我不得不不同意这个答案。虽然第一句话对于真正的随机事件是正确的,但计算机上的随机数发生器通常不是真正的随机数。事实上,如果你使用线性同余发生器,几乎可以肯定两个连续的数字是相同的(取决于模)。 – paxdiablo 2009-11-03 03:11:56

2

这并不直接解决您的问题,但您可能需要查看mt_rand()。 PHP的文档状态:

许多老 libcs​​的随机数发生器具有可疑或未知 特性和缓慢。通过 默认,PHP使用libc随机 号码生成器与rand() 函数。 mt_rand()函数是一个 插入式替代品。它使用 一个随机数生成器,使用“Mersenne Twister”的已知特征 特征,该特征将产生比平均libc rand()提供的 快四倍的随机数 。

http://www.php.net/manual/en/function.mt-rand.php