【发布时间】:2021-04-27 21:58:55
【问题描述】:
我希望从有界范围 [a, b] 中选择一系列随机样本,其中 b 被递归地替换为上一次采样中绘制的值。
所以,假设我在第一轮从 [0.01, 0.1] 中抽取 0.07,那么我想在下一轮从 [0.01, 0.07] 中抽取。如果现在我抽到 0.033,那么我希望下一次抽签在 [0.01, 0.33] 范围内。为简单起见,假设我希望随机抽取在每次迭代中均匀分布。
参数应该是要进行的抽奖次数,例如 10、100、1000 等。最有效的方法是什么?理想情况下使用一些函数式编程技巧。
编辑:
这是一个紧跟斐波那契递归示例的函数:
get_rand_1 = function(n, lower = 0.001, upper = 0.1) {
if(n == 1) return(runif(1, lower, upper))
return(runif(1, 0.01, get_rand_1(n-1, lower, upper)))
}
set.seed(1234567)
sapply(1:10, get_rand_1)
这确实完成了我需要它做的事情,但它确实会不时产生NaNs,如以下输出所示:
> sapply(1:10, get_rand_1)
[1] 0.05666382 0.06759059 NaN 0.01245241 0.01019525 0.01117497 0.01096470 0.01001802
[9] 0.01005574 0.01001110
Warning messages:
1: In runif(1, 0.01, get_rand_1(n - 1, lower, upper)) : NAs produced
2: In runif(1, 0.01, get_rand_1(n - 1, lower, upper)) : NAs produced
我不确定这是种子的产物,还是程序的固有缺陷或两者兼而有之。
具体来说,如果我硬编码上限和下限并且不将它们作为参数传递,则不会发生这种情况。
get_rand = function(n) {
if(n == 1) return(runif(1, 0.001, 0.1))
return(runif(1, 0.001, get_rand(n-1)))
}
set.seed(1234567)
sapply(1:10, get_rand)
这会产生:
> set.seed(1234567)
> sapply(1:10, get_rand)
[1] 0.056663823 0.066827837 0.002083137 0.004200264 0.001238414 0.003118070 0.001038515 0.001121686
[9] 0.001084810 0.001020310
这是在 Windows 10 机器上。我可以根据需要提供会话信息。
无论哪种情况,我仍然希望以最有效的方式实现这一点。欢迎提出建议。
【问题讨论】:
标签: r recursion functional-programming