[英]Calculate PI using Random Numbers
遇到以下問題:
在幾何學中,圓的周長與其直徑之比稱為 π。 可以從以下形式的無限級數估計 π 的值:
π / 4 = 1 - (1/3) + (1/5) - (1/7) + (1/9) - (1/11) + ... 還有另一種計算 π 的新方法。 想象一下,您有一個 2 個單位平方的飛鏢板。 它內接一個單位半徑的圓。 圓的中心與正方形的中心重合。 現在想象一下你隨機向飛鏢板扔飛鏢。 那么落入圓內的飛鏢數與投出的飛鏢總數的比值等於圓的面積與方形飛鏢板面積的比值。 單位半徑的圓的面積就是π平方單位。 飛鏢盤的面積為4平方單位。 圓的面積與正方形的面積之比為π/4。
為了模擬飛鏢的投擲,我們將使用隨機數生成器。 Random 模塊有幾個可以使用的隨機數生成函數。 例如,函數uniform(a, b) 返回a(包含)和b(不包含)范圍內的浮點隨機數。
想象一下,方形飛鏢板附有一個坐標系。 右上角有坐標 (1.0, 1.0),左下角有坐標 (-1.0, -1.0)。 它的邊長為 2 個單位,其中心(以及內切圓的中心)位於原點。
飛鏢盤內的隨機點可以通過其 x 和 y 坐標指定。 這些值是使用隨機數生成器生成的。 我們實現這一目標的方式是:
xPos = random.uniform (-1.0, 1.0)
yPos = random.uniform (-1.0, 1.0)
要確定一個點是否在圓內,它到圓心的距離必須嚴格小於圓的半徑。 坐標為 ( xPos, yPos ) 的點到中心的距離為 math.hypot (xPos, yPos)。 圓的半徑為 1 個單位。
您將要編寫的程序將稱為CalculatePI。 它將具有以下結構:
import math
import random
def computePI ( numThrows ):
...
def main ():
...
main()
您的函數 main() 將針對給定的拋出次數調用函數 computePI()。 函數computePI() 將通過為x 和y 坐標生成隨機數來模擬飛鏢的投擲。 您將確定該隨機生成的點是否在圓內。 您將按照拋出次數指定的次數執行此操作。 您將計算飛鏢落在圓圈內的次數。 該計數除以總投擲次數是比率 π/4。 然后,函數computePI() 將返回PI 的計算值。 在您的函數 main() 中,您想進行實驗,看看 PI 的准確性是否隨着飛鏢投擲次數的增加而增加。 您將結果與 math.pi 給出的值進行比較。 輸出中的數量差異是您計算出的 PI 值減去 math.pi。 使用以下投擲次數來運行您的實驗 - 100、1000、10,000、100,000、1,000,000 和 10,000,000。 您將使用這些數字作為輸入參數調用函數 computePI()。 您的輸出將類似於以下內容,即您的計算 PI 和差異的實際值將有所不同,但接近於顯示的值:
Computation of PI using Random Numbers
num = 100 Calculated PI = 3.320000 Difference = +0.178407
num = 1000 Calculated PI = 3.080000 Difference = -0.061593
num = 10000 Calculated PI = 3.120400 Difference = -0.021193
num = 100000 Calculated PI = 3.144720 Difference = +0.003127
num = 1000000 Calculated PI = 3.142588 Difference = +0.000995
num = 10000000 Calculated PI = 3.141796 Difference = +0.000204
Difference = Calculated PI - math.pi
您的輸出必須采用上述格式。 投擲次數必須左對齊。 π 的計算值和差值必須准確表示到小數點后六位。 差異上應該有加號或減號。 閱讀本書中有關格式化的相關章節。
到目前為止,我已經完成了:
import math
import random
def computePI (numThrows):
xPos = random.uniform (-1.0, 1.0)
yPos = random.uniform (-1.0, 1.0)
in_circle = 0
throws = 0
while (throws < numThrows):
if math.hypot (xPos, yPos) <= 1:
in_circle += 1
throws += 1
pi = (4 * in_circle) / numThrows
return pi
def main ():
throws = (100, 1000, 10000, 100000, 1000000, 10000000)
for numThrows in throws[0:7]:
main ()
我在調用 Main 函數中的 ComputePI 函數時遇到問題。 另外,如何使用左縮進打印 num 並確保所有數字都具有所需的小數位? 謝謝!
你的程序有三個主要問題:
在錯誤的地方生成隨機數
xPos = random.uniform (-1.0, 1.0) yPos = random.uniform (-1.0, 1.0)
這些行僅在您輸入computePI()
函數時執行一次。 這樣就可以進行計算的值完全相同hypot
數百甚至數千的迭代。 將這些行放在while 循環中。
整數運算
pi = (4 * in_circle) / numThrows
由於in_circle
和numThrows
都是整數,因此將使用整數算法(至少在 Python 2 中)執行此計算。 將常量從4
更改為4.0
會將其更改為浮點計算:
pi = (4.0 * in_circle) / numThrows
不完整的main()
函數:
不需要使用throws
元組的子集,並且您還沒有在for
循環中添加主體。 試試這個:
for numThrows in (100, 1000, 10000, 100000, 1000000, 10000000): randpi = computePI(numThrows) diff = randpi - math.pi print "num = %-8d Calculated PI = %8.6f Difference = %+9.6f" % \\ (numThrows, randpi, diff)
這就是我覺得很容易的方式。
import random
import math
def approximate_pi():
total_points = 0
within_circle = 0
for i in range (10000):
x = random.random()
y = random.random()
total_points += 1
distance = math.sqrt(x**2+y**2)
if distance < 1:
within_circle += 1
if total_points % 1000 == 0:
pi_estimate = 4 * within_circle / total_points
yield pi_estimate
將生成的總點數和圓圈內的點數設置為零
total_points = 0
within_circle = 0
多次生成 x 和 y 的隨機值。 計算點到圓心或 (0,0) 的距離。 然后,如果距離小於 1,則表示它在圓內,因此它會增加。
distance = math.sqrt(x**2+y**2)
if distance < 1:
within_circle += 1
現在,如果您生成了 1000 的倍數(1000,因為我們取了 10,000 的范圍,所以 1000 來獲得 10 個 pi 值),使用您已經知道的這個公式計算 pi 的估計值。並綁定估計值(pi_estmate)
if total_points % 1000 == 0:
pi_estimate = 4 * within_circle / total_points
yield pi_estimate
pi_estimates = list(es for es in approximate_pi())
errors = list(estimate-math.pi for estimate in approximate_pi())
print(pi_estimates)
print(errors)
輸出:
估計
[3.096, 3.142, 3.1253333333333333, 3.121, 3.1384, 3.136, 3.1314285714285712, 3.133, 3.1342222222222222]
錯誤
[0.04240734641020705, 0.02240734641020703, 0.03307401307687341, 0.020407346410206806, 0.02320734641020694, 0.0017406797435404187, -0.009021225018364554, -0.011592653589793223, -0.016703764700904067]
希望你理解,我希望我的解釋容易理解,我是初學者,學習的東西,如果有什么不對的,請隨時通知。 謝謝
基本上你上面寫的聲明說的是:
import math
def find_pi(iterations):
return sum(
1 for _ in range(iterations) if math.hypot(
random.random(), random.random()) <= 1) * 4.0/iterations
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.