2015-03-03 68 views
3

我用Monte Carlo方法「找到Pi」,但答案不正確。該oryginal代碼爲:楓葉:RNG不是隨機的

RandomTools[MersenneTwister]: with(Statistics): 

tries := 10000: 

s := 0; 
for i to tries do 
    if GenerateFloat()^2+GenerateFloat()^2 < 1 then s := s+1 end if; 
end do: 
evalf(4*s/tries) 

它給了和身邊的答案2.8-2.85

當我更改代碼以

s := 0; 
x := Array([seq(GenerateFloat(), i = 1 .. tries)]); 
y := Array([seq(GenerateFloat(), i = 1 .. tries)]); 
for i to tries do 
if x[i]^2+y[i]^2 < 1 then s := s+1 end if; 
end do: 
evalf(4*s/tries) 

那麼答案是正確的。我不知道爲什麼我不能在「for」循環中生成數字。

我已經發現它的含義是相同的,但方差是不同的。 爲:

tries := 100000; 
A := Array([seq(GenerateFloat(), i = 1 .. 2*tries)]); 
s1 := Array([seq(A[i]^2+A[tries+i]^2, i = 1 .. tries)]); 
Mean(s1); 
Variance(s1); 
s2 := Array([seq(GenerateFloat()^2+GenerateFloat()^2, i = 1 .. tries)]); 
Mean(s2); 
Variance(s2); 

輸出爲:

0.6702112097021581 
0.17845439723457215 
0.664707674135025 
0.35463131700965245 

這有什麼錯呢? GenerateFloat()應儘可能一致。

回答

6

自動簡化是把你,

GenerateFloat()^2+GenerateFloat()^2 

成,GenerateFloat()評估

2*GenerateFloat()^2 

之前。

一個簡單的改變,讓它按預期工作,將它們分開。例如,

restart: 
with(RandomTools[MersenneTwister]): 
tries := 10^4: 
s := 0: 
for i to tries do 
    t1,t2 := GenerateFloat(),GenerateFloat(); 
    if t1^2+t2^2 < 1 then s := s+1 end if; 
end do: 
evalf(4*s/tries); 

另一種方法是使用略有不同的結構,不會自動簡化。考慮一下,單引號(不對稱引號)不會停止自動簡化(如果需要,這是對術語的定義)。

'f()^2 + f()^2';             
            2 
           2 f() 

但下面不會自動簡化,

a:=1: 
'f()^2 + a*f()^2'; 
           2  2 
          f() + a f() 

因此另一種簡單的解決方法是,

restart: 
with(RandomTools[MersenneTwister]): 
tries := 10^4: 
s := 0: 
a := 1; 
for i to tries do 
    if GenerateFloat()^2 + a*GenerateFloat()^2 < 1 then s := s+1 end if; 
end do: 
evalf(4*s/tries); 
+0

非常感謝。不能upvote - 低代表,但謝謝。它的工作原理有點愚蠢...... – 2015-03-03 18:36:56