Search code examples
pythonprobabilitypi

Estimating pi from darts being thrown at a SPHERICAL dartboard (python)


The familiar code for estimating pi is as follows:

import math,random
random.seed(777)
j = pie = 1
while True:
    pie = pie + math.trunc(random.random()**2 + random.random()**2)
    if j%100000==0: print(4*(1-float(pie)/float(j)))
    j = j + 1
print('done')

which emulates darts being thrown at a two-dimensional dartboard. But when you try to elevate to a three-dimensional dartboard with:

import math,random
random.seed(777)
j = pie = 1
while True:
    pie = pie + math.trunc(random.random()**2 + random.random()**2 + random.random()**2)
    if j%100000==0: print((3.0/4.0)*8.0*(1-float(pie)/float(j)))
    j = j + 1
print('done')

you get something other than pi.


Solution

  • Generally, I agree with the solution proposed by @Bob__ as it's more straightforward. Having said that, your solution can be generalized to 3 dimensional dartboard:

    import math,random
    
    random.seed(777)
    j = pie = 1
    pie = 0
    while True:
        # pie = pie + math.trunc(random.random()**2 + random.random()**2 + random.random()**2)
        pie = pie + min(1, math.trunc(random.random()**2 + random.random()**2 + random.random()**2))
        if j%100000==0: print((3.0/4.0)*8.0*(1-float(pie)/float(j)))
        j = j + 1
    print('done')
    

    To understand the issue we need to clarify what the pie variable really does. It contains the number of cases where a random radius is longer than 1.0 (so beyond the 3D dartboard).

    The 2D case works because math.trunc always returns either 0 or 1 (in or out) but for 3D it returns either 0 or 1 or 2. So, in case of 3D, it fails because it sometimes increases pie by 2 and, thus, converges faster.

    To fix your example, you just need to make sure that pie is never increased by more than 1 at a time.