## Yet Another Buffon’s Needle Simulation Using Python

I remember being amazed years ago when I first read about Buffon’s Needle problem. You can estimate the value of pi (~3.1416) by dropping a needle on a floor made from wooden slats, and counting how many times the needle crosses the edge of a slat. Remarkable.

If the wood slats are w wide, and the needle is n long (where n is less than w), and you drop the needle many times and it crosses the edge of a slat with frequency f, then the value of pi_est = (2 * n) / (f * w). For example, if slats are w = 3 inches wide, a needle is n = 1 inch long, and you drop the needle 1,000 times, and it crossed an edge 210 times, then f = 210 / 1000 = 0.210 and pi_est = (2 * 1) / (0.21 * 3) = 3.1746.

Just for fun, I decided to code up a demo simulation. I saw many demos on the Internet but I didn’t want to be influenced by them, so I designed my simulation from scratch. In pseudo-code:

loop many times
generate a random 1st point
generate a random angle
find 2nd point
if line between points crosses edge
num_hits = num_hits + 1
else
num_misses = num_misses + 1
end-loop
compute f
compute pi_est

There were quite a few minor details. I set up a scenario with a slat width of 1.0 and a needle length of 0.5 and used 10,000 simulated drops. I didn’t use any fancy trigonometry or geometry (mostly because I was too lazy to look up the equations).

I set up the simulation so that the first end point of a dropped needle had x-coordinate from 0 to 3, and therefore the second end point had x-coordinate from 0.5 to 3.5. A dropped needle could cross at x = 0, x = 1, x = 2, or x = 3.

In one run of the demo, with 10,000 simulated drops, the needle hit an edge 3175 times so f = 0.3175 and the estimated value of pi was 3.1496. I kind of cheated by trying different values of the random number generator until I got a really nice estimate of pi.

The Space Needle in Seattle (~600 ft, 1962) is a fantastic design and inspired many similar towers. Here are four. Skylon Tower (Niagara Falls, Canada, ~500 ft, 1965. Sky Tower (Auckland, ~750 ft, 1997). Stratosphere Hotel (Las Vegas, ~1100 ft, 1996). Macau Tower (Macau, ~1000 ft, 2001). I’ve been to all five of these cities but never had the desire to go to the top of the towers. For some reason, a view from a high location doesn’t interest me that much.

# buffon.py
# Buffon's Needle

# replace "less-than" and "greater-than" with symbols

import numpy as np
np.random.seed(4)

print("\nBegin Buffon's Needle problem simulation \n")

width = 1.0     # floor slat width
needle = 0.5   # needle length
num_hits = 0
num_misses = 0

x_lo = 0.0; x_hi = 3.0   # 1st end point
y_lo = 0.0; y_hi = 4.0

print("Starting simulation")
for i in range(10000):
x = (x_hi - x_lo) * np.random.random() + x_lo
y = (y_hi - y_lo) * np.random.random() + y_lo

angle = np.radians(360.0 * np.random.random())  # 0 to 2pi

xx = x + needle * np.cos(angle)    # 2nd end point
yy = y + needle * np.sin(angle)

if xx "less-than" x:
(x, xx) = (xx, x)
(y, yy) = (yy, y)
# (x,y) now to left of (xx,yy)

if (x "less-than" 0.0 and xx "greater-than" 0.0) \
or (x "less-than" 1.0 and xx "greater-than" 1.0) \
or (x "less-than" 2.0 and xx "greater-than" 2.0) \
or (x "less-than" 3.0 and xx "greater-than" 3.0):
num_hits += 1
else:
num_misses += 1

print("Simulation done \n")

pr = (num_hits * 1.0) / (num_hits + num_misses) # frequency
pi_est = (2.0 * needle) / (pr * width)

print("Needle length: %0.1f " % needle)
print("Slat width: %0.1f " % width)
print("Number hits: " + str(num_hits))
print("Number misses: " + str(num_misses))
print("Probability of hitting crack: %0.4f" % pr)
print("Estimate of pi: %0.4f" % pi_est)

print("\nEnd simulation ")
This entry was posted in Miscellaneous. Bookmark the permalink.