谁能告诉我如何模拟,其中,,使用抛硬币(如多次,你需要)与?
我当时在考虑使用拒绝采样,但无法确定。
谁能告诉我如何模拟,其中,,使用抛硬币(如多次,你需要)与?
我当时在考虑使用拒绝采样,但无法确定。
Answers:
因为有无数种解决方案,所以让我们找到一种有效的解决方案。
这个想法的背后是实现伯努利变量的标准方法:将统一随机变量与参数a / b比较。当U < a / b时,返回1 ; 否则,返回0。
我们可以将硬币用作统一的随机数生成器。要在任意间隔[ x ,y )内均匀生成数字,请翻转硬币。前进时,在间隔的前p个部分中递归生成一个统一值X;当它是尾巴时,从最后一个1 - p递归生成X间隔的一部分。在某些时候,目标间隔会变得如此之小,以至于您从中选择一个数字并不重要:这就是递归开始的方式。显然,此过程会生成均匀的变量(达到任何所需的精度),这很容易通过归纳法得到证明。
这个想法不是有效的,但却导致了一种有效的方法。 由于在每个阶段都要从给定的间隔绘制数字,所以为什么不首先检查是否需要绘制呢?如果目标值超出此间隔,则您已经知道随机值与目标之间的比较结果。 因此,该算法倾向于迅速终止。(这可以解释为问题中要求的拒绝抽样程序。)
我们可以进一步优化该算法。 在任何阶段,我们实际上都有两个硬币可以使用:通过重新标记我们的硬币,我们可以将其制成正面为正面。因此,作为预计算,我们可以递归选择无论哪种重标记都会导致终止所需的翻转次数较少。 (此计算可能是一个昂贵的步骤。)
例如,使用的硬币直接模拟Bernoulli (0.01 )变量效率不高:平均需要翻转近十次。但是,如果我们使用p = 1 - 0.0 = 0.1一枚硬币,然后在短短的两年翻转,我们将确保完成和翻转的预期数量仅仅是1.2。
这是详细信息。
将任何给定的半开区间划分为区间
这定义了以半开间隔运行的两个变换和s (∗ ,T )。
就术语而言,如果是一组实数,则让表达式
意味着是一个下界我:吨< X为所有X ∈ 予。类似地,吨> 我指吨是上界我。
写。(事实上,它会使没有什么区别,如果牛逼是真实的,而不是理性的,我们只需要0 ≤ 牛逼≤ 1)。
这是产生具有所需伯努利参数的变量的算法:
集和我Ñ = 我0 = [ 0 ,1 )。
而 {抛硬币,以产生X Ñ + 1。设置I n + 1 = S (I n,X n + 1)。 递增n。}
如果然后设置Ž = 1。否则,将Z设置为0。
为了说明,这里是R
作为函数的算法的实现draw
。其参数为目标值和区间[ X ,ÿ ),最初[ 0 ,1 )。它使用辅助函数实现s。尽管不需要,但它也跟踪抛硬币的次数。它返回随机变量,抛数和检查的最后间隔。s
s <- function(x, ab, p) {
d <- diff(ab) * p
if (x == 1) c(ab[1], ab[1] + d) else c(ab[1] + d, ab[2])
}
draw <- function(target, p) {
between <- function(z, ab) prod(z - ab) <= 0
ab <- c(0,1)
n <- 0
while(between(target, ab)) {
n <- n+1; ab <- s(runif(1) < p, ab, p)
}
return(c(target > ab[2], n, ab))
}
作为其使用和其精度的试验的一个例子,走的情况下和p = 0.9。让我们画10 ,000使用的算法,报告的平均值(和它的标准误差)值,并注明翻转使用的平均数。
target <- 0.01
p <- 0.9
set.seed(17)
sim <- replicate(1e4, draw(target, p))
(m <- mean(sim[1, ])) # The mean
(m - target) / (sd(sim[1, ]) / sqrt(ncol(sim))) # A Z-score to compare to `target`
mean(sim[2, ]) # Average number of flips
在Python中:
def simulate(p):
binary_p = float_to_binary(p)
binary_string = '0.'
index = 3
while True:
binary_string += '0' if random.random() < 0.5 else '1'
if binary_string != binary_p[:index]:
return binary_string < binary_p[:index]
index += 1
一些证明:
np.mean([simulate(0.4) for i in range(10000)])
大约是0.4(但是不快)
我看到了一个简单的解决方案,但是毫无疑问,有很多方法可以做到这一点,大概有些方法比这更简单。该方法可以分为两个步骤:
(这里需要进行一些计算以显示它,但是您可以通过处理递归关系来相当容易地找出这些概率……或者可以通过对无限序列求和来实现……或者还有其他方法。)
[self-study]
标签并阅读其wiki。请注意,您无需在问题结尾处请求帮助-我们知道在此发布信息的每个人都希望得到帮助!