我需要在-1,1之间生成7个随机数,它们的总和等于1.我用这个代码来做。
diff(c(0, sort(round(runif(7,-1,1),2)), 1))
但是我有一个很大的问题。
该代码的一个输出是-0.89,0.21,0.00,0.21,0.30,0.19,0.61,-0.63。
问题是它是统一的我猜这样每次都会在第一个和最后一个数字中生成大的随机数,这不是我想要的。我需要将它传播到所有数字。恩。 0.22 -.21 .33 -.12 0.11 0.35 -0.08(总和不等于1只是一个例子)
你知道我可以写一个代码来获得这种随机数吗?
可能有两个解决方案,它们都使用无限循环:
解决方案1:
您可以考虑6个random和1个依赖,因此它们的总和可以是1.但是,可能会发生一个元素变得大于1或小于-1。因此,我们无法接受所有的答案。
while(T){
res<-runif(6,-1,1)
res<-append(res,1-sum(res))
if(sum(res>1)==0)
break
}
res
输出是:
-0.34038038 0.15811401 -0.20748670 0.26443104 0.45216639 -0.09912685 0.77228248
解决方案2:
我们应该不断产生不同的结果,并希望得到一个正确的答案。但是,为了减少时间,我们必须将randoms舍入1位数:
while(T){
res<-round(runif(7,-1,1), digits = 1)
print(sum(res))
if(sum(res)==1)
break
}
res
输出:
> res
[1] -0.6 0.2 0.4 0.7 -0.2 0.6 -0.1
您的总体想法可能受到random描述中链接的答案的启发。标准问题是如何在0和1之间生成7个加1的数字。答案是:
diff(c(0, sort(runif(6, 0, 1)), 1))
#> [1] 0.27960792 0.02035231 0.02638626 0.09945877 0.25134002 0.03379598 0.28905874
获得-1到1之间数字的必要修改非常简单;只是忽略了sort
:
diff(c(0, runif(6, 0, 1), 1))
#> [1] 0.9961661 -0.6528227 0.5298829 -0.2087127 -0.2298045 0.2017705 0.3635203
这是如何运作的?我们再次划分零和一之间的空间。但是b省略了这种排序,我们考虑了倒退的可能性,即负数是可能的。这是1000代的直方图:
这种方法的一个弱点是第一个和最后一个数字必然是正数。如果这困扰你,你可以添加额外的sample
,例如:
sample(diff(c(0, runif(6, 0, 1), 1)), 7)
#> [1] -0.004242793 -0.725348335 0.385971491 0.320525822 0.389915347
#> [6] 0.053195271 0.579983197
类似的解决方案,如Salman Lashkarara。您应该对数字进行舍入以找到解决方案。
library(magrittr)
set.seed(42)
x <- 1
while(sum(x) != 0){
x <- runif(7,-1,1) %>%
round(3)
}
x
#> [1] 0.155 0.559 -0.335 -0.230 -0.490 -0.557 0.898
sum(x)
#> [1] 0
Created on 2018-09-16 by the [reprex package](http://reprex.tidyverse.org) (v0.2.0).