遵循与前一个解决方案相同的递归思想,我们可以通过首先生成具有更多边界约束的r
来避免repeat
,这可能会加速很多,达到102
f <- function(s, n, a, b) {
if (s < n * a || s > n * b) {
stop("Invalid parameters.")
}
if (n == 1) {
return(s)
}
r <- runif(1, max(a, s - (n - 1) * b), min(b, s - (n - 1) * a))
c(r, Recall(s - r, n - 1, a, b))
}
我们可以看到
> (v <- f(s = 60, n = 30, a = 1, b = 3))
[1] 1.544962 1.229845 2.013064 1.510149 2.933672 1.782947 1.650229 2.700521
[9] 1.151468 1.758759 2.035019 1.355591 2.731922 2.918394 2.288166 2.198345
[17] 1.313646 2.312720 1.232810 1.591426 1.020105 2.788073 1.208734 2.929171
[25] 1.397976 2.044319 1.593190 2.961647 2.849886 2.953244
> summary(v)
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.002 1.387 2.126 2.000 2.585 2.892
> length(v)
[1] 30
> sum(v)
[1] 60
我想您可以try 下面这样的递归方法(我不认为我的方法是优化的,但只是给您一些提示)
一百零二
f <- function(s, n, a = 1, b = 2) {
if (s < n * a || s > n * b) {
stop("Invalid parameters.")
}
if (n == 1) {
return(s)
}
repeat {
r <- runif(1, a, b)
if (s - r >= (n - 1) * a && s - r <= (n - 1) * b) break
}
c(r, f(s - r, n - 1))
}
这样,例如,用s= 25
和n = 20
,我们可以获得
> (v <- f(s = 25, n = 20))
[1] 1.901342 1.153576 1.280439 1.920860 1.401054 1.245442 1.227995 1.340637
[9] 1.051620 1.958662 1.360496 1.001955 1.087513 1.006621 1.002153 1.008432
[17] 1.033762 1.004273 1.009684 1.003484
> length(v)
[1] 20
> sum(v)
[1] 25