2009-08-16 59 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