簡體   English   中英

使用隨機數計算 PI

[英]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 並確保所有數字都具有所需的小數位? 謝謝!

你的程序有三個主要問題:

  1. 在錯誤的地方生成隨機數

    xPos = random.uniform (-1.0, 1.0) yPos = random.uniform (-1.0, 1.0)

    這些行僅在您輸入computePI()函數時執行一次。 這樣就可以進行計算的值完全相同hypot數百甚至數千的迭代。 將這些行放在while 循環中。

  2. 整數運算

    pi = (4 * in_circle) / numThrows

    由於in_circlenumThrows都是整數,因此將使用整數算法(至少在 Python 2 中)執行此計算。 將常量從4更改為4.0會將其更改為浮點計算:

     pi = (4.0 * in_circle) / numThrows
  3. 不完整的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM