为什么布丰的针法估算圆周率得不到预期值?
Why Buffon's needle method in estimating pi doesn't produce the expected value?
这是我的代码
buffon <- function(a,l)
{
n<-0
N<-0
repeat {N<-N+1
print(N)
p<-c(n/N)
# Sample the location of the needle's centre.
x<-runif(1,min = 0,max =a/2)
print(x)
# Sample angle of needle with respect to lines.
theta<-runif(1, 0, pi/2)
print(theta)
# Does the needle cross a line?
k<-l/2*sin(theta)
ifelse(x<=k,n<-n+1,n<-n)
p<-c(n/N)
print(p)
pie<-(2*l)/(p*a)
print(pie)
if(N>5000) {break}
}
}
我正在尝试使用布冯针的想法来估计 pi 的值,但是,当我尝试时:buffon(2,3)
,最终估计是 3.8,这远大于3.1。如果我的代码中有任何错误或者我不能使用 pi 来估计 pi,有人可以向我解释吗?
加法:
我意识到我的代码有很多行是多余的,所以我今天早上修改了一下:
buffon01 <- function(n,a,l)
{
# Sample the location of the needle's centre.
x<-runif(n,min = 0,max =a/2)
# Sample angle of needle with respect to lines.
theta<-runif(n, 0, pi/2)
# Does the needle cross a line?
k<-l/2*sin(theta)
# l is the length of the needle
# a is the distance between to parallel line
v<-length(x[x<=k])
p<-c(v/n)
pie<-(2*l)/(p*a)
list("pi"=pie,"error"=abs(pie-pi))
}
通过设置大于 l 的方式,我可以获得非常接近 3.14 的结果...但是我得到的结果非常不稳定...就像我再次进行相同的实验一样 3.1* 可能是除了 4 之外的任何数字...我是否忽略了设置中的其他一些问题?
据我所知。你的问题是你使用的是 "long" 针(其中 l > a),然后公式 l/2*cos(theta)
不起作用。在那种情况下,您需要使用稍微 more elaborate formula.
所以我稍微清理了你的代码,并修改了确保 l < a:
buffon <- function(a,l) {
stopifnot(l < a)
n<-0
N<-0
repeat {
N <- N+1
# Sample the location of the needle's centre.
x <- runif(1, min=0, max=a/2)
# Sample angle of needle with respect to lines.
theta <- runif(1, min=0, max=pi/2)
# Does the needle cross a line?
n <- ifelse(x <= l/2*cos(theta), n + 1, n)
# Estimate probability of crossing line
p <- n/N
# Compute pi
pie <- (2*l)/(p*a)
if (N>50000) { # Note the increased iterations
break
}
}
return(pie)
}
ans <- buffon(a=3,l=2)
print(ans)
#[1] 3.159621
看来您还把上述公式中的 cos
换成了 sin
,以检查针是否碰到一条线。然而——在我的脑海中——这并不重要。最后,在 "repeat" 循环内打印使得函数在每次遇到它时都打印出来(从而填满控制台)。相反,我已将函数修改为 return pie
对象,因此您可以将其存储在变量中。
希望这对您有所帮助。
编辑:
您的新简明函数说明了问题。比较:
buffon01(1e6, a=3, l=2)
#$`pi`
#[1] 3.143023
#
#$error
#[1] 0.00143062
buffon01(1e6, a=2, l=3)
#`pi`
#[1] 3.850819
#$error
#[1] 0.7092266
在这里,您看到使用 l>a 失败,因为使用了错误的公式。关于收敛到 pi,Buffon 的针收敛速度很慢,需要多次投掷才能获得合适的估计值。但这是统计问题,here。
这是我的代码
buffon <- function(a,l)
{
n<-0
N<-0
repeat {N<-N+1
print(N)
p<-c(n/N)
# Sample the location of the needle's centre.
x<-runif(1,min = 0,max =a/2)
print(x)
# Sample angle of needle with respect to lines.
theta<-runif(1, 0, pi/2)
print(theta)
# Does the needle cross a line?
k<-l/2*sin(theta)
ifelse(x<=k,n<-n+1,n<-n)
p<-c(n/N)
print(p)
pie<-(2*l)/(p*a)
print(pie)
if(N>5000) {break}
}
}
我正在尝试使用布冯针的想法来估计 pi 的值,但是,当我尝试时:buffon(2,3)
,最终估计是 3.8,这远大于3.1。如果我的代码中有任何错误或者我不能使用 pi 来估计 pi,有人可以向我解释吗?
加法:
我意识到我的代码有很多行是多余的,所以我今天早上修改了一下:
buffon01 <- function(n,a,l)
{
# Sample the location of the needle's centre.
x<-runif(n,min = 0,max =a/2)
# Sample angle of needle with respect to lines.
theta<-runif(n, 0, pi/2)
# Does the needle cross a line?
k<-l/2*sin(theta)
# l is the length of the needle
# a is the distance between to parallel line
v<-length(x[x<=k])
p<-c(v/n)
pie<-(2*l)/(p*a)
list("pi"=pie,"error"=abs(pie-pi))
}
通过设置大于 l 的方式,我可以获得非常接近 3.14 的结果...但是我得到的结果非常不稳定...就像我再次进行相同的实验一样 3.1* 可能是除了 4 之外的任何数字...我是否忽略了设置中的其他一些问题?
据我所知。你的问题是你使用的是 "long" 针(其中 l > a),然后公式 l/2*cos(theta)
不起作用。在那种情况下,您需要使用稍微 more elaborate formula.
所以我稍微清理了你的代码,并修改了确保 l < a:
buffon <- function(a,l) {
stopifnot(l < a)
n<-0
N<-0
repeat {
N <- N+1
# Sample the location of the needle's centre.
x <- runif(1, min=0, max=a/2)
# Sample angle of needle with respect to lines.
theta <- runif(1, min=0, max=pi/2)
# Does the needle cross a line?
n <- ifelse(x <= l/2*cos(theta), n + 1, n)
# Estimate probability of crossing line
p <- n/N
# Compute pi
pie <- (2*l)/(p*a)
if (N>50000) { # Note the increased iterations
break
}
}
return(pie)
}
ans <- buffon(a=3,l=2)
print(ans)
#[1] 3.159621
看来您还把上述公式中的 cos
换成了 sin
,以检查针是否碰到一条线。然而——在我的脑海中——这并不重要。最后,在 "repeat" 循环内打印使得函数在每次遇到它时都打印出来(从而填满控制台)。相反,我已将函数修改为 return pie
对象,因此您可以将其存储在变量中。
希望这对您有所帮助。
编辑:
您的新简明函数说明了问题。比较:
buffon01(1e6, a=3, l=2)
#$`pi`
#[1] 3.143023
#
#$error
#[1] 0.00143062
buffon01(1e6, a=2, l=3)
#`pi`
#[1] 3.850819
#$error
#[1] 0.7092266
在这里,您看到使用 l>a 失败,因为使用了错误的公式。关于收敛到 pi,Buffon 的针收敛速度很慢,需要多次投掷才能获得合适的估计值。但这是统计问题,here。